linux linker: '-lpng' inhibits '-lz'? - linux

On ubuntu-13.04, I got an error when building an executable from shared libraries, using GCC-4.7.3 provided by the linux distribution.
I guess the problem is between libpng and zlib (the former uses the latter), but I don't know why.
First, my command is:
$ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp
-Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++
-Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so
-lpng -lz -lpthread -lreadline -lhistory
which gives the following error:
/usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzopen'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzclose'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzread'
collect2: error: ld returned 1 exit status
But note that -lz is present. After that, I added the linker option --trace-symbol= in order to get more information:
$ gfortran -o test_muesli_config_fml test_muesli_config_fml.o -fopenmp
-Wl,--rpath,/usr/local/lib/muesli /usr/local/lib/muesli/libfml.so -lstdc++
-Wl,--rpath,/usr/lib /usr/lib/liblapack.so -Wl,--rpath,/usr/lib /usr/lib/libblas.so
-lpng -lz -lpthread -lreadline -lhistory -Wl,--trace-symbol=gzwrite
which in turn gives the results:
/usr/local/lib/muesli/libfml.so: reference to gzwrite
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libz.so: definition of gzwrite
/usr/local/lib/muesli/libfml.so: undefined reference to `gzwrite'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzopen'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzclose'
/usr/local/lib/muesli/libfml.so: undefined reference to `gzread'
collect2: error: ld returned 1 exit status
so, gzwrite is found in libz.so but the linker don't use it!
By chance, I thought to remove the -lpng option (actually, the libpng library is not used) and my problem is solved! Why?
Secondly, I compile my whole code with another version of GCC-4.7.3 (compiled by myself -- I am used to test many versions of the compiler), and the error didn't occur, even using both -lpng and -lz!
Any idea?
In addition, a different try with another program (which USE libpng) leads to a successful build.
Edited on 2013-10-08
I'm pretty sure now that it is a bug in ubuntu-13.04: I've tried two other linux distros (Fedora 16 -- Ubuntu-10.04) and the linker behavior is standard, not as described above in the first part of my message.
I plan to report this problem on ubuntu community. Regards.
Edited on 2013-10-09
The bug has been reported to https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1237270

