Cannot link library when compiling with gcc - c

My directory structure is:
── bin
│   ├── mylib-osx.so.1.72
│   ├── mylib.so.1.72
├── my.c
I am trying to compile my.c and link mylib-osx.so.1.72 (I'm on a macOS), but to no avail:
ld: library not found for -l:PhotoDNAx64.so.1.72
I tried:
gcc -o my -lmylib-osx my.c
gcc -o my -lmylib-osx.so.1.72 my.c
gcc -o my -lmylib my.c
gcc -o my -L./bin -lmylib-osx my.c
gcc -o my -L./bin -l:"mylib-osx.so.1.72" my.c
What am I doing wrong and why cannot the library be found?

What am I doing wrong and why cannot the library be found?
Read about Invoking GCC. You was wrong in not reading that (or any other documentation of gcc).
Order of program arguments to gcc matters a lot (and in practice several arguments are very useful, e.g. both -Wall and -g at least, and probably -v sometimes). You want something like
gcc -v -Wall -g my.c -lmylib-osx -o my
(also try variants of that), since gcc is running some ld or equivalent linker command, and if you want to pass some -Llib-directory use something like
gcc -v -Wall -g my.c -L./bin -lmylib-osx -o my
and you also need to read the documentation of MacOSX linker (probably named ld). You could also read Levine's Linkers and loaders book.
If you are not happy with gcc (but please use a recent version, so GCC 8 in 2019, not the crappy software sold by Apple named gcc) consider using Clang (a recent version too, e.g. Clang 8 in 2019). It has the same limitation regarding order of program arguments than gcc does (since order of program arguments even mattered for Unix or POSIX cc).
In general, read the documentation of a command before asking questions here about that command. A minima, man gcc on your Apple (or Linux) computer.
PS. The last time I have used some MacOSX was in 2004. My biased recommendation is to install and use Linux (which I use since 1993; I tried MacOSX around 2004 during less than a year, and have been disappointed both by the operating system, including its display server and GUI desktop environment, and by the Apple hardware).

Related

Emscripten compilation error: "'openssl/sha.h' file not found"

I have a file called "speed.c" which I wish to use for a web program
This works:
gcc speed.c -lcrypto -lssl
But this doesn't:
emcc speed.c -v -lcrypto -lssl -s EXPORTED_FUNCTIONS=_speed,_main -o speed.wasm
The function within speed.c is called "speed".
On the website for Emscripten, it says that the compiler is just like any other so this one confuses me.
Any help? Thanks!
Emscripten can't use you system's libraries. This is because they are binaries compiled for your own machine (probably 64-bit linux), while emcc compiles to WebAssembly/JavaScript. You can generally see what architecture a binary is targeting with file:
$ file `realpath /usr/lib/libssl.so`
Thus, you will need to first compile OpenSSL with emcc. I haven't done this myself, but I believe it's possible. You could check out this github issue.
Once you've done that you should have two files name libssl.a and libcrypto.a. Then you can compile your own project like this:
$ SSL=/path/to/openssl
$ emcc speed.c $SSL/libssl.a $SSL/libcrypto.a -I $SSL/include/ # etc.
Take a look at the project building page if you haven't yet.

Dynamic linking libgit2 .so in gcc

I'm running a Debian (Buster) container and my goal is to compile a small program I wrote which relies on libgit2. First, I was installing libgit2 via the libgit2-dev package and my Makefile had the following:
gcc -O2 -fpic -shared -I /usr/local/include -lgit2 -o output.so my_app.c
However, I'd rather have a "cleaner" environment and install libgit2 via the libgit-27 which, AFAIK, only installs the shared object binary instead of also including the development files like libgit2-dev does.
Using find I can find where the .so file is installed into:
$ find / -name "*git2*" -print 2>/dev/null
/usr/lib/x86_64-linux-gnu/libgit2.so.0.27.7
/usr/lib/x86_64-linux-gnu/libgit2.so.27
/usr/share/doc/libgit2-27
/var/lib/dpkg/info/libgit2-27:amd64.list
/var/lib/dpkg/info/libgit2-27:amd64.symbols
/var/lib/dpkg/info/libgit2-27:amd64.md5sums
/var/lib/dpkg/info/libgit2-27:amd64.shlibs
/var/lib/dpkg/info/libgit2-27:amd64.triggers
and I've been trying several combinations of linking this .so with gcc like:
gcc -O2 -fpic -shared -L /usr/lib/x86_64-linux-gnu/ -libgit2.so.27 -o output.so my_app.c
but so far I always get the following error:
my_app.c:1:10: fatal error: git2.h: No such file or directory
#include <git2.h>
^~~~~~~~
compilation terminated.
I understand this is a glaring lack of knowledge on how C compilation works. My two questions are:
Is it possible to compile my program by just relying on the libgit2-27 Debian Buster package instead of libgit2-dev? If not, why?
If yes, an example and explanation would be appreciated!

gcc can't find -lX11

I've used linuxbrew to install gcc 5.3 on a machine on which I don't have sudo access. I now want to link with X11:
> gcc test.c -lX11
ld: cannot find -lX11
I've checked that libX11.so exists in /usr/lib64/ which is on the compiler's LIBRARY_PATH. If I use the system's gcc it works fine, but I need a newer version to compile my actual program.
use -L flag, like this -L/usr/lib64, or you can specify full path to library like this gcc test.c /usr/lib64/libX11.so
According to this comment by a linuxbrew developer,
linuxbrewed gcc removes /usr/lib64 from the library path because mixing system libraries with brewed libraries creates havoc.
The solution is to brew install linuxbrew/xorg/xorg.

How do you compile a C program?

This might be the most newbie question ever, but how do you compile a C program?
I’ve downloaded the source of a C program (ffmpeg, to be precise). How do I compile it?
For most Unix-style C programs, the incantation is:
./configure
make
sudo make install
This should already be documented in the INSTALL file, which additionally may contain further useful information.
For a single file just cc file.c (or gcc or whatever you C compiler is called)
For a complex project like ffmpeg, then either make, cmake, configure some other. Check their documentation
It depends on what OS and compilers you have, but typically the sequence is:
$ ./configure
$ make
$ sudo make install
to compile simple math program, it's not enough to <include math.h>. See
gcc file.c -lmath -o program_bin
for a single .c file using ffmpeg libraries, it can be made this way:
gcc -Wall -g live_segmenter.c -o live_segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad -lpthread -I/home/devicer/ffmpeg/include -L/home/devicer/ffmpeg/lib
notice -L and -I options. In serious projects they are usually set by pkg-config.
for the ffmpeg itself..
- install lame, few other required libraries, then do as Chris said.
Btw, sometimes it requires gmake, not make.
Also, have a look on
./configure --prefix /home/devicer/ffmpeg
This is what was mentioned (used for) in segmenter compilation above.

sscanf + c99 not working on some platforms?

When I compile a simple Hello World! program that uses the sscanf function on my local Debian lenny x64, it works. But when I upload the same program to the server running CentOS x86, it will not work. If I do not use sscanf, then the program works on both computers.
gcc -std=c99 -O2 -pipe -m32
If I compile it with sscanf but without -std=c99, then it works on both computers.
gcc -O2 -pipe -m32
What is the problem with sscanf and c99 on CentOS x86 ? I thought that compiling with the -m32 flag would work on all Linuxes ? (I have limited access to the CentOS server, so I do not have access to error messages.)
Probably the CentOS box is using an old version of glibc. Since the nonstandard GNU extensions to their scanf implementation ended up making glibc conflict with c99, they added a nasty hack of redirecting *scanf to __isoc99_*scanf when -std=c99 is in use; if your copy of glibc is missing the __isoc99_sscanf symbol, the program will then fail to run.
Static linking, or linking to a different libc without ugly backwardsness-compatibility hacks, would solve the problem.
Are you uploading the binary or the source and then recompiling? If you are uploading the binary, you are probably running into a library compatibility issue between Debian and CentOS.
If that is the case, upload the source only and recompile on CentOS.
If you do not have permission to compile # CentOS, then try compiling a static binary. You can use dietlibc which makes smaller binaries than glibc or try EGLIBC which is the default C library that Debian will use starting Debian "squeeze".
I came up with the similar problem, it works # Ubuntu 64-bit, but the compile fails # CenseOS 64-bit (REHL5 desktop):
the error message is:
undefined reference to `__isoc99_sscanf#GLIBC_2.7'
when i copied the executable file compiled #Ubuntu to REHL5, and run it another error appeared:
elf file os abi invalid
it is compiled without flag -std=c99, i'm a newbie at C, and looking forword some workarounds, ex. add some flag.
Makefile:
CC=gcc
CCFLAGS= -Wall -O2 -DLINUX -I../include
demos:linuxdemo.c
$(CC) $(CCFLAGS) -o demoA linuxdemo.c -L../lib -lsense4 -lusb
$(CC) $(CCFLAGS) -o demoSO linuxdemo.c -lusb -lsense4
clean:
rm -f demoA
rm -f demoSO
You need to update your glibc to 2.7
download the rpm package from here:
http://archive.fedoraproject.org/pub/archive/fedora/linux/releases/8/Everything/x86_64/os/Packages/
needs:
libc-common-2.7-2.x86_64.rpm
glibc-headers-2.7-2.x86_64.rpm
glibc-devel-2.7-2.x86_64.rpm
glibc-2.7-2.x86_64.rpm
command:
rpm -Uvh --aid --nodeps glibc-common-2.7-2.x86_64.rpm
rpm -Uvh --aid --nodeps glibc-headers-2.7-2.x86_64.rpm
rpm -Uvh --aid --nodeps glibc-devel-2.7-2.x86_64.rpm
rpm -Uvh --aid --nodeps glibc-2.7-2.x86_64.rpm

Resources