I wrote a simple C++ program using ntl libraries. I try to create a static library from my program. I used these commands :
g++ -Wall -g -c base.cpp -o base.o
ar rcs libMyStaticLib.a *.o
libMyStaticLib.a was created successfully. But when I used libMyStaticLib.a in another project I get these error:
g++ -o main.out main.cpp -lMyStaticLib
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libMyStaticLib.a(base.o): In function `NTL::Vec<NTL::GF2>::~Vec()':
/usr/local/include/NTL/vec_GF2.h:43: undefined reference to `NTL::WordVector::~WordVector()'
my main.cpp
#include <iostream>
#include </home/Qwer/test/base.h>
int main()
{
baseInit();
return 0;
}
I try to link ntl library while creating static library
ar rcs libMyStaticLib.a *.o -lntl
But I get this error :
ar: two different operation options specified
I want to try static library and use it in anoother project. How should I so this ?
Static libraries are nothing more that archives (that's what the ar program creates, and the .a suffix stands for) of object files. Linking with a static library is like linking with the objects files inside the archive.
That's why all other libraries that your static library depends on also must be linked:
$ g++ -o main.out main.cpp -lMyStaticLib -lntl
Related
As part of my learning, I am trying to merge two static libraries into single shared library. Following sequence of commands I am using to prepare static libraries
$gcc -c mathutil.cpp -o mathutil.o
$ar rcs libmathutil.a mathutil.o
$gcc -c dateutil.cpp -o dateutil.o
$ar rcs libdateutil.a dateutil.o
Could somebody please tell me how to merge these two static libraries into single shared library.
I have tried the following command
gcc -Wl,--whole-archive -shared libutil.so libmathutil.a
But it is giving lot of multiple definition errors.
If you have the source files why not compile them into a shared library directly? Add the -fPIC flag to your compile lines (PIC = Position Independant Code), and then link something like:
Compile the files:
gcc -c -fPIC mathutil.cpp -o mathutil.o
gcc -c -fPIC dateutil.cpp -o dateutil.o
Create the shared lib:
gcc -shared dateutil.o mathutil.o -o bin/shared/libutil.so
I'm trying to learn how to build and use dynamic library in a c++ program. Everything is fine and my program run well when I launch it from Terminal (I'm on a mac OS X El Capitan). Surprisingly that's not the case when I try to launch it by clicking on the executable. I get a dyld: Library not loaded: liblibrary.so, Reason: image not found error.
All my files are in a same repertory. I build them with commands :
g++ -c -fPIC A.cpp
g++ -c -fPIC B.cpp
g++ -shared -fPIC A.o B.o -o library.so
g++ main.cpp library.so -o Program
Thank's in advance for your help.
I tried the following solutions :
Add a PATH, both in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH
Change the library extention : library.so or library.dylib
Add an rpath g++ main.cpp library.so -Wl,-rpath,. -o Program and g++ main.cpp library.so -Wl,-rpath,$HOME/my_dir -o Program
You may need to give an explicit rpath (as an absolute path, not a relative one) at compile time (e.g. with g++ -Wall -Wl,-rpath,$HOME/yourdir main.cpp library.so -o Program), or setup some DYLD_LIBRARY_PATH, see this. You could need a .dylib suffix, not a .so one.
(I don't have any MacOSX any more, so I forgot the details)
Finally, I found the solution. Actually, dynamic library creation is different for macOS. What I tried since the beginning is only working for Linux.
So the Mac solution is:
g++ -dynamiclib -install_name "absolute_path/library.dylib" A.o B.o -o library.dylib
where:
-dynamiclib is the Mac equivalent for -shared.
-install_name "absolute_path/library.dylib" create an alias of library.dylib for the linker which is necessary to use library.dylib.
After that, the traditional command:
g++ main.cpp library.dylib -o Program
creates the executable if main.cpp and library.dylib are in the same directory.
The program can then be used everywhere in the system as long as library.dylib stays in the same place.
Following the comment of #Ssswift, relative path linking can be achieved with the command:
g++ -dynamiclib -install_name "#executable_path/library.dylib" A.o B.o -o library.dylib
The library can then follow the executable.
Thanks for your help.
I am attempting to link a CUDA kernel with a C++ autotools project however cannot seem to pass the linking stage.
I have a file GPUFloydWarshall.cu that contains the kernel and a wrapper C function that I would like place into a library libgpu.a. This will be consistent with the remainder of the project. Is this at all possible?
Secondly, the library would then need to be linked to around ten other libraries for the main executable which at the moment using mpicxx.
Currently I am using/generating the below commands to compile and create the libgpu.a library
nvcc -rdc=true -c -o temp.o GPUFloydWarshall.cu
nvcc -dlink -o GPUFloydWarshall.o temp.o -L/usr/local/cuda/lib64 -lcuda -lcudart
rm -f libgpu.a
ar cru libgpu.a GPUFloydWarshall.o
ranlib libgpu.a
When this is all linked into the main executable I get the following error
problem/libproblem.a(libproblem_a-UTRP.o): In function `UTRP::evaluate(Solution&)':
UTRP.cpp:(.text+0x1220): undefined reference to `gpu_fw(double*, int)'
Th gpu_fw function is my wrapper function.
Is this at all possible?
Yes, it's possible. And creating a (non-CUDA) wrapper function around it makes it even easier. You can make your life easier still if you rely on C++ linking throughout (you mention a wrapper C function). mpicxx is a C++ compiler/linker alias, and cuda files (.cu) follow C++ compiler/linker behavior by default. Here's a very simple question that discusses building cuda code (encapsulated in a wrapper function) into a static library.
Secondly, the library would then need to be linked to around ten other libraries for the main executable which at the moment using mpicxx.
Once you have a C/C++ (non-CUDA) wrapper exposed in your library, linking should be no different than ordinary linking of ordinary libraries. You may still need to pass the cuda runtime libraries and any other cuda libraries you may be using in the link step, but this is the same conceptually as any other libraries your project may depend on.
EDIT:
It's not clear you need to use device linking for what you want to do. (But it's acceptable, it just complicates things a bit.) Anyway, your construction of the library is not quite correct, now that you have shown the command sequence. The device link command produces a device-linkable object, that does not include all necessary host pieces. To get everything in one place, we want to add both GPUFloydWarshall.o (which has the device-linked pieces) AND temp.o (which has the host code pieces) to the library.
Here's a fully worked example:
$ cat GPUFloydWarshall.cu
#include <stdio.h>
__global__ void mykernel(){
printf("hello\n");
}
void gpu_fw(){
mykernel<<<1,1>>>();
cudaDeviceSynchronize();
}
$ cat main.cpp
#include <stdio.h>
void gpu_fw();
int main(){
gpu_fw();
}
$ nvcc -rdc=true -c -o temp.o GPUFloydWarshall.cu
$ nvcc -dlink -o GPUFloydWarshall.o temp.o -lcudart
$ rm -f libgpu.a
$ ar cru libgpu.a GPUFloydWarshall.o temp.o
$ ranlib libgpu.a
$ g++ main.cpp -L. -lgpu -o main -L/usr/local/cuda/lib64 -lcudart
$ ./main
hello
$
Can someone please tell me how to create a static library from a .cpp and a .hpp file? Do I need to create the .o and the .a? I would also like to know how can I compile a static library in and use it in other .cpp code. I have header.cpp, header.hpp . I would like to create header.a. Test the header.a in test.cpp. I am using g++ for compiling.
Create a .o file:
g++ -c header.cpp
add this file to a library, creating library if necessary:
ar rvs header.a header.o
use library:
g++ main.cpp header.a
You can create a .a file using the ar utility, like so:
ar crf lib/libHeader.a header.o
lib is a directory that contains all your libraries. it is good practice to organise your code this way and separate the code and the object files. Having everything in one directory generally looks ugly. The above line creates libHeader.a in the directory lib. So, in your current directory, do:
mkdir lib
Then run the above ar command.
When linking all libraries, you can do it like so:
g++ test.o -L./lib -lHeader -o test
The -L flag will get g++ to add the lib/ directory to the path. This way, g++ knows what directory to search when looking for libHeader. -llibHeader flags the specific library to link.
where test.o is created like so:
g++ -c test.cpp -o test.o
Can someone please tell me how to
create a static library from a .cpp
and a .hpp file? Do I need to create
the .o and the the .a?
Yes.
Create the .o (as per normal):
g++ -c header.cpp
Create the archive:
ar rvs header.a header.o
Test:
g++ test.cpp header.a -o executable_name
Note that it seems a bit pointless to make an archive with just one module in it. You could just as easily have written:
g++ test.cpp header.cpp -o executable_name
Still, I'll give you the benefit of the doubt that your actual use case is a bit more complex, with more modules.
Hope this helps!
I want to build a library from multiple source files, like a1.cpp a2.cpp. I used the following command, 'g++ -o libcode -c a1.cpp a2.cpp'. However, error pop up "cannot specify -o with -c or -S with multiple files".
In general, how should I build such lib from multiple sources? thanks...
You first compile your source files to objects files (*.o), and then invoke the ar command to build the library. In your example:
g++ -c a1.cpp a2.cpp
ar rcs libcode.a a1.o a2.o
This would build a static library, you can also create a dynamic one.
http://www.network-theory.co.uk/docs/gccintro/gccintro_79.html
http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html