Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to build in alpine arm64 (musl-libc) #129

Closed
creationix opened this issue Feb 1, 2018 · 13 comments
Closed

Unable to build in alpine arm64 (musl-libc) #129

creationix opened this issue Feb 1, 2018 · 13 comments

Comments

@creationix
Copy link

I'm trying to build casync in an alpine docker container so I can use it in my alpine based embedded system. I'm having build issues I suspect are because this code hasn't been tested with musl-libc.

To reproduce, try to build the following:

# Build casync in an arm64v8/alpine container
FROM arm64v8/alpine as casync
COPY /usr/bin/qemu-aarch64-static /usr/bin/
RUN apk update && apk upgrade
RUN apk add build-base git
RUN apk add meson xz-dev curl-dev openssl-dev zstd-dev acl-dev fuse-dev linux-headers

RUN git clone --branch=v2 --depth=1 https://github.com/systemd/casync.git
WORKDIR /casync
RUN meson build -Dselinux=false -Dudev=false -Dman=false
RUN ninja -C build

I get the following errors:

[1/65] Compiling C object 'src/shared@sta/cacompression.c.o'.
FAILED: src/shared@sta/cacompression.c.o 
cc  -Isrc/shared@sta -Isrc -I../src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu99 -O0 -g -Wextra -Werror=undef -Werror=format=2 -Wformat-security -Wformat-nonliteral -Wlogical-op -Wmissing-include-dirs -Werror=old-style-definition -Werror=pointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=shadow -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Werror=overflow -Werror=sign-compare -Wdate-time -Wnested-externs -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong -fPIE --param=ssp-buffer-size=4 -include config.h -fPIC -MMD -MQ 'src/shared@sta/cacompression.c.o' -MF 'src/shared@sta/cacompression.c.o.d' -o 'src/shared@sta/cacompression.c.o' -c ../src/cacompression.c
In file included from ../src/cacompression.c:1:0:
../src/util.h:307:22: error: unknown type name 'mode_t'
 char* ls_format_mode(mode_t m, char ret[LS_FORMAT_MODE_MAX]);
                      ^~~~~~
[2/65] Compiling C object 'src/shared@sta/cafileroot.c.o'.
FAILED: src/shared@sta/cafileroot.c.o 
cc  -Isrc/shared@sta -Isrc -I../src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu99 -O0 -g -Wextra -Werror=undef -Werror=format=2 -Wformat-security -Wformat-nonliteral -Wlogical-op -Wmissing-include-dirs -Werror=old-style-definition -Werror=pointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=shadow -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Werror=overflow -Werror=sign-compare -Wdate-time -Wnested-externs -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong -fPIE --param=ssp-buffer-size=4 -include config.h -fPIC -MMD -MQ 'src/shared@sta/cafileroot.c.o' -MF 'src/shared@sta/cafileroot.c.o.d' -o 'src/shared@sta/cafileroot.c.o' -c ../src/cafileroot.c
In file included from ../src/cafileroot.c:2:0:
../src/util.h:307:22: error: unknown type name 'mode_t'
 char* ls_format_mode(mode_t m, char ret[LS_FORMAT_MODE_MAX]);
                      ^~~~~~
[3/65] Compiling C object 'src/shared@sta/caformat-util.c.o'.
[4/65] Compiling C object 'src/shared@sta/cadigest.c.o'.
[5/65] Compiling C object 'src/shared@sta/calocation.c.o'.
FAILED: src/shared@sta/calocation.c.o 
cc  -Isrc/shared@sta -Isrc -I../src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu99 -O0 -g -Wextra -Werror=undef -Werror=format=2 -Wformat-security -Wformat-nonliteral -Wlogical-op -Wmissing-include-dirs -Werror=old-style-definition -Werror=pointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=shadow -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Werror=overflow -Werror=sign-compare -Wdate-time -Wnested-externs -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong -fPIE --param=ssp-buffer-size=4 -include config.h -fPIC -MMD -MQ 'src/shared@sta/calocation.c.o' -MF 'src/shared@sta/calocation.c.o.d' -o 'src/shared@sta/calocation.c.o' -c ../src/calocation.c
In file included from ../src/calocation.c:1:0:
/usr/include/sys/fcntl.h:1:2: warning: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Wcpp]
 #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
  ^~~~~~~
