Undefined references inside lib/odbc/c_src with libei development files installed
Describe the bug This is more a warning than a bug. I tried compiling a recent version of erlang (26.2.3) on my linux (fedora) machine and it failed with several undefined references to ei_* when linking odbcserver.
I inspected what happened and it seems the linker is picking up libei.so from https://gitlab.freedesktop.org/libinput/libei when installed. I think the latter in not yet widely used but given that is part of the wayland stack, we could anticipate this to happen more often.
To Reproduce Compile while having libei development files installed.
Expected behavior Compilation succeeds
Affected versions I tested with 26.2.2 and 26.2.3
Additional context
I am not completely sure about the fix. Removing libei from my machine solves the issues. Also removing -L/usr/lib64 prior to -lodbc in the linker command make linking succeed.
I can confirm this issue. Here is a build log.
This seems to be a name clash issue. I am not really sure what is the best way to solve it. Maybe it would be to use a absolute path somehow for odbc to find the OTP ei-libary. A PR would be welcome.
find-internal-libei-before-system-libei.patch.txt
I am not sure this is the proper way to handle but applying this patch makes the compilation succeed for me. Basically it makes the end of the linker command look like:
-L/tmp/buildroot/otp_src_26.2.3/lib/erl_interface/obj/x86_64-redhat-linux-gnu -lpthread -lei -L/usr/lib64 -lodbc
instead of:
-L/usr/lib64 -lodbc -L/tmp/buildroot/otp_src_26.2.3/lib/erl_interface/obj/x86_64-redhat-linux-gnu -lpthread -lei
I cannot access the patch so I include it here:
--- ./lib/odbc/c_src/Makefile.in
+++ ./lib/odbc/c_src/Makefile.in
@@ -80,10 +80,10 @@
# ----------------------------------------------------
CC = @CC@
CFLAGS = $(TYPEFLAGS) @CFLAGS@ @THR_DEFS@ @DEFS@
-EI_LDFLAGS = -L$(EI_ROOT)/obj$(TYPEMARKER)/$(TARGET)
+EI_LDFLAGS = -L$(EI_ROOT)/obj$(TYPEMARKER)/$(TARGET) $(EI_LIB)
LD = @LD@
-LDFLAGS = $(ODBC_LIB) $(EI_LDFLAGS)
-LIBS = @LIBS@ @THR_LIBS@ $(EI_LIB)
+LDFLAGS = $(EI_LDFLAGS) $(ODBC_LIB)
+LIBS = @LIBS@ @THR_LIBS@
INCLUDES = -I. $(ODBC_INCLUDE) $(EI_INCLUDE)
TARGET_FLAGS = @TARGET_FLAGS@
It seems from the documentation that when multiple -L values are specified the paths are searched for from left to right.
So in order to be sure that the linker picks up the internal library the -L<path_to_directory_with_internal_libei> -lei should occur before any other occurrences of -L, in particular any "system" paths like /usr/lib or /usr/lib64.
https://www.linuxtopia.org/online_books/an_introduction_to_gcc/gccintro_24.html
@zazaho You suggestion is much apricated, we would be even more happy if you cold provide it as a pull request, it would make possible inclusion much more efficient.
https://github.com/erlang/otp/pull/8258