I've downloaded and compiled: http://leenissen.dk/fann/wp/
cmake version 2.8.11.2
gcc (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.1
Command used to compile:
cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr .
Installation:
sudo make && sudo make install
Then I go to examples/ directory inside fann project and try to compile examples by running:
make all
I'm getting an error:
gcc -O3 xor_train.c -o xor_train -lfann -lm
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `sin'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `exp'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `cos'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `log'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `pow'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `sqrt'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so: undefined reference to `floor'
collect2: error: ld returned 1 exit status
make: *** [xor_train] Error 1
Update:
I've followed an instruction given by a library
I've checked on another machine and provided instruction works as intended so I guess my environment is in a some way misconfigured.
Some more info about shared library dependencies:
ldd /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libfann.so
linux-vdso.so.1 => (0x00007fff3abfe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f3997c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6f39f84000)
As suggested by #michael-burr compiled with -Wl,-v
/usr/bin/ld --sysroot=/ \
--build-id --eh-frame-hdr -m elf_x86_64 \
--hash-style=gnu --as-needed \
-dynamic-linker /lib64/ld-linux-x86-64.so.2 \
-z relro -o xor_train \
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o \
-L/usr/lib/gcc/x86_64-linux-gnu/4.8 \
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu \
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib \
-L/lib/x86_64-linux-gnu \
-L/lib/../lib -L/usr/lib/x86_64-linux-gnu \
-L/usr/lib/../lib \
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. \
-v /tmp/cc0AHZgU.o -lfann -lm -lgcc --as-needed -lgcc_s --no-as-needed \
-lc -lgcc --as-needed -lgcc_s --no-as-needed \
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o
GNU ld (GNU Binutils for Ubuntu) 2.23.52.20130913
Root cause: missing dependencies in FANN library (Will send a patch to author). Such a dependency is called "inter library dependency".
It may happen that one build a shared library A and doesn't have correct dependencies set (let's say B).
In such a case a shared library A will be build without any error msg as it's not required to provide implementation during compiling.
The problem will appear as a lack of library B when one try to create an executable file which depends on A.
In this specific case a solution is to modify a CMake configuration file according to CMake manual
Example changeline:
TARGET_LINK_LIBRARIES(fann m)
It looks like you're compiling your own program as 64-bit, but the FANN library is 32-bit. You might need to specify an architecture for FANN when you compile, which might mean modifying GCC flags in the makefile, unless there are autoconf settings to do it for you. Assuming that you want 64-bit FANN.
Alternatively, you could specify 32-bit architecture when you compile your own code.
Related
TLDR I tried to read the clang llvm documentation to find a way to pass library path, I wasn't successful. Then I searched and found a solution. I am curious where I can find the documentation of my solution.
Details and why
I was trying to run ruby's bundle on my catalina and I faced this error:
ld: library not found for -lssl
I reinstalled openssl using brew install openssl and then brew link openssl I received the follwoing response from it:
Warning: Refusing to link macOS provided/shadowed software: openssl#1.1
If you need to have openssl#1.1 first in your PATH run:
echo 'export PATH="/usr/local/opt/openssl#1.1/bin:$PATH"' >> ~/.zshrc
For compilers to find openssl#1.1 you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl#1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl#1.1/include"
For pkg-config to find openssl#1.1 you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/openssl#1.1/lib/pkgconfig"
While I appreciated brew's effort to make it work non of those worked. I narrowed the linker issue to this to see what's going on:
clang -dynamic -bundle -o asdf -L/usr/local/Cellar/mysql/8.0.19/lib -lmysqlclient -lssl -lcrypt -v
Finally using LIBRARY_PATH I made passed the enviornment variable
export LIBRARY_PATH=/usr/local/opt/openssl#1.1/lib/
You were able to make the clang linkage:
clang -dynamic -bundle -o asdf -L/usr/local/Cellar/mysql/8.0.19/lib -lmysqlclient -lssl -lcrypt -v
succeed when it otherwise failed by setting:
export LIBRARY_PATH=/usr/local/opt/openssl#1.1/lib/
in the environment of the clang command.
That's evidence that clang is influenced by the LIBRARY_PATH environment
variable in the same way as GCC compilers.
LIBRARY_PATH is not mentioned in the ENVIRONMENT section of man clang,
or indeed at all, so this GCC-like behaviour can strictly be viewed as not mandatory.
It seems likely however that the omission is an oversight in the manual,
since clang generally strives to be an unobtrusive substitute for gcc. If
we run a Linux clang linkage in verbose mode:
$ export LIBRARY_PATH=/wheres/wally; clang -v main.o -L. -lfoo -lbar
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Candidate multilib: .;#m64
Selected multilib: .;#m64
"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr \
-m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out \
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crt1.o \
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o \
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/crtbegin.o \
-L. -L/usr/bin/../lib/gcc/x86_64-linux-gnu/9 \
-L/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu \
-L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu \
-L/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../.. \
-L/usr/lib/llvm-10/bin/../lib -L/lib -L/usr/lib \
-L/wheres/wally \ # < There's wally!
main.o -lfoo -lbar -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc \
--as-needed -lgcc_s --no-as-needed \
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/crtend.o \
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o
we observe clang inserting the expansion of -L${LIBRARY_PATH} into
the ld commandline after all of the other -Ldir options. And if we
track down LIBRARY_PATH in the clang source tree,
we'll see the code that makes it do so.
In the ENVIRONMENT section of man gcc,
LIBRARY_PATH is documented:
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of directories, much like PATH .
When configured as a native compiler, GCC tries the directories thus specified when
searching for special linker files, if it can't find them using GCC_EXEC_PREFIX .
Linking using GCC also uses these directories when searching for ordinary libraries
for the -l option (but directories specified with -L come first).
and the same appears verbatim in GCC online documentation: 3.21 Environment Variables Affecting GCC
What clang does with LIBRARY_PATH conforms with the sentence I've emphasised.
It's worth knowing that while using LIBRARY_PATH for this purpose may have got
you out of a jam, it is not favoured in regular linkage practice, because it is
likely to be an invisible hand when you are studying the output of a
linkage: its effect is only revealed in verbose mode (by either gcc or clang). The
installer's recommendation:
export LDFLAGS="-L/usr/local/opt/openssl#1.1/lib"
is what you'd expect. I've no insight into why it didn't work for you.
On Debian bullseye (testing), with these xz/lzma-related packages installed:
ii liblzma-dev:amd64 5.2.4-1+b1 amd64
ii liblzma5:amd64 5.2.4-1+b1 amd64
ii lzma-dev 9.22-2.1 all
Clang generates a working ./a.out without issue:
$>gunzip < /usr/share/doc/liblzma-dev/examples/02_decompress.c.gz | sed -s 's/extern int/int' | clang -std=c18 -Wall -Wextra -x c -llzma -
However, attempting to use gcc fails:
$>gunzip < /usr/share/doc/liblzma-dev/examples/02_decompress.c.gz | sed -s 's/extern int/int' | gcc -std=c18 -Wall -Wextra -x c -llzma -
/usr/bin/ld: /tmp/ccl8uTG0.o: in function `init_decoder':
:(.text+0x20): undefined reference to `lzma_stream_decoder'
/usr/bin/ld: /tmp/ccl8uTG0.o: in function `decompress':
:(.text+0x1e1): undefined reference to `lzma_code'
/usr/bin/ld: /tmp/ccl8uTG0.o: in fuction `main':
:(.text+0x4e4): undefined reference to `lzma_end'
collect2: error: ld returned 1 exit status
g++ --version reports 9.3.0-3
clang++ --version reports 9.0.1-10
(Those compilers are both installed via apt-get.)
/etc/ld.so.conf.d/x86_64-linux-gnu.conf contains
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
I have checked that /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4 (and its .so.5 and .so symlinks, and the associated .a file too) exist.
Furthermore, the output of readelf --symbols /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4 | grep 'lzma_[sec]' shows that those three symbols exist (along with many others):
67: 000000000000c720 106 FUNC GLOBAL DEFAULT 13 lzma_stream_decoder##XZ_5.0
108: 00000000000039d0 701 FUNC GLOBAL DEFAULT 13 lzma_code##XZ_5.0
117: 0000000000003c90 65 FUNC GLOBAL DEFAULT 13 lzma_end##XZ_5.0
What am I doing wrong?
Clang puts the -llzma outside the --as-needed area of the linker command line:
[…] -L/usr/lib -llzma /tmp/--e00a22.o -lgcc --as-needed -lgcc_s […]
GCC puts it after --as-needed:
[…] --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 […]
-llzma /tmp/ccAZHRvb.o -lgcc --push-state
As a result, the linker notices that -llzma is not needed at that point in the command line and drops it. Linking is order-sensitive.
You can fix this by using - -llzma instead of -llzma -, as HolyBlackCat suggested.
I was trying to study the compilation/link process in detail using gcc.
So made a test .c file and compiled it using the verbose option of gcc.
gcc -v main.c
But in the verbose messages I cant find anywhere where it refers to libc. The only relevant (might be) thing I find is crtn.o and crtend.o
But when I do
readelf -d a.out
I can find the dependency on libc.so.6. So I am confused whether gcc doesn't output the message related to dynamically linking to libc or I am missing something.
The relevant message for the linker is as below:
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. /tmp/ccYoVOxt.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o
The library operand you are looking for is -lc. It's in there, use Ctrl+F to find it.
See also the ld documentation.
I am trying to build a JNI shared library which statically links to ffmpeg.
But at the linking stage, gcc fails with the following error:
/usr/bin/ld: ./lib_lin64/libswscale.a(swscale.o): relocation R_X86_64_PC32 against symbol `ff_M24A' can not be used when making a shared object; recompile with -fPIC
I am using the following commands to compile my jni library:
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -I ./include -fPIC -c *.c
gcc -shared -Wl,--no-undefined -o libnv_avc_dec.so *.o -Wl,-Bstatic -L./lib_lin64 -lavcodec -lavutil -lswresample -lswscale -Wl,-Bdynamic -lm
And I only use h264 decoding feature, so I am also building ffmpeg from source with the minimal required feature set. The ./configure command I use is:
./configure \
--enable-pic --prefix=ffmpeg-dist \
--disable-debug --enable-version3 --enable-gpl \
--disable-everything --enable-hwaccel=h264_vdpau --enable-hwaccel=h264_vaapi --enable-hwaccel=h264_qsv --enable-hwaccel=h264_mmal \
--enable-decoder=h264 --enable-decoder=h264_vdpau --enable-decoder=h264_crystalhd --enable-decoder=h264_mmal --enable-decoder=h264_qsv \
--disable-iconv --disable-securetransport --disable-xlib --disable-zlib --disable-lzma --disable-bzlib --disable-doc --disable-programs --disable-avformat --disable-avfilter --disable-postproc
So, as I understand, the linker tells me that ffmpeg should be compiled with -fPIC flag in order to make a shared library. But I believe that I've already done so by specifying the --enable-pic configure flag. And I am pretty much stuck here because I am not very familiar with autotools, nor with ffmpeg build process in particular.
If this is the issue of ffmpeg .a libs not being compiled with -fPIC flag, how can i force it? And if this is not the case, what am i doing wrong and how can i fix this error?
Environment details: Ubuntu 14.04.3 64-bit in Virtualbox, gcc 4.8.5 and 5.3 (both give the same results), ffmpeg v.2.8.5
If you're building a shared library but need to link with static ffmpeg libs add linker flags:
-Wl,-Bsymbolic
When using cmake:
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
I'm trying to generate code coverage files for a small C program compiled with clang on Debian Linux. Here's what I've done:
neuron#debian:~/temp$ ls
main.c test.c test.h
neuron#debian:~/temp$ clang *.c
neuron#debian:~/temp$ ./a.out
0
This is exactly as expected, I can compile and run things. Now trying to enable coverage.
neuron#debian:~/temp$ clang --coverage *.c
/usr/bin/ld: cannot find /usr/bin/../lib/libprofile_rt.a: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Trying to include the library for linking.
neuron#debian:~/temp$ clang --coverage -lprofile_rt *.c
/usr/bin/ld: cannot find -lprofile_rt
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Finding the library:
neuron#debian:~/temp$ find / -name \*profile_rt\* 2>/dev/null
/usr/lib/llvm-3.0/lib/libprofile_rt.so
/usr/lib/llvm-3.0/lib/libprofile_rt.a
neuron#debian:~/temp$ clang --coverage -lprofile_rt -L/usr/lib/llvm-3.0/lib *.c
/usr/bin/ld: cannot find /usr/bin/../lib/libprofile_rt.a: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here's more verbose output of the last command: http://pastie.org/8468331. What concerns me there:
the linker uses tons of gcc libraries to link with (though this may be a result of llvm not having it's own binunitls);
profiling library is being searched for at /usr/bin/../lib/libprofile_rt.a instead of the path I provided.
If we pass the arguments to the linker the output is the same:
neuron#debian:~/temp$ clang --coverage -Wl,-L/usr/lib/llvm-3.0/lib *.c -lprofile_rt
/usr/bin/ld: cannot find /usr/bin/../lib/libprofile_rt.a: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What do I do wrong?
Try changing the order of your link line from
clang --coverage -lprofile_rt -L/usr/lib/llvm-3.0/lib *.c
to
clang --coverage -L/usr/lib/llvm-3.0/lib *.c -lprofile_rt
Ok, doesn't seem like the linker is getting your -L for some reason. Maybe try
clang --coverage -Wl,L/usr/lib/llvm-3.0/lib *.c -lprofile_rt
The only way I've been able to resolve this issue is by creating a symbolic link to where LLVM/clang is looking for the library. I'm thinking this is a way for package maintainers to manage which feature-library is used by the host system.
ln -s /usr/lib/llvm-3.0/lib/libprofile_rt.a /usr/lib/libprofile_rt.a
Coverage, and other optional -f<***> profile features work as expected. I can verify this by adding the verbose -v switch.
Debian clang version 3.0-6.2 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: arm-unknown-linux-gnueabihf
Thread model: posix
"/usr/bin/clang" -cc1 -triple armv4t-unknown-linux-gnueabihf -S -disable-free -disable-llvm-verifier -main-file-name example.c -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-abi apcs-gnu -target-cpu arm1136jf-s -mfloat-abi hard -target-linker-version 2.22 -momit-leaf-frame-pointer -v -femit-coverage-notes -femit-coverage-data -resource-dir /usr/bin/../lib/clang/3.0 -fmodule-cache-path /var/tmp/clang-module-cache -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.0/include -internal-externc-isystem /usr/include/arm-linux-gnueabihf -internal-externc-isystem /usr/include -ferror-limit 19 -fmessage-length 130 -fno-signed-char -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/example-lLKOP1.s -x c example.c
clang -cc1 version 3.0 based upon llvm 3.0 hosted on arm-unknown-linux-gnueabihf
ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
ignoring duplicate directory "/usr/local/include"
ignoring duplicate directory "/usr/include/arm-linux-gnueabihf"
ignoring duplicate directory "/usr/include/arm-linux-gnueabihf"
ignoring duplicate directory "/usr/include/arm-linux-gnueabihf"
ignoring duplicate directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include/arm-linux-gnueabihf
/usr/include
/usr/include/clang/3.0/include/
/usr/lib/gcc/arm-linux-gnueabihf/4.6/include/
/usr/lib/gcc/arm-linux-gnueabihf/4.6/include-fixed/
End of search list.
"/usr/bin/as" -o /tmp/example-WbJHFT.o /tmp/example-lLKOP1.s
"/usr/bin/ld" -X --hash-style=both --build-id --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-linux-armhf.so.3 -o example.o /usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o /usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crti.o /usr/lib/gcc/arm-linux-gnueabihf/4.6/crtbegin.o -L/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf -L/lib/arm-linux-gnueabihf -L/usr/lib/arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.6 -L/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf -L/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../.. -L/lib/arm-linux-gnueabihf -L/lib -L/usr/lib/arm-linux-gnueabihf -L/usr/lib /tmp/example-WbJHFT.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \
/usr/lib/gcc/arm-linux-gnueabihf/4.6/crtend.o \
/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crtn.o \
/usr/bin/../lib/libprofile_rt.a