summaryrefslogtreecommitdiff
path: root/md/writeup/linux_hello_world_in_swift.md
diff options
context:
space:
mode:
Diffstat (limited to 'md/writeup/linux_hello_world_in_swift.md')
-rw-r--r--md/writeup/linux_hello_world_in_swift.md388
1 files changed, 388 insertions, 0 deletions
diff --git a/md/writeup/linux_hello_world_in_swift.md b/md/writeup/linux_hello_world_in_swift.md
new file mode 100644
index 0000000..94ce5de
--- /dev/null
+++ b/md/writeup/linux_hello_world_in_swift.md
@@ -0,0 +1,388 @@
+title:Linux Hello world in Swift
+keywords:linux,swift,apple,c,sdl2
+
+# 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/)
+