../src/calocation.c: In function 'ca_location_parse':
../src/calocation.c:118:21: error: implicit declaration of function 'strndupa' [-Werror=implicit-function-declaration]
                 a = strndupa(e+2, c-e-2);
                     ^~~~~~~~
../src/calocation.c:118:17: warning: nested extern declaration of 'strndupa' [-Wnested-externs]
                 a = strndupa(e+2, c-e-2);
                 ^
../src/calocation.c:118:19: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
                 a = strndupa(e+2, c-e-2);
                   ^
cc1: some warnings being treated as errors
[6/65] Compiling C object 'src/shared@sta/caencoder.c.o'.
FAILED: src/shared@sta/caencoder.c.o 
cc  -Isrc/shared@sta -Isrc -I../src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=gnu99 -O0 -g -Wextra -Werror=undef -Werror=format=2 -Wformat-security -Wformat-nonliteral -Wlogical-op -Wmissing-include-dirs -Werror=old-style-definition -Werror=pointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=shadow -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Werror=overflow -Werror=sign-compare -Wdate-time -Wnested-externs -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong -fPIE --param=ssp-buffer-size=4 -include config.h -fPIC -MMD -MQ 'src/shared@sta/caencoder.c.o' -MF 'src/shared@sta/caencoder.c.o.d' -o 'src/shared@sta/caencoder.c.o' -c ../src/caencoder.c
../src/caencoder.c: In function 'ca_encoder_node_free':
../src/caencoder.c:268:17: error: implicit declaration of function 'freecon' [-Werror=implicit-function-declaration]
                 freecon(n->selinux_label);
                 ^~~~~~~
../src/caencoder.c:268:17: warning: nested extern declaration of 'freecon' [-Wnested-externs]
../src/caencoder.c: In function 'ca_encoder_node_read_dirents':
../src/caencoder.c:486:13: error: implicit declaration of function 'scandirat' [-Werror=implicit-function-declaration]
         r = scandirat(n->fd, ".", &n->dirents, scandir_filter, scandir_compare);
             ^~~~~~~~~
../src/caencoder.c:486:9: warning: nested extern declaration of 'scandirat' [-Wnested-externs]
         r = scandirat(n->fd, ".", &n->dirents, scandir_filter, scandir_compare);
         ^
../src/caencoder.c: In function 'ca_encoder_node_read_selinux_label':
../src/caencoder.c:662:13: warning: unused variable 'r' [-Wunused-variable]
         int r;
             ^
../src/caencoder.c:661:15: warning: unused variable 'label' [-Wunused-variable]
         char *label;
               ^~~~~
cc1: some warnings being treated as errors
ninja: build stopped: subcommand failed.
The command '/bin/sh -c ninja -C build' returned a non-zero code: 1
Makefile:13: recipe for target 'rootfs.tar' failed
make: *** [rootfs.tar] Error 1
@creationix
Copy link
Author

Notice I'm trying with the v2 branch. I've also tried with latest master and it still doesn't compile.

@creationix
Copy link
Author

creationix commented Feb 1, 2018

If you don't want to bother with qemu translation, the error still reproduces (and runs much faster) using native x86_64 alpine:

FROM alpine as casync
RUN apk update && apk upgrade
RUN apk add build-base git
RUN apk add meson xz-dev curl-dev openssl-dev zstd-dev acl-dev fuse-dev linux-headers

