25 may 2016
emscripten on nixos, a status update.
since the project i’m hacking on requires me to develop on nixos, which is awsome btw, i had to figure how to compile xml.js on nixos. one requirement was the revision bump from 1.36.4 to 1.36.4.
since xml.js wouldn’t compile on nixos caused by a missing library:
cannot find -lgcc
. see the bug-report
for details.
in a nut-shell: using 1.36.4 emscripten xml.js compiles/works with ubuntu but fails on nixos.
/script/libxml2
.
52: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.
configure.ac:9742: AM_INIT_AUTOMAKE is expanded from...
aclocal.m4:52: the top level
configure.ac:in '.'.
libtoolize: putting auxiliary files file './ltmain.sh'
libtoolize: copying in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: putting macros file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
libtoolize: copying 52: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.
configure.ac:713: AM_INIT_AUTOMAKE is expanded from...
aclocal.m4:52: the top level
configure.ac:in regex is deprecated, passed through in regex; marked by <-- HERE in m/\${ <-- HERE ([^ \t=:+{}]+)}/ at /nix/store/klmb2g54ini7y5hcf5sfx92agsifgazi-automake-1.15/bin/automake line 3936.
Unescaped left brace 52: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated. For more info, see:
configure.ac:52: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:60: installing './compile'
configure.ac:52: installing './missing'
configure.ac:/nix/store/klmb2g54ini7y5hcf5sfx92agsifgazi-automake-1.15/share/automake-1.15/am/ltlibrary.am: warning: 'libxml2.la': linking libtool libraries using a non-POSIX
/nix/store/klmb2g54ini7y5hcf5sfx92agsifgazi-automake-1.15/share/automake-1.15/am/ltlibrary.am: archiver requires 'AM_PROG_AR' in 'configure.ac'
22: while processing Libtool library 'libxml2.la'
Makefile.am:/nix/store/klmb2g54ini7y5hcf5sfx92agsifgazi-automake-1.15/share/automake-1.15/am/ltlibrary.am: warning: 'testdso.la': linking libtool libraries using a non-POSIX
/nix/store/klmb2g54ini7y5hcf5sfx92agsifgazi-automake-1.15/share/automake-1.15/am/ltlibrary.am: archiver requires 'AM_PROG_AR' in 'configure.ac'
173: while processing Libtool library 'testdso.la'
Makefile.am:'./depcomp'
Makefile.am: installing /Makefile.am:21: warning: wildcard tutorial/*.html: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard tutorial/*.c: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard tutorial/*.pdf: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard tutorial/images/*.png: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard tutorial/images/callouts/*.png: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard API*.html: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard *.1: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard *.xsl: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard *.html: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard *.gif: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard html/*.html: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:21: warning: wildcard html/*.png: non-POSIX variable name
doc/Makefile.am:21: (probably a GNU make extension)
doc/Makefile.am:301: warning: filter-out %/xmlversion.h, $(wildcard $(top_srcdir: non-POSIX variable name
doc/Makefile.am:301: (probably a GNU make extension)
doc/Makefile.am:301: warning: wildcard $(top_srcdir: non-POSIX variable name
doc/Makefile.am:301: (probably a GNU make extension)
doctype... x86_64-unknown-linux-gnu
checking build system type... x86_64-unknown-linux-gnu
checking host system for a BSD-compatible install... /nix/store/n4zpfi4zzw10s2g91v1swkwq41v1afzz-coreutils-8.25/bin/install -c
checking is sane... yes
checking whether build environment for a thread-safe mkdir -p... /nix/store/n4zpfi4zzw10s2g91v1swkwq41v1afzz-coreutils-8.25/bin/mkdir -p
checking for gawk... gawk
checking
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yesfor gcc... /nix/store/0llznkhcyyndfhwqah01i1zcdhqxrx0d-emscripten-1.36.4/share/emscripten/emcc
checking
checking whether the C compiler works... yesfor C compiler default output file name... a.out
checking for suffix of executables...
checking in `/home/joachim/Desktop/projects/nlnet/xml.js/build':
checking whether we are cross compiling... configure: error: configure: error: cannot run C compiled programs.
compile, use `--host'.
If you meant to cross See `config.log' for more details
with non-zero return code 1! Command line: ['../libxml2/configure', '--with-http=no', '--with-ftp=no', '--with-python=no', '--with-threads=no', '--with-debug'] at /home/joachim/Desktop/projects/nlnet/xml.js/build
ERROR:root:Configure step failed *** Es wurden keine Ziele angegeben und keine „make“-Steuerdatei gefunden. Schluss. make:
% cat build/config.log
...3602: checking whether the C compiler works
configure:3624: /nix/store/0llznkhcyyndfhwqah01i1zcdhqxrx0d-emscripten-1.36.4/share/emscripten/emcc conftest.c >&5
configure:3628: $? = 0
configure:3676: result: yes
configure:3679: checking for C compiler default output file name
configure:3681: result: a.out
configure:3687: checking for suffix of executables
configure:3694: /nix/store/0llznkhcyyndfhwqah01i1zcdhqxrx0d-emscripten-1.36.4/share/emscripten/emcc -o conftest conftest.c >&5
configure:3698: $? = 0
configure:3720: result:
configure:3742: checking whether we are cross compiling
configure:3750: /nix/store/0llznkhcyyndfhwqah01i1zcdhqxrx0d-emscripten-1.36.4/share/emscripten/emcc -o conftest conftest.c >&5
configure:/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld: cannot find crt1.o: No such file or directory
/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld: cannot find crti.o: No such file or directory
/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld: cannot find crtbegin.o: No such file or directory
/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld: cannot find -lgcc
with exit code 1 (use -v to see invocation)
clang: error: linker command failed 3754: $? = 1
configure:3761: ./conftest
configure:/libxml2/configure: line 3763: ./conftest: No such file or directory
..3765: $? = 127
configure:3772: error: in `/home/joachim/Desktop/projects/nlnet/xml.js/build':
configure:configure:3774: error: cannot run C compiled programs.
compile, use `--host'.
If you meant to cross See `config.log' for more details
the interesting bit is that the crt1.o
,
crti.o
and crtbegin.o
as well as
libgcc.so / libgcc_s.so
are coming from different packages
like gcc
and glibc
IIRC.
i’ve spent a while trying to fix these requirements with
./gen.sh
a little scripte which creates fake libraries.
% cat /home/joachim/Desktop/projects/nlnet/xml.js/lib/gen.sh
#!/usr/bin/env bash
set -v
*.o
rm *.so
rm "crtbegin"
echo "int main() {}" > foo.cpp
echo ++ -c -Wall -Werror -lc --entry main foo.cpp -o foo.o
g
mv foo.o crtbegin.o
##### crt1 with _start symbol
"crt1"
echo "void _start() {}" > foo.c
echo -c -Wall -Werror -fpic foo.c -o crt1.o
gcc
for i in crtbegin crti crtend crtn; do
-f foo.o foo.c
rm "void foo123_$i(void) {}" > foo.c
echo -c -Wall -Werror -fpic foo.c -o foo.o
gcc
mv foo.o $i.o
done
for i in libgcc_s1 libgcc1 ; do
-f foo.o foo.c
rm "void foobar_$i(void) {}" > foo.c
echo
cat foo.c"1"
echo -c -Wall -Werror foo.c -o foo.o
gcc "2"
echo -shared -o $i.so foo.o
gcc
done
ar rc libgcc1.a foo.o
mv libgcc1.a libgcc.a mv libgcc_s1.so libgcc_s.so
so i came up with extending environment variables: NIX_LDFLAGS and
="-L /home/joachim/Desktop/projects/nlnet/xml.js/lib -rpath /nix/store/3qhj8rf3j064qbrm5q2yzkb5vd5qnhzj-shell/lib64 -rpath /nix/store/3qhj8rf3j064qbrm5q2yzkb5vd5qnhzj-shell/lib -L/nix/store/97aj51dl9jvn2qyjapi7m2v2gai9mp27-nodejs-4.3.1/lib -L/nix/store/97aj51dl9jvn2qyjapi7m2v2gai9mp27-nodejs-4.3.1/lib -L/nix/store/g47gdl1h8mzixl9566dnjlwgwvgpyvkr-libtool-2.4.6-lib/lib -L/nix/store/g47gdl1h8mzixl9566dnjlwgwvgpyvkr-libtool-2.4.6-lib/lib -L/home/joachim/Desktop/projects/nlnet/xml.js/lib" export NIX_LDFLAGS
strace -f -s 200 -e execve emconfigure ../libxml2/configure --with-http=no --with-ftp=no --with-python=no --with-threads=no --with-debug
would show something like:
24762] execve("/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld", ["/nix/store/60a1aqx579bjff3c90cw0l1zwyj2qxhg-binutils-2.26-dev/bin/ld", "-dynamic-linker", "/nix/store/iifa17bpi78d0l62463z7sn25jc3545j-glibc-multi-2.23/lib/ld-linux-x86-64.so.2", "--eh-frame-hdr", "-m", "elf_x86_64", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "conftest", "crt1.o", "crti.o", "crtbegin.o", "/run/user/1000/conftest-904287.o", "-L/home/joachim/Desktop/projects/nlnet/xml.js/build/../lib", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "crtend.o", "crtn.o", "-L", "/home/joachim/Desktop/projects/nlnet/xml.js/lib", "-rpath", "/nix/store/3qhj8rf3j064qbrm5q2yzkb5vd5qnhzj-shell/lib64", "-rpath", "/nix/store/3qhj8rf3j064qbrm5q2yzkb5vd5qnhzj-shell/lib", "-L/nix/store/97aj51dl9jvn2qyjapi7m2v2gai9mp27-nodejs-4.3.1/lib", "-L/nix/store/97aj51dl9jvn2qyjapi7m2v2gai9mp27-nodejs-4.3.1/lib", "-L/nix/store/g47gdl1h8mzixl9566dnjlwgwvgpyvkr-libtool-2.4.6-lib/lib", "-L/nix/store/g47gdl1h8mzixl9566dnjlwgwvgpyvkr-libtool-2.4.6-lib/lib", "-L/home/joachim/Desktop/projects/nlnet/xml.js/lib", "-L/nix/store/iifa17bpi78d0l62463z7sn25jc3545j-glibc-multi-2.23/lib", "-L/nix/store/hcndjf2r2rcrf39x77wklckn60sx89dx-gcc-5.3.0-lib/lib", "-rpath", "/nix/store/iifa17bpi78d0l62463z7sn25jc3545j-glibc-multi-2.23/lib", "-rpath", "/nix/store/hcndjf2r2rcrf39x77wklckn60sx89dx-gcc-5.3.0-lib/lib"], [/* 125 vars */]) = 0 [pid
the return value of 0
is the key but it didn’t work
anyways….
the emscripten source code mentiones this fix:
export EMCONFIGURE_JS=2
is the key in this case.
# Whether we fake configure tests using clang - the local, native compiler - or not. if not we generate JS and use node with a shebang
is perfect, you can try both, but may need to edit configure scripts in some cases
Beither approach in js, which can break on local filesystem access, etc., but is otherwise accurate so we
By default we configure if we think we have to. A value of '2' here will force JS checks in all cases. In summary:
disable this 0 - use native compilation for configure checks
1 - use js when we think it will work
2 - always use js for configure checks
= int(os.environ.get('EMCONFIGURE_JS') or 1) use_js
so every time you fail with ./configure for some weird reason like
the one above or other, try export EMCONFIGURE_JS=2
,
distclean the build and build again.
hf!
with this new knowledge it might get feasible to use nix as a tool chain for more complex emscripten setups!
thanks to matthewbauer and joelmo#nixos@irc.kde.org for their support and ideas!