WasmLinux: BusyBoxをコンパイルする
さぁ面倒なやつだ。。
BusyBoxは様々なLinuxコマンドが1つになったプロジェクトで、これさえ動けばそのLinuxシステム上で生活することが可能になる。 ...というのは過言かもしれないが、とにかく大きなマイルストーンになるのは間違いない。
WasmLinuxにはいくつかの機能が欠けているのでまだビルドしても動かないが、そもそもビルドすらできなければ終りなので、ビルドを先に準備する。
型が合わない
In file included from applets/applets.c:9:
In file included from include/busybox.h:8:
In file included from include/libbb.h:13:
In file included from include/platform.h:333:
In file included from /home/oku/repos/musl/prefix/include/unistd.h:37:
/home/oku/repos/musl/prefix/include/bits/alltypes.h:54:15: error: typedef redefinition with different types ('int' vs 'long')
54 | typedef _Addr intptr_t;
| ^
/usr/lib/clang/18/include/stdint.h:291:25: note: previous definition is here
291 | typedef __INTPTR_TYPE__ intptr_t;
| ^
In file included from applets/applets.c:9:
In file included from include/busybox.h:8:
In file included from include/libbb.h:34:
In file included from /usr/lib/clang/18/include/stddef.h:77:
/usr/lib/clang/18/include/__stddef_size_t.h:13:23: error: typedef redefinition with different types ('unsigned long' vs 'unsigned int')
13 | typedef __SIZE_TYPE__ size_t;
| ^
/home/oku/repos/musl/prefix/include/bits/alltypes.h:34:24: note: previous definition is here
34 | typedef unsigned _Addr size_t;
| ^
In file included from applets/applets.c:9:
In file included from include/busybox.h:8:
In file included from include/libbb.h:34:
In file included from /usr/lib/clang/18/include/stddef.h:87:
/usr/lib/clang/18/include/__stddef_wchar_t.h:19:24: error: typedef redefinition with different types ('int' vs 'unsigned int')
19 | typedef __WCHAR_TYPE__ wchar_t;
| ^
/home/oku/repos/musl/prefix/include/bits/alltypes.h:10:18: note: previous definition is here
10 | typedef unsigned wchar_t;
| ^
3 errors generated.
make[1]: *** [scripts/Makefile.build:198: applets/applets.o] エラー 1
make: *** [Makefile:372: applets_dir] エラー 2
intptr_t
については、 -ffreestanding
が残ってたのでClang側の <stdint.h>
が使われているのが敗因。というわけで -ffreestanding
を削ればOK。
残り2つはclang側のpredefineにある。
#define __SIZE_TYPE__ long unsigned int
#define __WCHAR_TYPE__ int
うーん。。とりあえずコンパイラがそう言ってるんだからMUSLの方を合わせるか。。
リンクしない
$ make V=1 CC=/home/oku/repos/linux/_warp/bin/warp-hosted-cc CROSS_COMPILE=/home/oku/repos/linux/_warp/bin/warp-
rm -f .kernelrelease
echo 1.37.0.git > .kernelrelease
/home/oku/repos/busybox/scripts/gen_build_files.sh /home/oku/repos/busybox /home/oku/repos/busybox
make -f scripts/Makefile.build obj=scripts/basic
mkdir -p .tmp_versions
rm -f .tmp_versions/*
make -f scripts/Makefile.build obj=applets
wasm-ld: error: entry point specified for relocatable output file
wasm-ld: warning: creating shared libraries, with -shared, is not yet stable
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [scripts/Makefile.build:264: applets/built-in.o] エラー 1
make: *** [Makefile:372: applets_dir] エラー 2
... もしかして -r
でリンクしてるのか。。? というか、 V=1
でコマンドラインが出ない理由もわからん。。GNU Makeには --trace
があるのでそれで代用。
とりあえず -Wl,--no-entry
で無理矢理通しておく。
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 5eac45f91..4d5e9ae87 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -252,12 +252,14 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
#
# Rule to compile a set of .o files into one .o file
#
+WASMLINUX_NOENTRY=-Wl,--no-entry
+
ifdef builtin-target
quiet_cmd_link_o_target = LD $@
# If the list of objects to link is empty, just create an empty built-in.o
# -nostdlib is added to make "make LD=gcc ..." work (some people use that)
cmd_link_o_target = $(if $(strip $(obj-y)),\
- $(LD) -nostdlib $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
+ $(LD) -nostdlib $(ld_flags) -r $(WASMLINUX_NOENTRY) -o $@ $(filter $(obj-y), $^),\
rm -f $@; $(AR) rcs $@)
$(builtin-target): $(obj-y) FORCE
@@ -292,10 +294,10 @@ $($(subst $(obj)/,,$(@:.o=-objs))) \
$($(subst $(obj)/,,$(@:.o=-y)))), $^)
quiet_cmd_link_multi-y = LD $@
-cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
+cmd_link_multi-y = $(LD) $(ld_flags) -r -Wl,--no-entry -o $@ $(link_multi_deps)
quiet_cmd_link_multi-m = LD [M] $@
-cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
+cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -Wl,--no-entry -o $@ $(link_multi_deps)
# We would rather have a list of rules like
# foo.o: $(foo-objs)
<linux/kd.h>
が無い
... カーネルヘッダの作り方忘れた。。とりあえず作りおきがあったのでそれを指定。
<sys/sysinfo.h>
が無い
これはMuslとglibcの非互換だよね多分。というわけで依存している free
と uptime
は一旦ビルドから外した。
start-group
end-group
が無い
とりあえず scripts/trylink
を適当に調整。これが必要って事は完全にforkする必要があるな。。
diff --git a/scripts/trylink b/scripts/trylink
index 2255deee7..577ab7e96 100755
--- a/scripts/trylink
+++ b/scripts/trylink
@@ -93,10 +93,10 @@ if ! check_cc "-Wl,--sort-section,alignment"; then
SORT_SECTION=""
fi
-START_GROUP="-Wl,--start-group"
-END_GROUP="-Wl,--end-group"
+START_GROUP=
+END_GROUP=
INFO_OPTS() {
- echo "-Wl,--warn-common -Wl,-Map,$EXE.map -Wl,--verbose"
+ echo "-Wl,-Map,$EXE.map -Wl,--verbose"
}
# gold may not support --sort-common (yet)
@@ -129,6 +129,8 @@ fi
# Sanitize lib list (dups, extra spaces etc)
LDLIBS=`echo "$LDLIBS" | xargs -n1 | sort | uniq | xargs`
+WASMLINUX_OPTS="-Wl,--no-entry -Wl,--export=_start_c /home/oku/repos/musl/prefix/lib/crt1.o /home/oku/repos/musl/prefix/lib/libc.a"
+
# First link with all libs. If it fails, bail out
echo "Trying libraries: $LDLIBS"
# "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3"
@@ -140,6 +142,7 @@ try $CC $CFLAGS $LDFLAGS \
$SORT_SECTION \
$GC_SECTIONS \
$START_GROUP $O_FILES $A_FILES $END_GROUP \
+ $WASMLINUX_OPTS \
$l_list \
|| {
echo "Failed: $l_list"
@@ -167,6 +170,7 @@ while test "$LDLIBS"; do
$SORT_SECTION \
$GC_SECTIONS \
$START_GROUP $O_FILES $A_FILES $END_GROUP \
+ $WASMLINUX_OPTS \
$l_list
if test $? = 0; then
echo " Library $one is not needed, excluding it"
@@ -196,6 +200,7 @@ if ! test -f busybox_ldscript; then
$SORT_SECTION \
$GC_SECTIONS \
$START_GROUP $O_FILES $A_FILES $END_GROUP \
+ $WASMLINUX_OPTS \
$l_list \
`INFO_OPTS` \
|| {
空っぽのexecutableができる
... まぁ main
のABI問題(mainの引数が2引数と3引数の両方あるのをどうすんのか問題)を解決していないからね。。 __main_argc_argv
ができるので、一旦 __original_main
に置き換える。
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index d9cc48423..d7a9d780f 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -1029,8 +1029,12 @@ get_script_content(unsigned n UNUSED_PARAM)
#if ENABLE_BUILD_LIBBUSYBOX
int lbb_main(char **argv)
#else
+#ifdef __wasm__
+int __original_main(int argc UNUSED_PARAM, char **argv, char **envp UNUSED_PARAM)
+#else
int main(int argc UNUSED_PARAM, char **argv)
#endif
+#endif
{
#if 0
/* TODO: find a use for a block of memory between end of .bss
これでwasm2cを掛けると46MiB。結構でかいね。。
-rw-r--r--. 1 oku oku 46M 11月 13 01:19 user.c
-rw-r--r--. 1 oku oku 6.6K 11月 13 01:19 user.h