You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(guides): Add guide for porting external libraries
Introduce a new guide in `library-porting.mdx` explaining the process
of porting external libraries to Unikraft.
Additionally, reformat `basic-porting.mdx` and `library-porting.mdx`
to adhere to the linter's requirement of a single sentence per line.
Signed-off-by: Stefan Stancu <stefanstancu2006@gmail.com>
1. In the `Makefile`, change `UK_LIBS` to `UK_LIBS ?= $(LIBS_BASE)/musl`.
44
-
After all that, when you run `make menuconfig`, you should see `musl: A C standard library` under `Library Configuration -->`.
42
+
In the Makefile, change `UK_LIBS` to `UK_LIBS ?= $(LIBS_BASE)/musl`.
45
43
44
+
After all that, when you run `make menuconfig`, you should see `musl: A C standard library` under Library Configuration.
46
45
After all that, we can start the actual porting.
47
46
In order to not get confused between multiple files, we will create two directories, `include/` and `src/`, where we will copy the header and source files that we need.
48
47
@@ -51,7 +50,7 @@ $ mkdir include/
51
50
$ mkdir src/
52
51
```
53
52
54
-
After that, we can clone the `coreutils` and extract the files necessary for `echo`:
53
+
After that, we can clone the coreutils and extract the files necessary for echo:
This tells the build system to use the `echo.c` file as a source file, and the `include/` directory as a path to search for header files.
69
+
After all this is done, we can try to run make.
70
70
71
-
After all this is done, we can try to run `make`.
72
71
We will receive a lot of build errors, as expected.
73
72
We need to solve them one by one.
74
-
75
73
First, we will receive some errors about missing headers, like `config.h`, `timespec.h`, etc.
76
-
To solve this, we will use the very blunt approach, `kill them all`.
74
+
To solve this, we will use the very blunt approach, kill them all.
77
75
We remove all the `#include` lines from the `echo.c` file, and go from there.
78
76
79
-
**Note** that this is obviously a bad idea for most applications.
80
-
We should find the headers and copy them, but in our case, since `echo` does not need much, we can figure out what to add on the way.
81
-
77
+
Note that this is obviously a bad idea for most applications.
78
+
We should find the headers and copy them, but in our case, since echo does not need much, we can figure out what to add on the way.
82
79
For now, we leave only the `stdio.h` and `sys/types.h` as include statements.
83
80
We will add more of them later.
84
81
85
82
Now, we receive some errors regarding undeclared things:
86
83
87
-
```text
88
-
/projects/unikraft/catalog-core/c-hello/src/echo.c:29:30: error: ‘false’ undeclared here (not in a function)
84
+
```plaintext
85
+
/projects/unikraft/catalog-core/c-hello/src/echo.c:29:30: error: 'false' undeclared here (not in a function)
89
86
29 | enum { DEFAULT_ECHO_TO_XPG = false };
90
-
/projects/unikraft/catalog-core/c-hello/src/echo.c:37:21: error: ‘EXIT_SUCCESS’ undeclared (first use in this function)
91
-
37 | affirm (status == EXIT_SUCCESS);
87
+
/projects/unikraft/catalog-core/c-hello/src/echo.c:37:21: error: 'EXIT_SUCCESS' undeclared (first use in this function)
88
+
37 | affirm (status == EXIT_SUCCESS);
92
89
......
93
90
```
94
91
@@ -103,16 +100,16 @@ We can add some headers now.
103
100
This way we get rid of some of the undefined symbols.
104
101
Next, we see some weird undefined functions called in the `usage()` function:
105
102
106
-
```text
107
-
/projects/unikraft/catalog-core/c-hello/src/echo.c:39:3: warning: implicit declaration of function ‘affirm’ [-Wimplicit-function-declaration]
108
-
39 | affirm (status == EXIT_SUCCESS);
103
+
```plaintext
104
+
/projects/unikraft/catalog-core/c-hello/src/echo.c:39:3: warning: implicit declaration of function 'affirm' [-Wimplicit-function-declaration]
105
+
39 | affirm (status == EXIT_SUCCESS);
109
106
| ^~~~~~
110
-
/projects/unikraft/catalog-core/c-hello/src/echo.c:41:11: warning: implicit declaration of function ‘_’ [-Wimplicit-function-declaration]
111
-
41 | printf (_("\
107
+
/projects/unikraft/catalog-core/c-hello/src/echo.c:41:11: warning: implicit declaration of function '_' [-Wimplicit-function-declaration]
108
+
41 | printf (_("\
112
109
| ^
113
110
```
114
111
115
-
Let's skip the usage function, we can just have the usage function exit.
112
+
Let's skip the `usage` function, we can just have the `usage` function exit.
116
113
117
114
```c
118
115
void
@@ -123,7 +120,7 @@ usage (int status)
123
120
```
124
121
125
122
Finally, we only have one screen of errors to solve.
126
-
We get an `LC_ALL undeclared` error, we need to `#include <locale.h>`.
123
+
We get an `LC_ALL` undeclared error, we need to `#include <locale.h>`.
127
124
128
125
There are some more GNU-specific functions, like `version_etc`, `proper_name`, `bindtextdomain`, etc.
129
126
They have to do just with the program metadata, like authors, licensing and versioning, so we can delete them (the following lines:)
@@ -143,8 +140,7 @@ We can also remove the `FALLTHROUGH` line from the main switch statement, since
143
140
144
141
Finally, when we try to `make` again, we only have 3 main errors left: undefined reference to `STREQ`, undefined reference to `close_stdout`, and implicit declaration of `c_isxdigit`.
145
142
Other than that, there are the `FALLTHROUGH` warnings from above.
146
-
147
-
For the `STREQ`, we can search that in the `coreutils` repo:
143
+
For the `STREQ`, we can search that in the coreutils repo:
148
144
149
145
```console
150
146
$ grep -r STREQ coreutils
@@ -160,7 +156,6 @@ This makes sense, it's just a wrapper over `strcmp`, so let's copy it into our s
160
156
```
161
157
162
158
We also need to `#include <string.h>`, since we use `strcmp`.
163
-
164
159
The `close_stdout` function is nowhere in the `coreutils/` repo, so we can assume that it's a function that closes the standard output descriptor, since it's called at the program exit.
165
160
We add it to our source file:
166
161
@@ -172,12 +167,10 @@ void close_stdout(void)
172
167
```
173
168
174
169
For this, we need to also include `unistd.h`.
175
-
176
170
Now, the only thing left is the `c_isxdigit` function.
177
-
Again, it's not found in the `coreutils` repository, but we can assume it's just the `isxdigit` function from libc, so we replace `c_isxdigit` with `isxdigit` and we include the `ctype.h` header.
178
-
171
+
Again, it's not found in the coreutils repository, but we can assume it's just the `isxdigit` function from libc, so we replace `c_isxdigit` with `isxdigit` and we include the `ctype.h` header.
We explore how to port external library dependencies on top of Unikraft.
5
+
---
6
+
7
+
## Porting External Libraries
8
+
9
+
Being a library operating system, Unikraft unikernels are mainly a collection of internal and external libraries, alongside the ported application.
10
+
As a consequence, a large library pool is mandatory in order to make the project compatible with as many applications as possible.
11
+
12
+
An application ported on top of Unikraft is essentially a library with an already provided main() function.
13
+
External libraries require files specific to the Unikraft build system (Config.uk, Makefile.uk, Makefile) together with glue code that might be missing from the Unikraft ecosystem.
14
+
15
+
## Directory Structure
16
+
17
+
External libraries should be placed in the `.unikraft/libs` folder.
18
+
The standard working directory structure looks like this:
19
+
20
+
```plaintext
21
+
app-directory/
22
+
|-- Makefile
23
+
|-- Makefile.uk
24
+
`-- .unikraft/
25
+
|-- libs/
26
+
| `-- lib-mylib/
27
+
`-- unikraft/
28
+
```
29
+
30
+
## Examining a Ported Library: lib-libhogweed
31
+
32
+
Let's examine core components of an existing port, such as lib-libhogweed.
33
+
34
+
### Glue Code
35
+
36
+
Sometimes, an external library's requirements are not fully present in Unikraft.
37
+
The solution is to add "glue code" manually to the library's sources.
38
+
Glue code is also useful when a library includes test modules; you can wrap them into a single function that Unikraft can invoke.
39
+
40
+
### Configuration: Config.uk
41
+
42
+
The `Config.uk` file defines the menu configuration for `make menuconfig`:
43
+
44
+
```plaintext
45
+
menuconfig LIBHOGWEED
46
+
bool "libhogweed - Public-key algorithms"
47
+
default n
48
+
select LIBMUSL # Include dependencies
49
+
```
50
+
51
+
You can also create auxiliary menus for test cases:
52
+
53
+
```plaintext
54
+
config TESTSUITE
55
+
bool "testsuite - tests for libhogweed"
56
+
default n
57
+
if TESTSUITE
58
+
config TEST_X
59
+
bool "test x functionality"
60
+
default y
61
+
endif
62
+
```
63
+
64
+
### Build Rules: Makefile.uk
65
+
66
+
The `Makefile.uk` sets header search paths and can trigger configuration scripts like `./configure`:
0 commit comments