Two possible fixes (until ubuntu doesn't repair itself):
Try to compile in libpng.a and libz.a as a static library (it can be only a temporary solution, because static libs are evil in most cases).
Recompile libpng from the original source, and compile libz.a as static herein.

Related

golang with cgo throws error collect2: error: ld returned 1 exit status

I am compiling a golang package, which includes the integration of a shared c library using cgo.
Everything builds successfully inside docker images golang:1.15.15, golang:1.16.6, but since golang:1.16.7 (also golang:1.17) it fails with error:
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `feenableexcept'
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `floor'
...
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `memoFree'
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `memoMalloc'
collect2: error: ld returned 1 exit status
I checked the golang release notes, and could not find any relevant changes for cgo.
I checked versions of gcc and ld, those are all different. I even setup a ubuntu distro with go1.13.8, gcc (Ubuntu 8.4.0-3ubuntu2) 8.4.0 and GNU ld (GNU Binutils for Ubuntu) 2.34, where I run into this issue, so I guess, that go goes not cause it.
Do you have any clue or suggestion, how I can find the root cause of this issue? Is it right to check gcc and ld, or which other tools need investigation?
Thanks to Zyl, I was able to narrow down the problem.
I checked several distributions (bullseye, buster, stretch) and with bullseye, the build failed. In my case, neither the version of ld coming from binutils nor gcc caused the problem.
It seems, that the default settings for handling DT_NEEDED tags for the linker have changed. I resolved my problem taking the solution from https://stackoverflow.com/a/62117174/2290153 and adding export CGO_LDFLAGS=-Wl,--no-as-needed to the environment. According to https://manpages.debian.org/bullseye/binutils-common/gold.1.en.html this is the default for the ld.gold linker, but not for ld.
What helped me a lot, was the -x flag of the go build command to have a look at the gcc command being executed for cgo.

gcc dialog library not linking

I'm trying to develop a small utility using the dialog library in C (the dialog command in linux).
On fedora linux works fine, but if i try to compile it on debian with the command:
gcc -ldialog -lncurses -I/usr/include dialog_test.c
I get the following error:
vetinari#ankhmorpork:~/Projects/Other/test$ gcc -ldialog -I/usr/include dialog_test.c
/usr/bin/ld: /tmp/ccX6fPYB.o: warning: relocation against `dialog_vars' in read-only section `.text'
/usr/bin/ld: /tmp/ccX6fPYB.o: in function `main':
dialog_test.c:(.text+0x5c): undefined reference to `init_dialog'
/usr/bin/ld: dialog_test.c:(.text+0x79): undefined reference to `dialog_yesno'
/usr/bin/ld: dialog_test.c:(.text+0xae): undefined reference to `dialog_menu'
/usr/bin/ld: dialog_test.c:(.text+0xbc): undefined reference to `dialog_vars'
/usr/bin/ld: dialog_test.c:(.text+0xc5): undefined reference to `end_dialog'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
The dialog command works fine.
Anyone has any idea why it isn't working on debian?
(Answer for the wiki sake, in case someone comes by here later)
You have to put the libraries you want to link at the end of the gcc command, like this:
gcc dialog_test.c -ldialog -lncurses
The reason is explained here: The way the linker looks up symbols it has to first see the reference, and then the library prodiving the symbol
Additionally, the dialog library might have other dependencies than ncurses. There is explanation how to find out what to include and what to link here, in short: dialog-config should tell you about it.
In this specific case, what worked for me (ubuntu 20.04) was linking ncursesw instead of ncurses.
After that, I was left with an
undefined reference to `sqrt'
linker error, which can be solved by linking the match library using -lm.
So, in total, this command works:
gcc dialog_test.c -ldialog -lncursesw -lm

How to satisfy dependencies for static compilation of 'dialog' tool for 32-bit

I want to compile the dialog program as 32-bit and statically linked executable in a 64-bit Ubuntu (16.04). This makes it easily distributable in a makeself archive without worrying about dependencies and such. I already built it 3 years ago that way and also took notes how to do it:
# get source and build-deps, then run:
./configure CFLAGS="-m32" LDFLAGS="-m32 -static"
make
Now I modified the source (added additional option) but the rebuild fails with complaints about undefined reference to Gpm_*** functions. This is unrelated to my modifications. Linking stage:
gcc -o dialog dialog.o -L. -ldialog -Wl,-rpath,/lib64 -L/lib64 -m32 -static -lncurses -ltermcap -lm
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `_nc_mouse_event':
(.text+0x632): undefined reference to `Gpm_GetEvent'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `enable_gpm_mouse':
(.text+0xcd2): undefined reference to `Gpm_Close'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `enable_gpm_mouse':
(.text+0xd22): undefined reference to `Gpm_Open'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `enable_gpm_mouse':
(.text+0xd3a): undefined reference to `Gpm_Close'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `_nc_mouse_init':
(.text+0xe8c): undefined reference to `gpm_fd'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/libncurses.a(lib_mouse.o): In function `mouse_activate':
(.text+0x1061): undefined reference to `gpm_fd'
collect2: error: ld returned 1 exit status
makefile:211: recipe for target 'dialog' failed
make: *** [dialog] Error 1
The linker picks up the libncurses.a which seems to be ok to me as it is a static library archive. I don't understand why the Gpm_*** functions are not found. The libgpm.a provides these and is in the same directory. Even configuring with adding /usr/lib/i386-linux-gnu/libgpm.a to the LDFLAGS has no effect.
How can I make it link successfully?
Update:
See results with verbose linking (-Wl,--verbose) here: https://pastebin.com/AP48KMGt
It works for me after installing gcc-multilib (of course) and the i386 development packages for libncurses5, libtinfo and libgpm:
sudo apt install gcc-multilib libncurses5-dev:i386 libtinfo-dev:i386 libgpm-dev:i386
and linking explicitly with them:
gcc -o dialog dialog.o -L. -ldialog -g -O2 -m32 -static -lncurses -ltinfo -lgpm -lm
I got./configure to generate a working Makefile based on your example, with
$ ./configure CFLAGS="-m32" LDFLAGS="-m32 -static" LIBS="-lgpm"
$ make
...
gcc -o dialog dialog.o -L. -ldialog -m32 -Wl,-rpath,/lib64 -L/lib64 -m32 -static -lncurses -ltermcap -lm -lgpm
The result seems to be a valid i386 executable:
$ file dialog
dialog: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=4cbdb45a86cb5e6859db8c7cbeeaaa49baf45718, not stripped
Note: I tried passing --host=i686-linux-gnu, --host=i686-pc-linux-gnu, --host=i386-linux-gnu or --host=i386-pc-linux-gnu to ./configure, but it didn't make any difference.

Linking error: DSO missing from command line

I am rather new to Linux (using Ubuntu 14.04 LTS 64bit), coming from Windows, and am attempting to port over an existing CUDA project of mine.
When linking via
/usr/local/cuda/bin/nvcc -arch=compute_30 -code=sm_30,compute_30 -o Main.o Display.o FileUtil.o Timer.o NeuralNetwork.o -L/usr/lib -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/cuda/lib64 -lGLEW -lglfw3 -lGL -lGLU -lcuda -lcudart
I encounter the following error:
/usr/bin/ld: /usr/local/lib/libglfw3.a(x11_clipboard.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [CUDANN] Error 1
The answer seems closely related to the solutions in this post (Strange linking error: DSO missing from command line), though given my inexperience with Linux I was unable to adapt them to my own problem.
Any ideas on what the problem could be?
Here is the full output during compilation: https://gist.github.com/wbolden/857eddd11e4dcb915c02
And here is my attempt at a Makefile:
https://gist.github.com/wbolden/135033daae04ed0d8cf3
Hopefully this will be of help to those, like me, who are new to Linux and don't find anything related to Linux to be particularly obvious.
As noted by talonmies, I am not able to link indirectly and as such need to specify any additional libraries required by the libraries I am using. That is to say, if I link library A, which requires libraries B and C, I need to link all three libraries for the program to link correctly.
To find what other libraries were needed I used the pkg-config command, for which I found a guide here. Running pkg-config --print-requires --print-requires-private glfw3 gave the following output, which is the list of packages required by glfw3.
x11
xrandr
xi
xxf86vm
gl
I was then able to find what libraries I needed to include by running pkg-config --libs, followed by the name of the library. For example, pkg-config --libs x11 yielded -lX11.
Note: you can pass multiple items to pkg-config as input, so running
pkg-config --libs $(pkg-config --print-requires --print-requires-private glfw3)
will print out all the additional libraries you need to link (-lX11 -lXrandr -lXi -lXxf86vm -lGL).
My program now links successfully, I hope this helpful to anyone with a similar problem.
Your linker need X11 library,You need to specify -lX11 to linker
Try
/usr/local/cuda/bin/nvcc -arch=compute_30 -code=sm_30,compute_30 -o Main.o Display.o FileUtil.o Timer.o NeuralNetwork.o -L/usr/lib -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/cuda/lib64 -lGLEW -lglfw3 -lGL -lGLU -lcuda -lcudart -lX11
Try to add -pthread at the end of the library list (command line) in the Makefile.
It worked for me.
Use the following commands to fix the issue:
FLAGS=-lX11 ./configure --prefix=/usr --disable-static
make
make install

Undefined reference to WinMain in Cygwin

I am trying to compile and having following problem
$ gcc errlib.c -o errlib.o
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `WinMain'
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/lib/libcmain.c:39:(.text.startup+0x7e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
Any suggestions? These files are well tested and generated the code fine before but now i think there might be some cygwin settings or so ... m compiling on windows 8 on cygwin.
Use -c compile flag to only produce object file. Without -c it tries to link an executable and the linker (called automatically) fails.

Resources