Linking between GCC and GFortran [duplicate] - c

I just have a system crash and reinstall Ubuntu 11.10, and my code produces this strange error.
I wrote a simple code sample to test where the problem is:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main (void) {
int i;
i = shm_open ("/tmp/shared", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); printf ("shm_open rc = %d\n", i);
shm_unlink ("/tmp/shared");
return (0);
}
and the compile command is
gcc -lrt test.c -o test
The error is:
/tmp/ccxVIUiP.o: In function `main':
test.c:(.text+0x21): undefined reference to `shm_open'
test.c:(.text+0x46): undefined reference to `shm_unlink'
collect2: ld returned 1 exit status
I have already added -lrt lib, why does it still not compile?

Libraries at the end:
gcc test.c -o test -lrt
From GCC Link Options:
-llibrary
-l library
Search the library named library when linking.
(The second alternative with the library as a separate argument
is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in the
order they are specified.
Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but
before bar.o. If bar.o refers to functions in `z', those functions
may not be loaded.

Change the compile line from
gcc -lrt test.c -o test
to
gcc test.c -o test -lrt

In Expert C programming Page 108:
<Handy Heuristic>
Where to Put Library Options:Always put the -l library options at the rightmost end of your compilation command line.
But it doesn't tell why, so i guess this is somewhat a rule?:)

For those of you using super-auto-magical CMAKE like me, try to add:
target_link_libraries(your_binary_name PRIVATE librt.so)
to your CMakeLists.txt
Alternatively, replace PRIVATE for PUBLIC as needed..
If you have well established paths to libraries (e.g. all needed libs in /usr/lib), you may be fine with just stating in CMakeLists.txt:
set(CMAKE_CXX_FLAGS "-lrt")

Related

gcc undefined reference to portaudio functions

I am trying to use portaudio in one of my projects. Unfortunately, I cannot compile my main.c file.
Error: "undefined reference to 'Pa_Initialize'" (Pa_Initialize is a function from the portaudio library)
My working directory includes the .a file from portaudio as well as the portaudio.h.
My current gcc command: gcc main.c libportaudio.a -lm -o main
Update: these are the includes in my main.c
#include <stdio.h>
#include <math.h>
#include "portaudio.h"
If you get an undefined reference error, you have probably already integrated the header file portaudio.h.
As Kurt E. Clothier already mentioned, you must also mention the libraries inside your gcc command. According to the portaudio website, the gcc command is
gcc main.c libportaudio.a -lrt -lm -lasound -ljack -pthread -o main
I was able to fix the issue by rebuilding the portaudio library.

GCC link against .so file without souce code

I am trying to compile compile a simple "hello world" program for an Axis A210 (cris architecture). I managed to get download GCC from the vendor, but it came with glibc, and the camera is running uClibc-0.9.27. I pulled the file /lib/libuClibc-0.9.27.so from the device.
I managed to compile this program that segfaults:
#include <unistd.h>
int main(int argc, char** argv)
{
*((unsigned int*)0) = 0xDEAD;
}
and this program that just hangs:
#include <unistd.h>
int main(int argc, char** argv)
{
int a = 0;
}
with cris-gcc -g -static -nostdlib -o compiled main.c.
Now I'd like to use the functions in libuClibc, but I can't seem to get the linking to work: I've tried
cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.
but that just gives:
./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
Is there a way to link to this .so file or to otherwise get some standard functions like exit working?
regarding:
cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.
The linker works with libraries in the order they are encountered. So they must be listed in the order needed.
The linker needs to know where the library is located before knowing which library to examine. Suggest:
cris-gcc -g -static -nostdlib -o compiled main.c -L. -luClibc-0.9.27
However, a *.so library is NOT a static library. It is a dynamic library, so the option: -static should be removed However, that requires that the dynamic library be available at 'run time' if the related *.a (a static library) is available then it should be used in the compile/link statement.
Note: the function: exit() has its' prototype exposed via the stdlib.h header file, not the unistd.h header file.
regarding:
#include <unistd.h>
int main(int argc, char** argv)
{
*((unsigned int*)0) = 0xDEAD;
}
the parameters: argc and argv are not used, so the compiler will output two warning statements about 'unused parameters'. Suggest using the function signature: int main( void )
this code is trying to write to address 0. However, the application does not 'own' address 0, (an usually, such an address will be 'marked' as 'readonly' so the application will exit with a 'seg fault event')
it is poor programming practice to include header files those contents are not used. Suggest removing the statement: #include <unistd.h>
this statement: int a = 0; will result in the compiler outputting a warning message about a variable that is 'set' but never 'used'
regarding:
cris-gcc -g -static -nostdlib -o compiled main.c -L. -luClibc-0.9.27
When compiling, should always enable the warnings, then fix those warnings. Suggest:
cris-gcc -Wall -Wextra -Wconversion -pedantic -std=c99 -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.
Apart of all the problems noticed by #user3629249 in his answer (all of them are to be followed), the message:
./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
means that the libuClibc-0.9.27.so binary has been stripped its symbols or you have not privileges to read the file, and so, the symbol table. The linker is unable to use that binary and it can only be loaded into memory. Anyway, you need a nonstripped shared object, and as suggested by #user3629249, don't use -static (by the reason stated in his answer), put the parameters in order (library dir before the library to be linked, also stated by him). Even you can link the shared by specifying it as:
cris-gcc -nostdlib -o compiled main.c libluClibc-0.9.27.so
and another thing: You need not only the standard C library to link an executable... you normally use a crt0.o at the beginning of your program with the C runtime and the start code for your program. You have not included that, and probably the compiler is getting it from another place.
One question: If you got the compiler, why do you intend to supply your own version of the standard library? isn't provided by the compiler? If you change the libc, then you must change also the crt0.o file. It defaults to some compiler provided, and you haven't received the message no definition for start.
Try to compile with just a main function, as you did, but don't specify shared libraries or directories... just the main code:
cris-gcc -o compiled main.c
and see what happens.... this will be very illustrative of what you lack in your system.

