diff options
Diffstat (limited to 'md')
-rw-r--r-- | md/writeup/hello_world_swift.md | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/md/writeup/hello_world_swift.md b/md/writeup/hello_world_swift.md new file mode 100644 index 0000000..5e39407 --- /dev/null +++ b/md/writeup/hello_world_swift.md @@ -0,0 +1,386 @@ +title:Linux Hello world in Swift +keywords:linux,swift + +# Linux Hello world in Swift +## Intro + +Swift is one of cool modern languages, that appeared recently on the scene. +Purpose of Swift is replace C/ObjectC/C++ on MacOS. In same time its works on Linux. +Support of Swift for Linux is not that great there is lack of many libraries and all +Siwft power opens on Macos, but its still some fun language to play. Main swift page +provides only Macos and Ubuntu as main supported platforms. Anything else you may have +troubles to get working. Currently supported architectures are intel64 and arm64. +Lets get into this journey of running Swift on Linux. + +## Installing Swift +### Ubuntu + +Installing on Ubuntu is most easiest part, download from main page and done. +[https://swift.org/download/](https://swift.org/download/) + +```bash +wget -c https://swift.org/builds/swift-5.1.4-release/ubuntu1804/swift-5.1.4-RELEASE/swift-5.1.4-RELEASE-ubuntu18.04.tar.gz +tar -xvf swift-5.1.4-RELEASE-ubuntu18.04.tar.gz +``` + +### Archlinux + +Installing from main swift page, not able to compile because of missing GCC flags. +So easiest way to install is from AUR +[https://aur.archlinux.org/packages/swift-bin/](https://aur.archlinux.org/packages/swift-bin/) +Compiling other swift package from AUR have same issues, related to not able to compile source. + +```bash +wget -c https://aur.archlinux.org/cgit/aur.git/snapshot/swift-bin.tar.gz +tar -xvf swift-bin.tar.gz +cd siwft-bin +makepkg +sudo pacman -U +``` + +## Compile Swift + +All this examples given for Swift version 5.1 + +```bash +mkdir HelloWorld +cd ./HelloWorld/ +swift package init --type executable +swift run +``` + +Compiled file is located in +```bash +./.build/debug/HelloWorld +``` + + +## Static Swift Compilation + +Swift static compilation compiles in all Swift runtime and uses default Linux libraries. + +```bash +swift build -c release -Xswiftc -static-stdlib +``` + +File is located in ./.build/x86_64-unknown-linux/release/HelloWorld +```bash +ls -lah ./.build/x86_64-unknown-linux/release/HelloWorld +-rwxr-xr-x 1 fam fam 34M Mar 1 18:29 ./.build/x86_64-unknown-linux/release/HelloWorld + +ldd ./.build/x86_64-unknown-linux/release/HelloWorld + linux-vdso.so.1 (0x00007ffebcd17000) + libdl.so.2 => /usr/lib/libdl.so.2 (0x00007efc5a6d4000) + libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007efc5a6b2000) + libatomic.so.1 => /usr/lib/libatomic.so.1 (0x00007efc5a6a8000) + libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007efc5a4bf000) + libm.so.6 => /usr/lib/libm.so.6 (0x00007efc5a379000) + libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007efc5a35f000) + libc.so.6 => /usr/lib/libc.so.6 (0x00007efc5a197000) + /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007efc5c624000) +``` + +## Swift on ARM64 + +Swift installation manual for RasPi4 + +[https://swift-arm.com/install-swift/](https://swift-arm.com/install-swift/) + +```bash +curl -s https://packagecloud.io/install/repositories/swift-arm/release/script.deb.sh | sudo bash +sudo apt-get install swift5 +``` + +Now steps from beginning could be followed. And result will be same. + + +## Interfacing to C + +Swift is based on clang/llvm and able to parse C language and create interface to Swift. +Its eliminates need to write glue/binding library for Swift and simplifies C integration. + + +```bash +mkdir Cint0 +cd Cint0 +swift package init --type executable +``` + + +Define C header with functions to be binded +_code.h_ +```c +#ifndef __CCODE_H +#define __CCODE_H + +#include <stdlib.h> +#include <stdio.h> + +int one(); +int two(); +int calc(int a, int b); + +#endif +``` + +Function implementation + +_code.c_ +```c +#include "include/code.h" + +int one() +{ + printf("First\n"); + return 1; +} + +int two() +{ + printf("Second\n"); + return 2; +} + +int calc(int a, int b) +{ + return a+b; +} +``` + +_main.swift_ +```swift +import ccode; + +print("Start program") + +print(one()); +print(ccode.two()); +print(calc(12,12)) + +print("End program") +``` + +C source and header files are ready. Swift code that using C code is written. +So its time to define package and build everything. Package.swift defines +what is included in source and dependencies. So add target "Cint0" with +dependencies on "ccode" that is our C code. +And then add extra target that will compile code "ccode" and doesn't depend on +anything. ... and build. + +_Package.swift_ +```swift +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "Cint0", + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name:"Cint0", + dependencies: ["ccode"]), + .testTarget( + name: "Cint0Tests", + dependencies: ["Cint0"]), + .target( + name:"ccode", + dependencies: []), + + ] +) +``` + + + +## SDL2 example + +### Binding SDL2 library + +To use C SDL2 headers from Swift we need to create bindings. This also shows how to bind C code to Swift + +```bash +mkdir CSDL2 +cd CSDL2 +swift package init --type system-module +``` + + +Resulting files are +``` +$ swift package init --type system-module +Creating system-module package: CSDL2 +Creating Package.swift +Creating README.md +Creating .gitignore +Creating module.modulemap +``` + +Create __Headers__ directory and add there file +_CSDL2-Header.h_ +```c +#include <SDL2/SDL.h> +``` + +_Package.swift_ +```swift +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "CSDL2", + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "CSDL2", + targets: ["CSDL2"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "CSDL2", + dependencies: []), + .testTarget( + name: "CSDL2Tests", + dependencies: ["CSDL2"]), + ] +) +``` + + +Here is main thing, to tell Swift with headers to make accessible +_module.modulemap_ +``` +module CSDL2 { + header "Headers/CSDL2-Header.h" + link "SDL2" + export * +} +``` + +Now its time to test CSDL2 package + +### SDL2 test with bindings + +SDL2 test +```bash +mkdir SDLtest +cd ./SDLtest +swift package init --type executable +``` + +Small SDL2 example in C +```c +#include <SDL2/SDL.h> + +#define SCREEN_WIDTH 200 +#define SCREEN_HEIGHT 200 + +char quit = 0; +SDL_Window *window = NULL; +SDL_Renderer *renderer = NULL; + +int main() +{ + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow( + "WEBASM", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + SCREEN_WIDTH, SCREEN_HEIGHT, + SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff); + int quit=0; + while(0 == quit) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + { + quit = 1; + break; + } + } + } + } + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); +} +``` + +Lets convert C example to working with Swift code + +Pointers can be defined as OpaquePointer without type so far. +All functions are called same as in C. +Enum types if they are passed then can be accessed as NAME.rawValue . + + +```swift +import CSDL2 + +var windowPtr: OpaquePointer! = nil +var renderPtr: OpaquePointer! = nil + +SDL_Init(0) +SDL_CreateWindowAndRenderer(200,200,0,&windowPtr,&renderPtr) +SDL_SetRenderDrawColor(renderPtr,0xff,0xff,0xff,0xff) +var quit = 0; +var e = SDL_Event(); +while quit == 0 { + while SDL_PollEvent(&e) != 0 + { + switch e.type { + case case SDL_QUIT.rawValue:: + quit = 1 + default: + print("Unknown event") + } + } +} + +print("Hello, world!") + +SDL_DestroyRenderer(renderPtr) +SDL_DestroyWindow(windowPtr) +SDL_Quit() +``` + +So far all Swift features looks like they are working out of the box, without +deep Swift knowledge was able to bind library, and used. Also this is largest code base +Swift code that I ever wrote in my life. So far it looks like easy language to learn. + +## Sources + + +## Links + +[01] [https://www.programiz.com/swift-programming](https://www.programiz.com/swift-programming) +[02] [https://swift.org/download/](https://swift.org/download/) +[03] [https://aur.archlinux.org/packages/swift-bin/](https://aur.archlinux.org/packages/swift-bin/) +[04] [https://swift-arm.com/install-swift/](https://swift-arm.com/install-swift/) +[05] [https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md](https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md) +[06] [https://theswiftdev.com/how-to-call-c-code-from-swift/](https://theswiftdev.com/how-to-call-c-code-from-swift/) +[07] [https://github.com/KevinVitale/SwiftSDL/blob/master/Package.swift](https://github.com/KevinVitale/SwiftSDL/blob/master/Package.swift) +[08] [https://rderik.com/blog/making-a-c-library-available-in-swift-using-the-swift-package/](https://rderik.com/blog/making-a-c-library-available-in-swift-using-the-swift-package/) +[09] [https://github.com/KevinVitale/SwiftSDL/tree/master/Sources](https://github.com/KevinVitale/SwiftSDL/tree/master/Sources) +[10] [https://www.uraimo.com/2016/04/07/swift-and-c-everything-you-need-to-know/#working-with-pointers](https://www.uraimo.com/2016/04/07/swift-and-c-everything-you-need-to-know/#working-with-pointers) +[11] [https://www.objc.io/blog/2018/01/30/opaque-vs-unsafe-pointers/](https://www.objc.io/blog/2018/01/30/opaque-vs-unsafe-pointers/) + |