Closed tkralphs closed 4 years ago
I extra made the LT_LDFLAGS variable more accessible in d1d64dc, so that it is easier to set the -all-static
flag for libtool. I would think that there is no need for an extra configure flag that just sets this flag.
I probably didn't understand what you meant by " forbid that at configure time". You mean adding -static
to LDFLAGS?
I just meant basically transferring the recipe that is now in coinbrew
(here) to configure
. We would just ignore any request to link to libraries we know will prevent the fully static executable from being created. One of the sticking points that was not at all obvious was just that even when you specify -static
and do everything right, libtool
will happily link to shared libraries anyway and you end up with a non-static executable even though you explicitly said you don't want one.
That thing in coinbrew seems to assume that bzlib, readline, lapack, amd, etc are only available as shared libraries and have to be disabled. Also it seems to think that third-party needs to be disabled. I don't think that such restrictive and specific rules are what one would want to have in BuildTools.
I get it that a -static
in the libtool flags just tells libtool to build a static library, which may depend on other libs that may be available as shared library only.
With -all-static
in the libtool flags, a -static
should be passed on to the linker, as far as I understood. For executables this would then fail when some lib is not available as shared library.
Maybe a call of configure with LT_LDFLAGS=-all-static LDFLAGS=-static --disable-shared
would do something to also prevent configure from recognizing packages that are not available as static libraries. For coin-or packages, we just believe that the flags from the .pc file are working, though, and do not try linking something during configure.
Hmm, OK, I see your point. Yes, I am assuming that those libraries that are disabled are only available as shared libraries, since that's the typical case and when it's not, the person doing the building will presumably know enough to build by hand. So I guess it's betters as is.
It seems to me that libtool linking doesn't ever fail because it cannot find a static library, though, even when -all-static
and -static
are specified. This is what was so frustrating in trying to make static executables. I couldn't ever get libtool to explain when things were going wrong. I just had to try and see if I get what I wanted, there was never an error.
So I can get pretty far with the above mentioned LT_LDFLAGS=-all-static LDFLAGS=-static --disable-shared
e38d1115 changes the lapack test to only warn if lapack.pc is present, but linking doesn't work.
I updated the Makefile.am of the unittest of CoinUtils, Osi, Clp, Cgl, and Cbc to acknowledge LT_LDFLAGS, so their binary is build with -static, too.
On my system, which has only shared library versions of gfortran and lapack, I can get static executables of cbc and clp and static libs lib/libCbc.a lib/libCgl.a lib/libClpSolver.a lib/libcoinglpk.a lib/libCoinUtils.a lib/libOsiCbc.a lib/libOsiCommonTest.a lib/libCbcSolver.a lib/libClp.a lib/libcoinasl.a lib/libcoinmetis.a lib/libOsi.a lib/libOsiClp.a lib/libOsiGlpk.a if I omit trying to build Mumps and HSL.
Maybe these configure flags are something you want to mention in https://coin-or.github.io/user_introduction#additional-useful-information
So you did not need to disable all the libraries that I did? And you managed to get fully static binaries? I tried many incantations and couldn't get fully static executables without manually disabling libraries. I can try again, but something strange is going on here.
The flags mentioned are all the ones for configure necessary for me.
I got "fully static binaries":
$ ldd bin/*
bin/cbc:
not a dynamic executable
bin/cbc-generic:
not a dynamic executable
bin/clp:
not a dynamic executable
bin/glpsol:
not a dynamic executable
I haven't tried whether --disable-shared
is indeed necessary or whether configure will figure out by itself that it cannot build shared libraries with LDFLAGS=-static
.
I built Clp with LT_LDFLAGS=-all-static LDFLAGS=-static --disable-shared
and got this.
~/tmp/dist/bin > ldd clp
linux-vdso.so.1 (0x00007fffd4f7e000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007ff3603d0000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ff3601b0000)
liblapack.so.3 => /usr/lib/x86_64-linux-gnu/liblapack.so.3 (0x00007ff35f910000)
libgfortran.so.4 => /usr/lib/x86_64-linux-gnu/libgfortran.so.4 (0x00007ff35f530000)
libblas.so.3 => /usr/lib/x86_64-linux-gnu/libblas.so.3 (0x00007ff35f2c0000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007ff35f030000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff35ee10000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff35ea80000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff35e6e0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff35e4c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff35e0c0000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007ff35de80000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff361000000)
So what should I do with that? I cannot look into your system to see what has happening to get you there.
I wasn't expecting you to do anything with that, just providing a data point. Anyway, I realized that I was accidentally building 2.10.5 and the behavior is much different there. There seems to be no hope of static binaries there.
I tried your recipe with master and I did now get some errors when things are not working, which helps immensely. I still needed to disable readline, but I no longer need to disable the other things I was previously disabling. Thanks!
Well, I was curious why you had gotten this, but there was so little information... :).
If there are errors that should rather be warnings, then we can look into it. If there is only a shared libgfortran, there is not much one can do from within configure - you just cannot build mumps or hsl then. What do you get if you don't disable readline? An error or a dependency on a shared library?
It looked like a dependency on a shared library, but let me do it again and see.
With readline, I get a bunch of errors like this, which I take to mean that I will not get a static executable in the end.
/mnt/c/Users/tkral/Documents/tmp/dist/lib/libcoinasl.a(funcadd1.o): In function `dl_open.isra.0':
funcadd1.c:(.text+0x129): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libreadline.a(complete.o): In function `rl_username_completion_function':
(.text+0x4419): warning: Using 'getpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Strangely, although there is an error with ASL, it goes away if I disable readline.
I'll see if this is fixed by -static-libgcc and -static-libstdc++
.
These are warning, not errors. I also get the one regarding dlopen in codes that use it (like ASL), but I get a static binary at the end. I guess they will at least work until these specific functions are called.
Ah, OK. Those are warnings, but there are errors because the build stops. There are a bunch of errors like these:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libreadline.a(display.o): In function `_rl_move_cursor_relative':(.text+0xf86): undefined reference to `tputs'
(.text+0xfec): undefined reference to `tputs'
(.text+0x11ac): undefined reference to `tputs'
Not sure how to interpret that. There seems to be a mismatch between the static version of readline installed and some other libraries. Guess I could do an update and see if that helps.
Maybe it just misses to link against -lncurses
. AC_COIN_CHK_GNU_READLINE seems to look for it, but doesn't add it to LFLAGS
Maybe it just misses to link against
-lncurses
. AC_COIN_CHK_GNU_READLINE seems to look for it, but doesn't add it to LFLAGS
Maybe this would do:
diff --git a/coin.m4 b/coin.m4
index 0707ed1..c4389c6 100644
--- a/coin.m4
+++ b/coin.m4
@@ -1895,7 +1895,7 @@ AC_DEFUN([AC_COIN_CHK_GNU_READLINE],
fi
if test $coin_has_readline = yes ; then
m4_foreach_w([myvar],[$1],
- [m4_toupper(myvar)_LFLAGS="-lreadline $m4_toupper(myvar)_LFLAGS"
+ [m4_toupper(myvar)_LFLAGS="$LIBS $m4_toupper(myvar)_LFLAGS"
])
AC_DEFINE([COIN_HAS_READLINE],[1],[Define to 1 if readline is available])
fi
Yes, that worked.
Excellent, static libraries without any special recipe! Wahoo!
Will you apply the fix then?
yes, done
Are you going to re-run autotools for all the projects?
I should get there later today as I'm doing some other changes in BuildTools anyway.
After all the time spent trying to figure out how to build fully static executables, I now realized that SYMPHONY already had a recipe for that baked into its build system. See here:
https://github.com/coin-or/SYMPHONY/blob/master/SYMPHONY/src/Makefile.am#L353
Ugh, that all-important
-all-static
flag was sitting right there the whole time. I guess one of my co-developers figured that out long ago. Would it make sense to provide a--fully-static
flag toconfigure
? I guess maybe not, since to get truly static libraries, it seems necessary to ensure that no system libraries that are shared are linked in, etc. Or I guess we could also forbid that at configure time in the case of fully static? What do you think?