Shared library and rpath

I cannot make rpath work properly and make my binary to search for the library in the specified folder:
I have 3 very simple files:
main.c
#include <stdio.h>
#include <func.h>
int main() {
testing();
return 1;
}
func.h
void testing();
func.c
#include "func.h"
void testing(){
printf(testing\n");
}
Then I proceed to create a shared library as it follows:
gcc -c -fpic func.c -o ../release/func.o
gcc -shared -o ../release/lib/lib_func.so ../release/func.o
And then compile the program:
gcc main.c ../release/lib/lib_time_mgmt.so -Wl,-rpath=/home/root/ -o ../release/main
I receive the next warning:
main.c:7:2: warning: implicit declaration of function ‘testing’ [-Wimplicit-function-declaration]
testing();
But besides it, the program works fine.
However, my problem is that if now I want to move the library to /home/root (as specified in rpath) it does not work and the library is still searched only in the path specified when I compiled the main.c file which is ../release/lib/lib_time_mgmt.so
What am I doing wrong?
EDIT: After accepting the answer, I leave here the exact line as I used it and made it work for whoever might find it useful:
gcc main.c -L/home/root -Wl,-rpath,'/home/root/' -l:libtime_mgmt -o ${OUT_FILE}
Note: the rpath was used with the path betwen simple '. Not sure if that was the reason why it was not working before, but it worked this way now.
rpath is not used at compile time, but rather at link/runtime... thus you probably need to use both of these:
-L /home/root - to link correctly at build time
-Wl,-rpath=/home/root - to link correctly at run-time
You should use the -l ${lib} flag to link with libraries, don't specify their path as an input.
In addition to this, convention states that the libraries are named libNAME.so - e.g:
-l func will try to link with libfunc.so
-l time_mgmt will try to link with libtime_mgmt.so
Once you've addressed the above points, try the following:
gcc main.c -L/home/root -Wl,-rpath=/home/root -lfunc -ltime_mgmt -o ${OUT_FILE}
As a final point, I'd advise that you try not to use rpath, and instead focus on installing libraries in the correct places.
Unrelated to your question, but worth noting. Your use of #include <...> vs #include "..." is questionable. See: What is the difference between #include <filename> and #include "filename"?

erl_interface linker error

I need to use erl_interface in my C-program. There is Erlang R15B01 on Debian Wheezy.
I just do the following (for example).
// main.c
#include <ei.h>
#include <erl_interface.h>
int main() {
erl_init(NULL,0);
return 0;
}
Then i say:
cc -I/usr/lib/erlang/lib/erl_interface-3.7.7/include -L/usr/lib/erlang/lib/erl_interface-3.7.7/ -lei -lerl_interface -o prog main.c
Directory specified as -L contains libei.a and liberl_interface.a but linker abusing that reference to erl_init is undefined: undefined reference to erl_init
What may be wrong? Sorry for really stupid question.
Newest versions of the GNU toolchain require that the object files and libraries be specified in the same order their symbols depend on each other. So you should generally put the library flags to the end of the invocation, like this:
gcc -o prog main.c -L<libdir> -I<includedir> -lerl_interface -lei

undefined reference 'shm_open', already add -lrt flag here

I just have a system crash and reinstall Ubuntu 11.10, and my code produces this strange error.
I wrote a simple code sample to test where the problem is:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main (void) {
int i;
i = shm_open ("/tmp/shared", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); printf ("shm_open rc = %d\n", i);
shm_unlink ("/tmp/shared");
return (0);
}
and the compile command is
gcc -lrt test.c -o test
The error is:
/tmp/ccxVIUiP.o: In function `main':
test.c:(.text+0x21): undefined reference to `shm_open'
test.c:(.text+0x46): undefined reference to `shm_unlink'
collect2: ld returned 1 exit status
I have already added -lrt lib, why does it still not compile?
Libraries at the end:
gcc test.c -o test -lrt
From GCC Link Options:
-llibrary
-l library
Search the library named library when linking.
(The second alternative with the library as a separate argument
is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in the
order they are specified.
Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but
before bar.o. If bar.o refers to functions in `z', those functions
may not be loaded.
Change the compile line from
gcc -lrt test.c -o test
to
gcc test.c -o test -lrt
In Expert C programming Page 108:
<Handy Heuristic>
Where to Put Library Options:Always put the -l library options at the rightmost end of your compilation command line.
But it doesn't tell why, so i guess this is somewhat a rule?:)
For those of you using super-auto-magical CMAKE like me, try to add:
target_link_libraries(your_binary_name PRIVATE librt.so)
to your CMakeLists.txt
Alternatively, replace PRIVATE for PUBLIC as needed..
If you have well established paths to libraries (e.g. all needed libs in /usr/lib), you may be fine with just stating in CMakeLists.txt:
set(CMAKE_CXX_FLAGS "-lrt")

Resources