I'm currently learning OpenCL. Now, when I want to compile my program, I get an error with this command:
g++ -Wall -l OpenCL main.cpp -o main
The errors are mostly undefined references, because the library is not linked, I think (nevertheless I will post the error code at the end).
But with this command everything works fine:
g++ -Wall main.cpp -o main -l OpenCL
So my question is, what do I have to do, to use the -l Flag in front of the command?
(The Background is: I want to use Netbeans to compile my programm and when i add the flag under -> properties -> build -> C++ Compiler -> additional options, it will put in in the Position, shown in the first command)
Thanks in advance for your help
Here's the error code:
/tmp/ccmKP4oI.o: In function `cl::detail::ReferenceHandler<_cl_context*>::release(_cl_context*)':
main.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP11_cl_contextE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP11_cl_contextE7releaseES3_]+0x14): undefined reference to `clReleaseContext'
/tmp/ccmKP4oI.o: In function `cl::detail::ReferenceHandler<_cl_command_queue*>::release(_cl_command_queue*)':
main.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP17_cl_command_queueE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP17_cl_command_queueE7releaseES3_]+0x14): undefined reference to `clReleaseCommandQueue'
/tmp/ccmKP4oI.o: In function `cl::Platform::getInfo(unsigned int, std::string*) const':
main.cpp:(.text._ZNK2cl8Platform7getInfoEjPSs[_ZNK2cl8Platform7getInfoEjPSs]+0x22): undefined reference to `clGetPlatformInfo'
/tmp/ccmKP4oI.o: In function `cl::Platform::get(std::vector<cl::Platform, std::allocator<cl::Platform> >*)':
main.cpp:(.text._ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE[_ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE]+0x41): undefined reference to `clGetPlatformIDs'
main.cpp:(.text._ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE[_ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE]+0xb4): undefined reference to `clGetPlatformIDs'
collect2: error: ld returned 1 exit status
Order of [most] arguments to g++ is very important.
Libraries should go last (at least after source and object files). You can't really change that.
The -l should preferably be glued to the library name:
g++ -Wall main.cpp -o main -lOpenCL
# ^^^ glue the -l to the library name
You probably want to also pass -g (in addition of -Wall) to the compiler to get a debuggable binary. Use the gdb debugger.
As James Kanze commented, you might want to replace -g with -ggdb if using specifically gdb.
With g++ (and generally under Unix), -l specifies a source of
input (either a .a or a .so), and input is processed in
order. When the input is a static library (a .a file), it
will be scanned for objects which resolve undefined references;
if it is a .so, there aren't any object files in it, but it
will still only be taken into consideration if it resolves some
undefined symbol.
When you put the -l before any object files, there are no
undefined symbols yet, so nothing will be incorporated into the
program.
Related
I have a cpp code in which I have included tcl.h library. I am trying to compile it using the gcc compiler. but I'm getting the following error :
gcc -o top.o -std=c99 top.c
top.c:12: warning: return type defaults to 'int'
/tmp/ccDOTTZQ.o: In function `main':
top.c:(.text+0xa): undefined reference to `Tcl_CreateInterp'
top.c:(.text+0x1f): undefined reference to `Tcl_EvalFile'
top.c:(.text+0x3d): undefined reference to `Tcl_GetVar2Ex'
top.c:(.text+0x75): undefined reference to `Tcl_ListObjGetElements'
top.c:(.text+0xb1): undefined reference to `Tcl_GetString'
top.c:(.text+0xcc): undefined reference to `Tcl_GetInt'
collect2: ld returned 1 exit status
Its not able to find the Cpp-tcl APIs. Kindly help me with this.
Your code is not linking to the Tcl library, so obviously it can't find the implementations of those functions. (In C and C++, the linking to the implementations of functions is a separate stage from the use of the declarations of those functions, which is what the header files provide.)
Except that you're actually calling gcc wrong. You need to use two steps, first with -c to compile the source code to an object file:
gcc -c -o top.o -std=c99 top.c
Then like this to link the result and make an executable:
gcc -o top.exe -std=c99 top.o -ltcl
With the first, you might need to additionally specify an appropriate -I option to locate the include files (if they're not in the standard locations). With the second, you might need to specify an appropriate -L option to locate the library files (libtcl.so). Depending on the system, you might also need to specify some version numbers (e.g., -ltcl86 or -ltcl8.6 instead of -ltcl). These are all options that depend on your build system configuration, so they're hard to predict exactly here.
Before i ask a new question, i have read few or more question about this, but i keep confuse.
I Compile my program with :
g++ -std=c++11 -Wall -O3 -fopenmp main.cpp -o main -D WITH_COUNTER -I /usr/local/src/pcm -L /usr/local/src/pcm -L /usr/local/lib
Then, i found the error :
main.cpp:(.text.startup+0x27e): undefined reference to PCM::getInstance()
main.cpp:(.text.startup+0x289): undefined reference to PCM::resetPMU()
main.cpp:(.text.startup+0x310): undefined reference to PCM::program(PCM::ProgramMode, void const*)
So, can anyone explain to me how to solve this?
You don't actually link with the libraries themselves.
The -L option tells the linker to add a directory to its search-path, but the linker will not go through all libraries in its path to find which might be correct (there could be hundreds or even thousands).
Instead you need to explicitly specify libraries to link with using the -l (lower-case L) option.
For some example library foo, there will exist a file named libfoo.a or libfoo.so. To link with it you use -lfoo.
If the documentation for your library doesn't tell you which library you should link with, look for a suitable named file (as mentioned above) and use the correct option to link with the library.
I tried to run .c file called grover.c in this C application libquantum
www.libquantum.de/files/libquantum-1.1.1.tar.gz
Now I this application already contains a Makefile.in and I can generate the executables called shor and grover using the command
./configure
make
make demos
But when I try to run grover.c using gcc or clan like this
clang grover.c
It gives me error of lots of undefined function reference.
In function oracle':
grover.c:(.text+0x50): undefined reference toquantum_sigma_x'
grover.c:(.text+0x89): undefined reference to quantum_toffoli'
grover.c:(.text+0xc8): undefined reference toquantum_toffoli'
grover.c:(.text+0xf2): undefined reference to quantum_cnot'
grover.c:(.text+0x137): undefined reference toquantum_toffoli'
grover.c:(.text+0x16b): undefined reference to quantum_toffoli'
grover.c:(.text+0x1b0): undefined reference toquantum_sigma_x'
I need to know how can I remove this error and if I can run this c code called grover.c in this application.
Thanks,
It looks like your compiler can not find one or more libraries to link to. My hunch is that the makefile has the appropriate commands to invoke the linker.
If you look at your makefile, you probably will see some commands like -L -l,
when the flag -L add a directory to the default search path for libraries and the flag -l is used to name the library to link.
for example -L/lib/openGL -lglut32 would cause the library libglut32.so.X.Y.Z which is found in the directory /lib/openGL. (not this is for a Linux system, but it should be fairly similar for Mac).
N.B. X.Y.Z are the version number of the library.
Once you work this out, there may be issues with the load finding the libraries, especially if they are in non-standard locations.
------------------------ edit --------------------------
After I posted this, and went to bed I realized that I missed a potential case (and thanks to Paul Griffiths for also noticing my omission.....teach me to do multiple things at once).
Any how, just compiling a simple file, say hello.c, as clang hello.c -o hello works because everything is in one file and clang will automatically link to the C run-time library.
If, in your case the code is spread across multiple files, say grover.c and file1.c you would need to do:
clang -c grover.c -o grover.o
clang -c file1.c -o file1.o
clang grover.o file1.o -o grover
(or alteratively clang grover.c file1.c -o grover)
SO what the first two lines are doing is translating the source-code files (grover.c and file1.c) into object files. THe third line covers the two object files into an executable.
Finally, both these cases can be involved. You could have multiple files as well as missing libraries.
So I have a very sample code for trying to decode a FFMPEG video stream.
My problem is avcodec does not want to link, to do so I made a clean installation of Ubuntu 13.04. I have build ffmpeg from source following the guide here: https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
I just want to compile my file. Note that my ubuntu does not have any implementations or header files for avcodec. The command line I use is:
gcc -I/home/USER/ffmpeg_build/include -L/home/USER/ffmpeg_build/lib -lavcodec -o test.exe Downloads/auv/src/dronerosvideo/src/ar2.cpp
/tmp/ccKTprFq.o: In function `fetch_and_decode(int, int, bool)':
ar2.cpp:(.text+0x36e):
undefined reference to `avcodec_register_all'
ar2.cpp:(.text+0x378):
undefined reference to `av_log_set_level'
ar2.cpp:(.text+0x382):
undefined reference to `avcodec_find_decoder'
ar2.cpp:(.text+0x3b1):
undefined reference to `avcodec_alloc_context3'
ar2.cpp:(.text+0x3d6):
undefined reference to `avcodec_open2'
ar2.cpp:(.text+0x46d):
undefined reference to `av_init_packet'
ar2.cpp:(.text+0x50a):
undefined reference to `avcodec_decode_video2'
ar2.cpp:(.text+0x534):
undefined reference to `av_free_packet'
/tmp/ccKTprFq.o:(.eh_frame+0x13): undefined reference to
`__gxx_personality_v0'
collect2: error: ld returned 1 exit status
Just for a sane test if I remove the -L argument compiler says:
/usr/bin/ld: cannot find -lavcodec
Which means that the linker finds the library in /home/USER/ffmpeg_build/lib. Also if we check the library for implementation it exists:
nm ffmpeg_build/lib/libavcodec.a | grep "register_all"
0000000000000000 T avcodec_register_all
Also as advised since it is C++ I have exten "C" around the include of the library.
At this point I'm falling out of any ideas at all, why exactly compilation fails?
First, it is C++, so you'll need to use g++ not gcc so that the C++ standard library gets linked. This should get rid of undefined reference to '__gxx_personality_v0'.
Then, the order of libaries to link is actually important.
You'll need to specify a library after the object (or source or other library) using it.
Putting it together, a command line like this works (in my tests):
g++ -o test.exe -I$HOME/ffmpeg/include test.cc -L$HOME/ffmpeg/lib -lavcodec
(Actually, depending on how ffmpeg was built, you might need other libraries as well, like pthreads or libx264)
If you got pkg-config installed, it might be possible to just ask that it for proper clags:
# Since you didn't install ffmpeg to a known location, tell pkg-config about that location.
export PKG_CONFIG_PATH=$HOME/ffmpeg/lib/pkgconfig
g++ -o test.exe $(pkg-config -clags libavcodec) test.cc $(pkg-config -libs libavcodec)
My friends developed a C++ game in Visual Studio on Windows, and I would like to compile it on my Linux x64 machine. I'm not very familiar with C++ but I'm trying g++ on command-line. However I only get a bunch of undefined reference errors.
The basic file structure is:
Libraries/SFML-2.0/lib
Libraries/SFML-2.0/include
Libraries/SFML_Linux64/lib
Libraries/SFML_Linux64/include
Libraries/Box2D/lib
Libraries/Box2D/include
Libraries/Box2DLinux/lib
Libraries/Box2DLinux/include
Game
Game/lib
Game/includes
Game/... (other subdirectories)
I tried the following command:
g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/
This is the kind of errors I get (some lines snipped and replaced with ...):
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: I funktionen "_start":
(.text+0x20): undefined reference to `main'
/tmp/ccFXe37c.o: I funktionen "mp::createNetworkThread(void*)":
app.cpp:(.text+0x10): undefined reference to `worldDataMutex'
app.cpp:(.text+0x15): undefined reference to `sf::Mutex::lock()'
...
/tmp/ccFXe37c.o: I funktionen "mp::App::exec()":
app.cpp:(.text+0x148): undefined reference to `mp::ResourceHandler::instance()'
app.cpp:(.text+0x15a): undefined reference to `mp::ResourceHandler::loadTexture(std::string)'
app.cpp:(.text+0x3d7): undefined reference to `mp::Window::Window(mp::WorldData*)'
app.cpp:(.text+0x406): undefined reference to `mp::Controller::Controller(mp::World*, mp::Window*)'
...
app.cpp:(.text+0x471): undefined reference to `sf::Mutex::unlock()'
app.cpp:(.text+0x4bb): undefined reference to `sf::Thread::launch()'
app.cpp:(.text+0x4d7): undefined reference to `sf::Clock::Clock()'
app.cpp:(.text+0x4e6): undefined reference to `sf::Clock::getElapsedTime() const'
...
collect2: fel: ld returnerade avslutningsstatus 1
(I hope you can look through the Swedish above.)
That's very courteous of you to provide library paths to the linker. However, linkers are ungrateful slobs and usually do not look for any library files on their own when they see an undefined reference to a function.
Like, undefined reference to `sf::Mutex::lock() — I bet there is libsfml-system.so.2.0 or whatever in the Libraries/SFML_Linux64/lib/ directory, with the definition for sf::Mutex::lock(). But the linker doesn't care. You have to say -lsfml-system at the end of your compile invocation.
This will make g++ understand to look for functions not only in libstdc++ library, but also in the libsfml-system file. And if g++ happen to find such a file in the default or additional (specified with -L flag) library directories, he will use it for resolving references to function calls.
But you have to say to it explicitly what library files you want to throw in, specifying only directories with libraries doesn't do much. So, try to use
g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/ -lsfml-system
How to build C++ programs
C++ programs are built in two steps: the first step is compilation, and the second step is linking.
During compilation, you turn your source files into object files — things which contain compiled machine code. Now there is a trick you have to understand. Say, if you have a.cpp with
// a.cpp
int f(int x);
int main() {
return f(42);
}
you can compile it with g++ -c a.cpp and it will get you object file a.o (with compiled code), without any compilation errors. But wait! There is no actual definition of what f() is in a.cpp!
And now, when you go to the second step, linking, and invokes g++ -o test a.o, it will complain that there is undefined reference to f(). So let's make b.cpp with this text:
// b.cpp
int f(int x) {
return 2 * x - 3;
}
compile it with g++ -c b.cpp and then perform linking as g++ -o test a.o b.o — and wow, now it links without an error!
What happened? Well, when the compiler sees a function call, it puts in object file not an actual call instruction, but a placeholder that says "call a function with such and such name and such and such parameters". And then the linker takes a bunch of object files, and sews them together. When it sees such a placholder, it looks for the mentioned function in object files it was given, and puts actual call to it instead of the placeholder.
So, the building of C++ program looks something like this:
For each x.cpp file you have, call g++ -c x.cpp <bunch of flags> -I<include directories>
Then call g++ -o resultprogram a.o b.o c.o d.o ... <bunch of flags> -L<library directories> -l<additional libraries>
-l flag tells the linker that if he sees a call to a function, and there is no such function defined anywhere in the specified object files (a.o, b.o, etc), then it should look in this library. Please not, that the linker won't look in any object files and/or libraries except those you specified (okay, it will also look in standard C++ library libstdc++, but that's it).
However, this process is pretty boring to do by hand if you have 10 or more files. That's why people use "project files" and "build systems". When Visual Studio builds a project, it does all those steps I mentioned: it compiles every single file in a project, and then links the result together. On Linux, you don't have Visual Studio, but you have make utility. There are some utilities for converting VS projects to makefiles, I believe.