C++ FFTW3 linking error [duplicate] - c++

This question already has answers here:
Linker errors when compiling against glib...?
(2 answers)
Closed 10 years ago.
I am getting very strange error whenever I am trying to compile a C++ program with FFTW3 implementation.
I am compiling as follows
g++ -O3 -lm -lfftw3 myFile.cpp -o myFileFFTW
I also included my headers file as follows
#include <math.h> #include "fftw3.h"
The error is as follows
(.text+0x63): undefined reference to `fftw_malloc'
Any suggestions?
Edit:
the suggestion by hmjd worked for me.
Linker errors when compiling against glib...?
I guess one should not work for straight 3 days otherwise mind does not work!!
Special thanks hmjd!! you saved my day and I could finish my project on time !!

I guess problem is -lfftw3 not present on your system and you are also not specifying libs correctly.
Libraries at the end of the compiler command:
gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include re.c -o re -lglib-2.0
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.
snnippet from Linker errors when compiling against glib...?

Related

Linking against a c/c++ library

I have some basic questions regarding linking against a C/C++ library. I am trying to understand the difference in using the two different usages -L/usr/local/lib -lm usage and /usr/local/lib/libm.a usage. E.g., when I compile and link an example from the [SUNDIALS] library, both of the following work
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe -I/usr/local/include -L/usr/local/lib/ -lsundials_cvode -lsundials_nvecserial -lm
OR
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe /usr/local/lib/libsundials_cvode.a /usr/local/lib/libsundials_nvecserial.a
However, to compile and link an example from the library [libsbml], the following works
g++ -Wall readSBML.cpp -o readSBML.exe -I/usr/local/include -L/usr/local/lib -lsbml
but the this does not
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.a
If required, I can post the complete error message I get, but the last line of the message is as follows
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My questions are as follows:
In the second style of linking (of the first example), there is no information regarding where to find the include files (header files), how does the compiler know the information supplied in -I/usr/local/include which is provided in the first style of the first example?
In the second style of first example there is no /usr/local/lib/libm.a (it actually gives an error message that libm.a cannot be found if I try to include it), then why -lm is required in the first style?
How do I compile the second example in the second style (i.e., using /usr/local/lib/libsbml.a)? I do see that there are files - libsbml.a and libsbml-static.a in the /usr/local/lib folder, but none of them work.
If it helps, I am on an OS X machine.
I would be very thankful if any one could help in this regard.
Just an update - I tried
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.5.dylib
and that compiled and linked just fine.
Thanks
SN
In general
The -L option is meant to find where the libraries themselves are. Each library is a collection of one or more object code (machine language) files. There is no need to find the include files.
The -I option has nothing to with linker, it helps the compiler resolve the header files used in your driver programme( eg Roberts_dns.c). This happens during the pre-processing stage.
In the second style of linking (of the first example), there is no
information regarding where to find the include files (header files),..
If the compilation worked as you expected,it may be because /usr/local/include is in the default include path for gcc. To check the default include path for gcc do gcc -xc -E -v -.
In the second style of first example there is no
/usr/local/lib/libm.a(it actually gives an error message that libm.a
cannot be found if I try to include it), then why -lm is required in
the first style?
In Linux, some libraries like libc.a are directly linked to your execultable by default while libm.a is not. In Mac (your environment), though, libm is directly link to the executable by default. So you don't have to explicitly link it. It is less likely that libm.a is located in /usr/local/lib/. So you got an error. But why link it in the first place?

lstd++ & extern - calling C++ from C

I have wrapped my C++ header file in an extern "C" block to allow calling C++ functions from C. I have included the proper header files in the proper places. It works if I do something like the following:
g++ -c cpp_src.cc
gcc -c c_src.c
gcc -o c_exe c_src.o cpp_src.o -lstdc++
But if I remove the -lstdc++ from the last line, I get a bunch of errors. Because of reasons beyond my control, I cannot add the -lstdc++ flag. Is there a way to get the above to work without -lstdc++? What exactly is lstdc++, as in how does the gcc use it while linking with g++ compiled code?
Also, cpp_src.cc uses STL, if that makes a difference.
If you really need to have an object file that you can link with gcc without using -lstdc++, you can do an incremental link of your C++ object file with -lstdc++ and then use the result of that on your gcc link line. Something like:
ld -i -static cpp_src.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -lstdc++ -o cpp_withstdlib.o
This will link your C++ object file with the standard C++ library and produce a new object file (cpp_withstdlib.o) that contains all the standard C++ library stuff you need, so can be linked on the gcc command line without needing -lstdc++
The tricky part is the -L option -- you need to figure out where g++ has stashed its standard library, as it generally doesn't put it in the standard /usr/lib location. The above is for an Ubuntu 14.04 machine. On most Linux machines, you can find it with locate libstdc++.a
You're generally just better off using g++ to link C++ code, as it knows all the right paths and won't make little mistakes that result in a binary that superficially appears to work, but is actually incorrect.
Using Josh's suggestion, you can do:
ld -i -static cpp_src.o `g++ -print-file-name=libstdc++.a` -o cpp_withstdlib.o
which is a bit cleaner, and could readily be done in a Makefile.
-lstdc++ causes the linker to link to libstdc++, which is gcc's implementation of the C++ standard library. If your code uses any symbols from the standard library (it uses the standard library, and not all code is inlined from headers), it must link libstdc++ (or whichever standard library implementation you use).
You can avoid the standard library, or you can link against the system standard library, or you can statically link a copy of the standard library into your program.

Undefined reference to PQfinish even though libraries etc. are included [duplicate]

This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 8 years ago.
I'm trying to compile a C++ application using libpq.
On my Debian it compiles fine with the following command:
g++ -I /usr/include/postgresql/ -L /usr/lib/postgresql/9.3/lib/ -lpq -o test test.cpp
On my Ubuntu I get the following error:
undefined reference to 'PQfinish'
I've included link to postgresql headers and libraries and used the -lpq. What am I missing?
Move -lpq to the end of the command line.
Linking is done in the order specified, and objects are only taken from libraries if they are needed to resolve symbols at that point. So each library has to come after any other object that needs it.

Compiling program using gfortran and the HDF-EOS2 library

I have the problem of linking the HDF-EOS library to a Fortran90 program. I have compiled the library from source to a directory specified in $prefix. My simple compile command is:
gfortran -I$prefix/include -L$prefix/lib -Wl,-rpath -Wl,$prefix/lib -lhdfeos -lGctp -lmfhdf -ldf -lz -lsz -ljpeg tst.f90
When compiling, I get the following error:
undefined reference to `gdopen_'
In the program, which I am not supposed to change, the HDF-EOS library is used via the external keyword, e.g.
integer(kind=4), external :: gdopen
In the library, nm $prefix/lib/libhdfeos.a | grep gdopen gives me:
00000000000120c0 T gdopen
When compiling with -fno-underscoring, I get just a different error:
gfortran -fno-underscoring -I$prefix/include -L$prefix/lib -Wl,-rpath -Wl,$prefix/lib -lhdfeos -lGctp -lmfhdf -ldf -lz -lsz -ljpeg tst.f90
the error is then:
undefined reference to `gdopen'
Also, gfortran finds the libraries, otherwise it would complain. Is the error related to the underscore? What else can I try? I work on Fedora and gfortran version 4.7.2.
Yes, very likely to be caused by the underscore.
Try compiling with -fno-underscoring (https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html), but fixing it by a proper bind(C) interface would be better.
This tutorial (Did you read it before going here? Very easy to find even for a complete novice in the library, like me.) also states you should use -fno-underscoring.
Continue by implementing the rest what the tutorial recommends, including compiling with FC=$(HDF4_DIR)/bin/h4fc.

In C++, why don't I have to include anything to use the sqrt() function?

I am just learning C++. Compiling with g++ version 3.2.3, "g++ hworld.cpp":
double sqrt(double);
int main(){
double x = sqrt(1515.15);
return 0;
}
That compiles fine, but if we were to replace sqrt with "sqrtfoo" the compiler would say sqrtfoo cannot be used as a function. I thought I would have to include cmath, but I guess not? Can someone please explain what my program has access to before any includes? For comparison, gcc does not allow me to do this, saying "undefined reference to 'sqrt'." Thank you.
You don't need to include cmath because your code has a prototype for sqrt in it already, the very first line.
As the existing answers explain, the double sort(double) provides a prototype to let the compiler know that the function exists.
But you also mentioned that this doesn't work under GCC. When you build a C or C++ program, the source code is compiled into object format. The object files are then linked together to form an executable.
To see this in action, try
gcc -c hello.c
This tells GCC to compile (-c) the source file hello.c. Assuming that hello.c exists and has no errors, you'll find hello.o in the current directory. Now try
gcc -o hello hello.o
This tells GCC to link hello.o with the appropriate system libraries, and to generate an output file called "hello". If hello.c uses math functions, you'll also need to link in the math library:
gcc -o hello hello.o -lm
"-l" is used to tell gcc to include extra libraries (beyond the default "libc" C library). "m" refers to "libm", which is the math library containing sqrt. If your program uses only one source file it's common to ask implicitly GCC to compile and link in a single command:
gcc -o hello hello.c -lm
Now to your question. GCC won't compile the above code because you haven't asked it to link in the math library. But g++ is okay with it. There's a very similar question already on Stack Overflow. According to its accepted answer,
the C++ runtime libstdc++ requres libm, so if you compile a C++
program with GCC (g++), you will automatically get libm linked in.
Since "libstdc++" is the C++ language runtime library, it's included by g++ by default. And as it depends on libm, the linker automatically loads libm while producing the final binary program.
Header files hold only declarations (signatures), and you've included one in the first line (prototype: double sqrt(double)).
The compiler compiles it just fine, because you've stated that somewhere this function is defined. The step that occurs after compiling is responsible for actually looking for that function definition. It's called linking, and during that phase linker lookups those definitions. In case of sqrtfoo it cannot find anything, whereas in case of sqrt it finds it in some standard library (I do not know the details here).