Porting C applications over to Redox

I’ve been interested in Redox for a while, and recently had the opportunity to spend some time working with it. Getting the initial Redox build done wasn’t much trouble, and getting started adding/building (simple) recipes that require pure Rust builds was pretty straight-forward. However, quite a few of the applications that I’d be interested in using something other than Rust, often primarily (or at least including) C or C++. As a result, I decided to give it a shot using Redis, as it’s one of the more (the most?) popular key-value stores and is used in a lot of applications. I’ve also successfully done from-source builds for this on Linux already.

I started with Redis 7.0.5 (the current stable release), and then added a bunch of small fixes to deal with compilation errors relating to Redox not having syslog.h or glob.h, per the rust-lang repository’s libc build specs at libc/build.rs at master · rust-lang/libc · GitHub, where Redox’s headers don’t include either one (compared to, say, Linux). Most of these follow something of the following pattern:

#if !defined(__redox__)
// stuff here that Redox compilation doesn't like
#endif

The recipe custom build step is pretty much

rsync -av --delete "${COOKBOOK_SOURCE}/" ./
COOKBOOK_CONFIGURE="make"
COOKBOOK_CONFIGURE_FLAGS=(
    CFLAGS="-static"
    EXEEXT="-static"
    LDFLAGS="-I/usr/local/include"
    MALLOC=libc
)
cookbook_configure

where the MALLOC=libc flag is necessary because Redis defaults to using jemalloc, which isn’t available, and of course we otherwise want a static binary for Redox builds since dynamic linking isn’t really supported.

Once that’s done, apart from some warnings, the rest of the source-level compilation seems to run fine. However, I then run into a linker error when trying to link for redis-server, one of the main binaries that’s produced by the build process.

    LINK redis-server
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: cannot find -ldl
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: cannot find -lrt
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:376: redis-server] Error 1
make[2]: Leaving directory '/home/chrism/redox/redox/cookbook/recipes/redis/build/src'
make[1]: *** [Makefile:6: all] Error 2
make[1]: Leaving directory '/home/chrism/redox/redox/cookbook/recipes/redis/build'
redoxer env: exit status: 2
cook - redis - error: failed to build: failed to run "/home/chrism/redox/redox/cookbook/target/release/cookbook_redoxer" "env" "bash" "-ex": exited with status exit status: 1
make: *** [mk/repo.mk:13: build/repo.tag] Error 1

As far as I can tell, these are related to this line in the Makefile

    # All the other OSes (notably Linux)
    FINAL_LDFLAGS+= -rdynamic
    FINAL_LIBS+=-ldl -pthread -lrt

I’ve tried modifying the lines to look something like the following, including setting the static build flag and removing the dl and rt dependencies, but then end up with a bunch of errors related to undefined references to

LINK redis-server
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: debug.o: in function `bugReportStart':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1118: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: debug.o: in function `logServerInfo':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1716: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: /home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1722: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: /home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1723: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: /home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1725: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: debug.o:/home/chrism/redox/redox/cookbook/recipes/redis/build/src/debug.c:1736: more undefined references to `serverLogRaw' follow
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: server.o: in function `adjustOpenFilesLimit':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/server.c:2139: undefined reference to `setrlimit'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: server.o: in function `daemonize':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/server.c:6101: undefined reference to `setsid'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: server.o: in function `redisAsciiArt':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/server.c:6177: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: server.o: in function `main':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/server.c:6838: undefined reference to `tzset'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: config.o: in function `configSetCommand':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/config.c:928: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: module.o: in function `moduleLogRaw':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/module.c:7024: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: module.o: in function `moduleLoad':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/module.c:11236: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: module.o: in function `moduleVerifyConfigFlags':
/home/chrism/redox/redox/cookbook/recipes/redis/build/src/module.c:11459: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: /home/chrism/redox/redox/cookbook/recipes/redis/build/src/module.c:11451: undefined reference to `serverLogRaw'
/home/chrism/redox/redox/prefix/x86_64-unknown-redox/relibc-install/bin/../lib/gcc/x86_64-unknown-redox/8.2.0/../../../../x86_64-unknown-redox/bin/ld: module.o:/home/chrism/redox/redox/cookbook/recipes/redis/build/src/module.c:11455: more undefined references to `serverLogRaw' follow
collect2: error: ld returned 1 exit status

My understanding is that both libdl and librt are parts of libc, which should default to pulling things from the relibc implementation. I can see that there is an ld_so directory under the relibc directory in the Redox source, but am having a hard time understanding exactly how that works/if it’s supposed to play the role of the linker that libdl would do. I can’t seem to find any references to librt at all; is this something that would need to be implemented from scratch from Redox, in the same way that it appears both pthread and libm needed to be? Thanks for taking a look, and if I can clarify things, just let me know!

2 Likes

Just in case anyone reads this post in the future, Jeremy answered in the Mattermost chat:

There is no librt or libdl on Redox, those components if they exist are integrated into libc. The missing functions you listed like setrlimit and setsid are not in relibc yet. So, someone would have to implement those.

1 Like