RUN git clone --branch=v2 --depth=1 https://github.com/systemd/casync.git
WORKDIR /casync
RUN meson build -Dselinux=false -Dudev=false -Dman=false
RUN ninja -C build

@creationix
Copy link
Author

creationix commented Feb 1, 2018

There is something strange going on here. I even tried adding #include <sys/stat.h> into src/util.h and it still fails saying mode_t is undefined. Is some weird include undefining this?

edit: adding the include does help, but I get to other errors. I'll see if I can PR a fix.

@creationix
Copy link
Author

Ok, so the biggest issues are this code uses lots of gnu extensions and isn't portable to other libc implementations like musl.

I was able to get it mostly compiling by adding the following to util.h:

#ifndef strdupa
  #define strdupa(s) strcpy(alloca(strlen(s) + 1), s)
#endif
#ifndef strndupa
  #define strndupa(s, n) strncpy(alloca(strnlen(s, n) + 1), s, n)
#endif
#ifndef comparison_fn_t
  typedef int (comparison_fn_t) (const void *, const void *);
#endif

But I'm having a harder time implementing a replacement for scandirat.

@creationix
Copy link
Author

creationix commented Feb 2, 2018

Here's another related bug report where a project can't port to musl because of depending on scandirat https://bugs.launchpad.net/apparmor/+bug/1671857

@keszybz
Copy link
Member

keszybz commented Feb 3, 2018

We'd be happy to merge a patch that adds compatibility with musl, but I don't think any of the maintainers are going to develop it. It's outside of our scope of interest, sorry.

@keszybz
Copy link
Member

keszybz commented Feb 3, 2018

Oh, and in general, it seems better to add missing interfaces like strdupa to the a standard library then to reimplement them in every project.

@poettering
Copy link
Member

So, scandirat() and strdupa() really are something your libc should provide, please ask them to add this, both are genuinely useful, and in particular in the case of scandirat() are not easy to emulate safely. If this is fixed in your libc once, everybody benefits, including the folks hacking on apparmor for examples. In particular as doing scandirat() if you already have scandir() is trivial, but not if you don't...

@poettering
Copy link
Member

#define strdupa(s) strcpy(alloca(strlen(s) + 1), s)

This is really problematic: you are doing stack allocation from within function parameters. This is not generally considered safe in C (because preparing function params themselves affect the stack), and only works on some archs/compilers.

@poettering
Copy link
Member

There is something strange going on here. I even tried adding #include <sys/stat.h> into src/util.h and it still fails saying mode_t is undefined. Is some weird include undefining this?

iirc mode_t is defined in sys/types.h and not in sys/stat.h

@creationix
Copy link
Author

Understood, thanks for the feedback. For now, I just wrote up a quick tiny set of tools that fits my needs. It's not as fancy as casync, but for my needs, it's almost as good. And it's a lot easier than trying to convince musl upstream to pull in functions they've already said they don't want to implement and then wait for alpine to update to said updated musl version once/if it's upstreamed.

@creationix
Copy link
Author

iirc mode_t is defined in sys/types.h and not in sys/stat.h

Thanks. I was reading the man page and must have misread which it said to use.

poettering added a commit to poettering/casync that referenced this issue Feb 5, 2018
Some include corrections, as suggested by systemd#129
poettering added a commit to poettering/casync that referenced this issue Feb 6, 2018
Some include corrections, as suggested by systemd#129
poettering added a commit to poettering/casync that referenced this issue Feb 13, 2018
Some include corrections, as suggested by systemd#129
@pejas

This comment has been minimized.

ammarfaizi2 pushed a commit to ammarfaizi2/linux-block that referenced this issue Apr 4, 2023
…ted so far in musl and uclibc

We use it just when listing tracepoint events, and for root, so just
emit a warning about it to get users to ask the library maintainers to
implement it, as suggested in this systemd ticket:

 systemd/casync#129

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/lkml/ZCwv4z5Dh%2FdHUMG6@kernel.org/
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants