From 2d5c3e19256ab716fa52567abb2989616f67dfda Mon Sep 17 00:00:00 2001 From: Mohammad Akhlaghi Date: Sun, 20 Jan 2019 05:14:41 +0000 Subject: Bash is built with its own libreadline, not using ours While working on a pipeline based on this, I noticed many linking errors of our installed Bash, complaining that it can't link with libreadline. This was while readline was present in the proper directory and the Bash within a recipe would work properly. After some investigation, I found out that this is because Make's `foreach' function (which was used to define the targets) was apparently calling Bash without setting `LD_LIBRARY_PATH', causing this error. To avoid such sitations, Bash now uses its internal build of readline and we no longer ask it to link with the installed readline. --- reproduce/src/make/dependencies-basic.mk | 217 ++++++++++++++++--------------- 1 file changed, 113 insertions(+), 104 deletions(-) mode change 100644 => 100755 reproduce/src/make/dependencies-basic.mk (limited to 'reproduce/src') diff --git a/reproduce/src/make/dependencies-basic.mk b/reproduce/src/make/dependencies-basic.mk old mode 100644 new mode 100755 index 6e274ed..2904a0b --- a/reproduce/src/make/dependencies-basic.mk +++ b/reproduce/src/make/dependencies-basic.mk @@ -19,9 +19,8 @@ # ------------------------------------------------------------------------ # # Original author: -# Mohammad Akhlaghi -# Contributing author(s): # Your name +# Contributing author(s): # Copyright (C) 2018-2019, Your Name. # # This Makefile is free software: you can redistribute it and/or modify it @@ -149,10 +148,10 @@ $(tarballs): $(tdir)/%: elif [ $$n = make ]; then w=http://akhlaghi.org/src; \ elif [ $$n = mpfr ]; then w=http://www.mpfr.org/mpfr-current;\ elif [ $$n = mpc ]; then w=http://ftpmirror.gnu.org/gnu/mpc;\ - elif [ $$n = ncurses ]; then w=http://ftpmirror.gnu.org/gnu/ncurses;\ + elif [ $$n = ncurses ]; then w=http://ftpmirror.gnu.org/gnu/ncurses;\ elif [ $$n = openssl ]; then w=http://www.openssl.org/source; \ elif [ $$n = pkg ]; then w=http://pkg-config.freedesktop.org/releases; \ - elif [ $$n = readline ]; then w=http://ftpmirror.gnu.org/gnu/readline; \ + elif [ $$n = readline ]; then w=http://ftpmirror.gnu.org/gnu/readline; \ elif [ $$n = sed ]; then w=http://ftpmirror.gnu.org/gnu/sed;\ elif [ $$n = tar ]; then w=http://ftpmirror.gnu.org/gnu/tar;\ elif [ $$n = wget ]; then w=http://ftpmirror.gnu.org/gnu/wget;\ @@ -333,111 +332,35 @@ $(ibdir)/make: $(tdir)/make-$(make-version).tar.lz \ # See Tar's comments for the `-j' option. $(call gbuild, $<, make-$(make-version), , , -j$(numthreads)) -$(ilidir)/ncurses: $(tdir)/ncurses-$(ncurses-version).tar.gz \ - $(ibdir)/make | $(ilidir) - - # Delete the library that will be installed (so we can make sure - # the build process completed afterwards and reset the links). - rm -f $(ildir)/libncursesw* - - # Standard build process. - $(call gbuild, $<, ncurses-$(ncurses-version), static, \ - --with-shared --enable-rpath --without-normal \ - --without-debug --with-cxx-binding \ - --with-cxx-shared --enable-widec --enable-pc-files \ - --with-pkg-config=$(ildir)/pkgconfig ) - - # Unfortunately there are many problems with `ncurses' using - # "normal" (or 8-bit) characters. The standard way that will work - # is to build it with wide character mode as you see above in the - # configuration (or the `w' prefix you see below). Also, most - # programs (and in particular Bash and AWK), first look for other - # (mostly obsolete) libraries like tinfo, which define the same - # symbols. The links below address both situations: we need to fool - # higher-level packages to find this library even if they aren't - # explicitly mentioning its name correctly (as a value to `-l' at - # link time in their configure scripts). - # - # This part is taken from the Arch Linux build script[1], then - # extended to Mac thanks to Homebrew's script [2]. - # - # [1] https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/ncurses - # [2] https://github.com/Homebrew/homebrew-core/blob/master/Formula/ncurses.rb - # - # Since we can't have comments, in the connected script, here is a - # summary: - # - # 1. We find the actual suffix of the library, from the file that - # is not a symbolic link (starting with `-' in the output of - # `ls -l'). - # - # 2. We make symbolic links to all the "ncurses", "ncurses++", - # "form", "panel" and "menu" libraries to point to their - # "wide" (character) library. - # - # 3. We make symbolic links to the "tic" and "tinfo" libraries to - # point to the same `libncursesw' library. - # - # 4. Some programs link with "curses" (not "ncurses", notice the - # starting "n"), so we'll also make links for these to point - # to the `libncursesw' library. - # - # 5. A link is made to also be able to include files from the - # `ncurses' headers. - if [ x$(on_mac_os) = xyes ]; then so="dylib"; else so="so"; fi; \ - if [ -f $(ildir)/libncursesw.$$so ]; then \ - \ - sov=$$(ls -l $(ildir)/libncursesw* \ - | awk '/^-/{print $$NF}' \ - | sed -e's|'$(ildir)/libncursesw.'||'); \ - \ - cd "$(ildir)"; \ - for lib in ncurses ncurses++ form panel menu; do \ - ln -fs lib$$lib"w".$$sov lib$$lib.$$so; \ - ln -fs $(ildir)/pkgconfig/"$$lib"w.pc pkgconfig/$$lib.pc; \ - done; \ - for lib in tic tinfo; do \ - ln -fs libncursesw.$$sov lib$$lib.$$so; \ - ln -fs libncursesw.$$sov lib$$lib.$$sov; \ - ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/$$lib.pc; \ - done; \ - ln -fs libncursesw.$$sov libcurses.$$so; \ - ln -fs libncursesw.$$sov libcursesw.$$sov; \ - ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/curses.pc; \ - ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/cursesw.pc; \ - \ - ln -fs $(idir)/include/ncursesw $(idir)/include/ncurses; \ - echo "GNU ncurses is built and ready" > $@; \ - else \ - exit 1; \ - fi - -$(ilidir)/readline: $(tdir)/readline-$(readline-version).tar.gz \ - $(ilidir)/ncurses - $(call gbuild, $<, readline-$(readline-version), static, \ - --with-curses --disable-install-examples, \ - SHLIB_LIBS="-lncursesw" ) && \ - echo "GNU Readline is built and ready" > $@ - # IMPORTANT: Even though we have enabled `rpath', Bash doesn't write the -# absolute adddress of the libraries it depends on. So if you run `ldd -# $(ibdir)/bash' on the command-line, it will say that it is linking with -# the system's `readline'. But if you run that same command within a rule -# in this reproduction pipeline, you'll see that it is indeed linking with -# our own built readline. +# absolute adddress of the libraries it depends on! Therefore, if we +# configure Bash with `--with-installed-readline' (so the installed version +# of Readline, that we build below as a prerequisite or AWK, is used) and +# you run `ldd $(ibdir)/bash' on the resulting binary, it will say that it +# is linking with the system's `readline'. But if you run that same command +# within a rule in this reproduction pipeline, you'll see that it is indeed +# linking with our own built readline. $(ibdir)/bash: $(tdir)/bash-$(bash-version).tar.gz \ - $(ilidir)/readline + $(ibdir)/make # Delete any possibly existing output rm -f $@ - # Build Bash. + # Build Bash. Note that we aren't building Bash with + # `--with-installed-readline'. This is because (as described above) + # Bash needs the `LD_LIBRARY_PATH' set properly before it is + # run. Within a recipe, things are fine (we do set + # `LD_LIBRARY_PATH'). However, Make will also call the shell + # outside of the recipe (for example in the `foreach' Make + # function!). In such cases, our new `LD_LIBRARY_PATH' is not set. + # This will cause a crash in the shell and thus the Makefile, + # complaining that it can't find `libreadline'. Therefore, even + # though we build readline below, we won't link Bash with an + # external readline. ifeq ($(static_build),yes) - $(call gbuild, $<, bash-$(bash-version), , --enable-static-link \ - --with-installed-readline=$(idir)) + $(call gbuild, $<, bash-$(bash-version), , --enable-static-link) else - $(call gbuild, $<, bash-$(bash-version), , \ - --with-installed-readline=$(idir)) + $(call gbuild, $<, bash-$(bash-version)) endif # To be generic, some systems use the `sh' command to call the @@ -465,7 +388,7 @@ endif $(idir)/etc:; mkdir $@ $(ilidir): | $(ildir); mkdir $@ $(ilidir)/zlib: $(tdir)/zlib-$(zlib-version).tar.gz \ - $(ibdir)/bash + $(ibdir)/bash | $(ilidir) $(call gbuild, $<, zlib-$(zlib-version)) && echo "Zlib is built" > $@ # OpenSSL: Some programs/libraries later need dynamic linking. So we'll @@ -544,6 +467,92 @@ $(ibdir)/wget: $(tdir)/wget-$(wget-version).tar.lz \ # Basic command-line programs necessary in build process of the # higher-level dependencies: Note that during the building of those # programs, there is no access to the system's PATH. +$(ilidir)/ncurses: $(tdir)/ncurses-$(ncurses-version).tar.gz \ + $(ibdir)/bash | $(ilidir) + + # Delete the library that will be installed (so we can make sure + # the build process completed afterwards and reset the links). + rm -f $(ildir)/libncursesw* + + # Standard build process. + $(call gbuild, $<, ncurses-$(ncurses-version), static, \ + --with-shared --enable-rpath --without-normal \ + --without-debug --with-cxx-binding \ + --with-cxx-shared --enable-widec --enable-pc-files \ + --with-pkg-config=$(ildir)/pkgconfig ) + + # Unfortunately there are many problems with `ncurses' using + # "normal" (or 8-bit) characters. The standard way that will work + # is to build it with wide character mode as you see above in the + # configuration (or the `w' prefix you see below). Also, most + # programs (and in particular Bash and AWK), first look for other + # (mostly obsolete) libraries like tinfo, which define the same + # symbols. The links below address both situations: we need to fool + # higher-level packages to find this library even if they aren't + # explicitly mentioning its name correctly (as a value to `-l' at + # link time in their configure scripts). + # + # This part is taken from the Arch Linux build script[1], then + # extended to Mac thanks to Homebrew's script [2]. + # + # [1] https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/ncurses + # [2] https://github.com/Homebrew/homebrew-core/blob/master/Formula/ncurses.rb + # + # Since we can't have comments, in the connected script, here is a + # summary: + # + # 1. We find the actual suffix of the library, from the file that + # is not a symbolic link (starting with `-' in the output of + # `ls -l'). + # + # 2. We make symbolic links to all the "ncurses", "ncurses++", + # "form", "panel" and "menu" libraries to point to their + # "wide" (character) library. + # + # 3. We make symbolic links to the "tic" and "tinfo" libraries to + # point to the same `libncursesw' library. + # + # 4. Some programs link with "curses" (not "ncurses", notice the + # starting "n"), so we'll also make links for these to point + # to the `libncursesw' library. + # + # 5. A link is made to also be able to include files from the + # `ncurses' headers. + if [ x$(on_mac_os) = xyes ]; then so="dylib"; else so="so"; fi; \ + if [ -f $(ildir)/libncursesw.$$so ]; then \ + \ + sov=$$(ls -l $(ildir)/libncursesw* \ + | awk '/^-/{print $$NF}' \ + | sed -e's|'$(ildir)/libncursesw.'||'); \ + \ + cd "$(ildir)"; \ + for lib in ncurses ncurses++ form panel menu; do \ + ln -fs lib$$lib"w".$$sov lib$$lib.$$so; \ + ln -fs $(ildir)/pkgconfig/"$$lib"w.pc pkgconfig/$$lib.pc; \ + done; \ + for lib in tic tinfo; do \ + ln -fs libncursesw.$$sov lib$$lib.$$so; \ + ln -fs libncursesw.$$sov lib$$lib.$$sov; \ + ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/$$lib.pc; \ + done; \ + ln -fs libncursesw.$$sov libcurses.$$so; \ + ln -fs libncursesw.$$sov libcursesw.$$sov; \ + ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/curses.pc; \ + ln -fs $(ildir)/pkgconfig/ncursesw.pc pkgconfig/cursesw.pc; \ + \ + ln -fs $(idir)/include/ncursesw $(idir)/include/ncurses; \ + echo "GNU ncurses is built and ready" > $@; \ + else \ + exit 1; \ + fi + +$(ilidir)/readline: $(tdir)/readline-$(readline-version).tar.gz \ + $(ilidir)/ncurses + $(call gbuild, $<, readline-$(readline-version), static, \ + --with-curses --disable-install-examples, \ + SHLIB_LIBS="-lncursesw" ) && \ + echo "GNU Readline is built and ready" > $@ + $(ibdir)/diff: $(tdir)/diffutils-$(diffutils-version).tar.xz \ $(ibdir)/bash $(call gbuild, $<, diffutils-$(diffutils-version), static) @@ -553,7 +562,7 @@ $(ibdir)/find: $(tdir)/findutils-$(findutils-version).tar.lz \ $(call gbuild, $<, findutils-$(findutils-version), static) $(ibdir)/gawk: $(tdir)/gawk-$(gawk-version).tar.lz \ - $(ibdir)/bash + $(ilidir)/readline $(call gbuild, $<, gawk-$(gawk-version), static, \ --with-readline=$(idir)); @@ -595,7 +604,7 @@ $(ibdir)/which: $(tdir)/which-$(which-version).tar.gz \ # (CURRENTLY IGNORED) GCC prerequisites # ------------------------------------- $(ilidir)/gmp: $(tdir)/gmp-$(gmp-version).tar.lz \ - $(ibdir)/bash + $(ibdir)/bash | $(ilidir) $(call gbuild, $<, gmp-$(gmp-version), static, , , make check) \ && echo "GNU multiple precision arithmetic library is built" > $@ -- cgit v1.2.1