Linking issue on Debian8 - c

I'm trying to recompile my software for debian 8, but i have run into this strange issue of libgssappi refusing to link with anything.
>~/torque_github$ gcc test.c -lgssapi
/usr/bin/ld: cannot find -lgssapi
collect2: error: ld returned 1 exit status
The library is present in the system, as seen here:
>~/torque_github$ /sbin/ldconfig -p | grep gssapi
libgssapi_krb5.so.2 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2
libgssapi.so.3 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libgssapi.so.3

On my Debian/Jessie/x86-64 system, /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so is provided (according to dpkg -S) by the libkrb5-dev package and /usr/lib/x86_64-linux-gnu/libgssapi.so.3 is provided by libgssapi3-heimdal package (and I don't have any libgssapi*dev package).
You probably should install both of them (with sudo aptitude install libkrb5-dev libgssapi3-heimdal command), and use pkg-config with krb5-gssapi to get compilation and linking flags.
gcc -Wall -g $(pkg-config --cflags krb5-gssapi) \
test.c \
$(pkg-config --libs krb5-gssapi) \
-o myprog
(you could have to change your test.c source code if some API has changed; perhaps you'll need to #include <krb5/krb5.h>)
You might even use gcc -v instead of gcc above.
Remember that order of arguments to gcc matters a big lot. Your initial question had a different order (and that is enough to make gcc fail)!

Related

Compile hiredis in C on Mac OS X

I'm trying to compile a client using hiredis in C on Mac OS X.
I've installed hiredis with:
brew install hiredis
But still get the error:
fatal error: 'hiredis.h' file not found
My hiredis.h is however in:
/usr/local/include/hiredis/hiredis.c
How do I tell the compiler this?
I'm compiling with:
gcc test.c -o test
In your question you said hiredis.h is in /usr/local/include/hiredis/hiredis.c, which doesn't really make any sense.
Assuming you meant that your hiredis.h is in /usr/local/include/hiredis. You can do like:
gcc test.c -I/usr/local/include/hiredis -o test
Read about -I in this SO post.
UPDATE:
As mentioned by #EricPostpischil in comments, its a better idea to just include like:
#include < hiredis/hiredis.h>
I am still not sure if /usr/local/include is in default include path. If it is, well no need to do anything, just compile like:
gcc test.c -o test
and if it isn't,
gcc test.c -I/usr/local/include -o test
If you have installed hiredis with homebrew, you can see what's in the package like this:
brew ls --verbose hiredis
/usr/local/Cellar/hiredis/0.14.0/INSTALL_RECEIPT.json
/usr/local/Cellar/hiredis/0.14.0/CHANGELOG.md
/usr/local/Cellar/hiredis/0.14.0/.brew/hiredis.rb
...
...
/usr/local/Cellar/hiredis/0.14.0/lib/libhiredis.dylib
/usr/local/Cellar/hiredis/0.14.0/lib/pkgconfig/hiredis.pc <--- PKG-CONFIG
/usr/local/Cellar/hiredis/0.14.0/lib/libhiredis.a
/usr/local/Cellar/hiredis/0.14.0/lib/libhiredis.0.14.dylib
...
...
And, as you can see, it gives you a pkg-config file with all the settings in it that you need. So, you might as well install pkg-config and do it properly!
brew install pkg-config
Now, if you want to know the C compiler flags for hiredis, you do:
pkg-config --cflags hiredis
-D_FILE_OFFSET_BITS=64 -I/usr/local/Cellar/hiredis/0.14.0/include/hiredis
And if you want to know the linker settings, you do:
pkg-config --libs hiredis
-L/usr/local/Cellar/hiredis/0.14.0/lib -lhiredis
And so, your compile-link command becomes very simple and updates itself when you update the packages:
gcc-9 $(pkg-config --cflags --libs hiredis) -o program program.c

(Newbie) ld exit return 1, and libgcrypt

After much research, trying to find out how to link libraries to gcc, going to /usr/bin and /usr/lib confirming the stuff are there. When I try to compile my keygen file, this is the error it blurts out.
$ gcc keygen.c -W -Wall /usr/bin/libgcrypt-config
/usr/bin/libgcrypt-config: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
I've been told by numerous sources that I should compile this way to check if libgcrypt installed correctly.
$ gcc -o foo foo.c 'libgcrypt-config --cflags --libs'
But everytime I try to do that this is what it blurts out:
gcc: error: libgcrypt-config --cflags --libs: No such file or directory
I've confirmed that libgcrypt20 and libgcrypt20-dev are installed using dpkg --get-selections>installed. But I am just so utterly confused as to what may be wrong.
Any form of help would be much appreciated.
Try:
$ gcc -o foo foo.c `libgcrypt-config --cflags --libs`
` instead of '

Clang link-time optimization doesn't work properly on Fedora 18

I'm a newcomer to clang, so it's likely I'm doing something silly. But I've spent several hours looking for solutions, including searching here, where I haven't found questions addressing -flto with distro-provided packages. The detail of this description are specific to Fedora 18, but I'm having similar problems on Ubuntu 13.04, so the problem isn't specific to Fedora. It's either me or clang.
Problem: I'm trying to compile a simple hello-world program using clang++ -flto to get the benefits of link-time-optimization. Without -flto it works fine. With -flto it fails to link. Invoking as clang -flto -o hello hello.o -v to see the full linker command line, I get:
$ clang++ -flto -o hello hello.o -v
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
"/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../.. -L/lib -L/usr/lib -plugin /usr/bin/../lib/LLVMgold.so hello.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error loading plugin
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error in plugin cleanup (ignored)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
There seem to be two problems:
clang++ invokes the linker as /usr/bin/ld, and that's not the gold linker. Fedora18 installs gold as /usr/bin/ld.gold. I've tried creating a symlink from /usr/local/bin/ld to /usr/bin/ld.gold, verified that which ld says /usr/local/bin/ld, but clang++ doesn't use that. It seems to be hardwired to /usr/bin/ld.
clang++ invoked the linker with -plugin /usr/bin/../lib/LLVMgold.so. That's wrong, as the Fedora distribution of clang places it at /usr/lib64/llvm/LLVMgold.so.
I have tried manually invoking that linker line above with the following tweaks:
Replace -plugin /usr/bin/../lib/LLVMgold.so with -plugin /usr/lib64/llvm/LLVMgold.so. This yields the error message hello.o: file not recognized: File format not recognized. So the non-gold linker seems to know about plugins but wont take the .o's which contain LLVM bitcode.
Replace /usr/bin/ld with /usr/bin/ld.gold. This works, generates an executable that runs as expected.
Both of the above with --plugin instead of -plugin. This change makes no difference.
So what's the best way for somebody who prefers to stick to the system-provided packages to use clang -flto? I'm hoping there is a config file, or undocumented options or environment variables that will let me override these. Or better, that I'm missing a package and a "yum install ..." will fix it.
I would prefer not to invoke the linker directly, as then my makefiles need to know system objects and libraries that they should be ignorant of (e.g. crt1.o, crtbegin.o, crtend.o). I could also build clang myself, but I'm not seeing anything in its configure script that lets me configure the path of the linker and plugin.
I'm running Fedora 18. The only non-distro packages on the computer are google chrome and VMware Tools (it's a guest inside VMWare Fusion). Versions of relevant Fedora packages (the whole computer is "yum updated" as of today, 29-Apr-2013):
$ yum list --noplugins installed binutils* clang* llvm* gcc*
Installed Packages
binutils.x86_64 2.23.51.0.1-6.fc18 #updates
binutils-devel.x86_64 2.23.51.0.1-6.fc18 #updates
clang.x86_64 3.2-2.fc18 #updates
clang-devel.x86_64 3.2-2.fc18 #updates
clang-doc.noarch 3.2-2.fc18 #updates
gcc.x86_64 4.7.2-8.fc18 #fedora
gcc-c++.x86_64 4.7.2-8.fc18 #fedora
llvm.x86_64 3.2-2.fc18 #updates
llvm-libs.x86_64 3.2-2.fc18 #updates
There is an utility alternatives in Fedora - it allows to subtitute one linker with another on system level:
$ sudo alternatives --display ld
ld - status is auto.
link currently points to /usr/bin/ld.bfd
/usr/bin/ld.bfd - priority 50
/usr/bin/ld.gold - priority 30
Current `best' version is /usr/bin/ld.bfd.
$ sudo alternatives --set ld /usr/bin/ld.gold
About LLVMgold.so location you can only report a bug in Fedora Bugzilla, since the path is built-in in clang sources:
lib/Driver/Tools.cpp: std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
Fedora guys may apply a patch to the Clang's source package, or create a symlink to LLVMgold.so.
There is no changes even in Fedora 20 yet.

undefined reference to `ftdi_init'

I have used libftdi in the past and compiled using the command:
gcc -lftdi -o i2csend i2csend.c
Everything went fine.
Today, on Ubuntu 12.10 I get many errors such as undefined reference toftdi_init'`
I understand that libftdi was renamed to libftdi1 so I tried the same command with -lftdi1 and got error:
/usr/bin/ld: cannot find -lftdi1
collect2: error: ld returned 1 exit status
Can anyone explain why?
You should typically not directly specify external package's library names.
It's better to use the packaging system's help program, i.e. pkg-config, like so:
$ gcc -o i2csend i2csend.c $(pkg-config --cflags --libs libftdi1)
Note that this assumes that the package name is libftdi1 in pkg-config's database; I'm not sure how to verify this portably. You can run pkg-config --list-all | grep ftdi to find out.
It's generally a good idea to keep the libraries part (-l option) at the end of the command line, which the above is doing. It's somewhat cleaner to factor out the CFLAGS part, but that requires repeating the command:
$ gcc $(pkg-config --cflags libftdi1) -o i2csend i2csend.c $(pkg-config --libs libftdi1)
Here, I've used double spaces to separate the logical parts of the command line for improved clarity.

C & Mac: trouble finding a header using pkg-config

I'm trying to use in one of my projects. I'm working on a Mac, have gotten MacPorts with pkg-config and glib-2.0 packages.
When I try to make a file containing an include to above path, I get the following error (line above it is for clarity that it does actually give me the right dirs):
$ pkg-config --cflags --libs glib-2.0
-I/opt/local/lib/glib-2.0/include -I/opt/local/include -L/opt/local/lib -lglib-2.0 -lintl
$ make
gcc hash-glib.c -c `pkg-config --cflags --libs glib-2.0` -std=c99 -Wall -Wextra -pedantic -O2
hash-glib.c:2:23: error: glib/glib.h: No such file or directory
$
Presumably, you've run:
ls -l /opt/local/lib/glib-2.0/include/glib/glib.h \
/opt/local/include/glib/glib.h
to demonstrate that the header #include "glib/glib.h" actually is present in one of the locations where you've been told by pkg-config that it could be found. If it isn't there, then pkg-config is misleading you, and the compiler is telling you that you've been hoodwinked.
Since the compiler will have done its utmost to find the header, it is a reasonable bet that the file isn't in either of those locations. You are then left with detective work: where is the glib.h header installed?
find /opt/local -type f -name glib.h
If that tells you where it is, you can then work out what pkg-config should be saying. If that fails to find it, widen the search area. If you still can't find it, maybe it isn't installed yet? Or you only installed the glib runtime, not the development package.

Resources