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

Problematic check for run-time libs availability in autoconf scripts #11114

Closed
jbulow opened this issue May 15, 2023 · 8 comments
Closed

Problematic check for run-time libs availability in autoconf scripts #11114

jbulow opened this issue May 15, 2023 · 8 comments
Labels

Comments

@jbulow
Copy link

jbulow commented May 15, 2023

curl/m4/curl-functions.m4

Lines 5856 to 5876 in f157610

dnl CURL_RUN_IFELSE
dnl -------------------------------------------------
dnl Wrapper macro to use instead of AC_RUN_IFELSE. It
dnl sets LD_LIBRARY_PATH locally for this run only, from the
dnl CURL_LIBRARY_PATH variable. It keeps the LD_LIBRARY_PATH
dnl changes contained within this macro.
AC_DEFUN([CURL_RUN_IFELSE], [
case $host_os in
darwin*)
AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4)
;;
*)
old=$LD_LIBRARY_PATH
LD_LIBRARY_PATH=$CURL_LIBRARY_PATH:$old
export LD_LIBRARY_PATH
AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4)
LD_LIBRARY_PATH=$old # restore
;;
esac
])

When compiling a projects and its dependencies (curl) with custom compiler flags (such as enabling address sanitizers) this autoconf macro will also test that the compiler can run with the libraries found on the path(s) set in LD_LIBRARY_PATH. This will result in a failure when a library used by both the compiler and curl is used. libz is such a library.

This is how configure fails:

checking for sys/time.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for struct timeval... yes
checking run-time libs availability... failed
configure: error: one or more libs available at link-time are not available run-time. Libs used at link-time: -lpsl -lssl -lcrypto -lssl -lcrypto -lz

Looking in config.log the error is seen:

clang: symbol lookup error: /my_projects_sysroots/lib/libz.so.1: undefined symbol: __asan_option_detect_stack_use_after_return

Running from command line the problem can be reproduced by:

LD_LIBRARY_PATH=/my_projects_sysroots/lib clang
clang: symbol lookup error: /my_projects_sysroots/lib/libz.so.1: undefined symbol: __asan_option_detect_stack_use_after_return

To summarize: LD_LIBRARY_PATH should not be set when compiling conftest.c in the configure script. It should only be set when running the resulting program.

@bagder bagder added the build label May 15, 2023
@bagder
Copy link
Member

bagder commented May 15, 2023

Problematic, yes. Also very challenging to fix, since the autotools macro AC_RUN_IFELSE that we use for this both compiles and runs the code without really offering a way to set the variable only for the execution and not for the compiling part.

@jbulow
Copy link
Author

jbulow commented May 15, 2023

Maybe it is possible to temporarily change the CC variable to include the LD_LIBRARY_PATH set to $old value (from CURL_RUN_IFELSE) ?

By directly changing the configure script like this:

ac_compile='LD_LIBRARY_PATH= $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='LD_LIBRARY_PATH= $CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'

The configure script will succeed as expected. I'm not sure if it is possible to expand $CC to include this change though.

IIRC, the compiler needs to be wrapped in a script in order for the expansion of CC to work correctly in this case.

@bagder
Copy link
Member

bagder commented May 15, 2023

Right, something like this?

diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index 4d4d13a40..6bef89720 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -5864,15 +5864,18 @@ AC_DEFUN([CURL_RUN_IFELSE], [
    case $host_os in
      darwin*)
       AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4)
      ;;
      *)
+      oldcc=$CC
+      CC="./compiler $CC"
       old=$LD_LIBRARY_PATH
       LD_LIBRARY_PATH=$CURL_LIBRARY_PATH:$old
       export LD_LIBRARY_PATH
       AC_RUN_IFELSE([AC_LANG_SOURCE([$1])], $2, $3, $4)
       LD_LIBRARY_PATH=$old # restore
+      CC=$oldcc
      ;;
    esac
 ])
 
 dnl CURL_COVERAGE

and:

$ cat compiler
#!/bin/sh

LD_LIBRARY_PATH=
exec $@

@jbulow
Copy link
Author

jbulow commented May 16, 2023

I think the compiler script must be generated by the configure script and set LD_LIBRARY_PATH=$old. Maybe expand $CC within the script as well to avoid having a "two part" CC variable that doesn't expand correctly in all circumstances.

I could not test the patch above as autoreconf -if ignores the files in the m4 directory when generating the configure script.

@jbulow
Copy link
Author

jbulow commented May 16, 2023

A simple workaround is to use curl´s cmake buildsystem.

@bagder
Copy link
Member

bagder commented May 16, 2023

There are plenty of workarounds. If cmake is good enough, then that might be the easiest.

autoreconf -if ignores the files in the m4 directory when generating the configure script.

That's the only way we ever generate configure so that sounds wrong.

bagder added a commit that referenced this issue May 16, 2023
in the CURL_RUN_IFELSE macro, with LD_LIBRARY_PATH set to the value of
the configure invoke, and not the value that might be used later,
intended for the execution of the output the compiler ouputs.

For example when the compiler uses the same library (like libz) that
configure checks for.

Reported-by: Jonas Bülow
Fixes #11114
@bagder
Copy link
Member

bagder commented May 16, 2023

@jbulow does #11120 make things work for you?

@jbulow
Copy link
Author

jbulow commented May 17, 2023

Yes, it seems to work fine! Sorry for the delay, I had some issues bringing the patch into our buildsystem.

Thanks!

@bagder bagder closed this as completed in b78ca50 May 18, 2023
bch pushed a commit to bch/curl that referenced this issue Jul 19, 2023
in the CURL_RUN_IFELSE macro, with LD_LIBRARY_PATH set to the value of
the configure invoke, and not the value that might be used later,
intended for the execution of the output the compiler ouputs.

For example when the compiler uses the same library (like libz) that
configure checks for.

Reported-by: Jonas Bülow
Fixes curl#11114
Closes curl#11120
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

2 participants