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!
Related
I use g++ 10.2.0 and try to create a static library, but when I create object file for archiving a static library, object file format always shows precompiled header, it makes the final static library cannot work:
//file static_test.cpp
void fn(){
int temp;
++temp;
}
//file static_test.h
void fn();
build them but not link
g++ -c static_test.h static_test.cpp -o static_test.o
use file to show static_test.o format
file static_test.o
static_test.o:GCC precompiled header (version 014) for C++
and I archive it
ar rsv libstatic_test.a static_test.o
use file to show libstatic_test.a format:
current ar archive
use a main.cpp to test this static library
#include "static_test.h"
int main(){
fn();
return 0;
}
compile them and link
g++ main.cpp libstatic_test.a
libstatic_test.a: cannot add symbol: archive has no index;run ranlib to add one
collect2: error:ld return 1
why and how to solve this problem, tks~
-c is only for a single file, the second static_test.cpp is ignored. You should get the compiler warning about multiple files set to -c. g++ -c static_test.h results the precompiled header in static_test.o and static_test.cpp is ignored. The proper command should be
g++ -c static_test.cpp -o static_test.o
Do not pass header files to the compiler when you compile object files. All other commands you are using look ok.
if you would like to create a static library with gcc, you have to say it to the linker/wrapper programm "gcc" like:
gcc -static -o libyourlibname(.lib/.so) obj1.o obj2.o -s
legende:
-static: tells the linker to build a static lib
-o : output file
-s : strip all debug/linking stuff, including debug informations
note:
may be you need the option -fPIC at .c compile time like:
gcc -O2 -fPIC -c file1.c -o file1.o
legende:
-O2 : tells the c compiler to optimize
-fPIC : create program independet code (internal for the output code)
-c : compile C file to object file:
-o : tell the linker how the object file should be named
By the way:
Pre-compiled header files are only created by compiling C/C++ files only.
You have require huge memory, and mostly pre-compiled header files are not needed in small projects of small student homework tasks.
And each time you change the header file, you (the compiler) have to create a new copy of the .pch file.
Of course, .pch files are good for end-products which does not change it in the form for the developer. But they are mostly depend on the compiler.
So, you can't use .pch files from Windows MinGW64 Project under Linux (with the near) same compiler in different versions.
I'm having a custom C header file that I have created. There are several files in my directory as follows.
lib1/
-lib1.h
-lib1.c
lib2/
-lib2.h
-lib2.c
-lib_main.c
-lib_main.h
-main.c
-main.cpp
-Makefile
Now, for testing the header file with a test file called main.c, I will be giving the following command in the terminal,
gcc lib_main.c lib1/lib1.c lib2/lib2.c main.c -o ./main
Now, how could I test the same header files with main.cpp instead of main.c, how do I change it?
You should (and most probably must) compile separately the c and c++ sources into a object file, and then link together.
As an example
gcc -c -o lib1.o lib1/lib1.c
gcc -c -o lib2.o lib2/lib1.c
gcc -c -o lib_main.o lib_main.c
g++ -c -o main.o main.cpp
g++ -o main lib1.o lib2.o lib_main.o main.o
The first four commands create a series of object files, with extension .o. The last command link together the object files into an executable.
Obviously you need to add the relevant compiler options for each source.
Two important points to notice:
Order of files in the linking is important. See discussion here and here.
To mix c and c++ code with each other, for example if a c++ code calls a c function, you need to follow specific guidelines.
I wrote a c++ class(files class.h and class.cpp) that I want to use in a c++ application app.cpp from multiple directories on my linux system. Therefore, I moved the class.h and class.cpp files to /usr/local/include/. I tried to compile app.cpp using g++ -o app app.cpp which results in an undefined reference error(probably since g++ does not find the class.cpp file).
I figured out that I can fix this error by either writing the content of class.cpp directly into class.h or by explicitly specifying the location of class.cpp with the extended command g++ -o app app.cpp /usr/local/include/class.cpp. Obviously, both solutions are not satisfactory.
Presumably, someone who does this stuff more regularly(I'm not an computer science student) can give me a quick solution to my problem. Therefore, I ask now instead of investing more hours into searching the web.
Create a static compiled library using g++ -c class.cpp and ar rvs libclass.a class.o(can also create a shared library here)
Compile using g++ -o app app.cpp -lclass
For example, I'm given carModels.cpp, carModels.h, carType.in, manufacturers.h, manufacturers.o, and lastly my own file tester.cpp. How would I go about linking all of these using g++ in a Linux terminal? Would I have to create any additional ".o" files? I'm supposed to assume that the given files already work. Multiple lines in terminal are fine, I just I want a clear understanding of it. (I'm coming from a C++ IDE that I didn't really care for.)
Compile each source file to its own object file:
g++ -I . -c carModels.cpp -o carModels.o
g++ -I . -c tester.cpp -o tester.o
Now link all object files together:
g++ carModels.o tester.o manufacturers.o -o outputname
Consider adding more options like -O3, -std=c++11, -Wall, etc. as needed.
you can do this in two steps, first compile to *.o files,
gcc -c your.cpp other.cpp .....
then link them
gcc -o you_out_put_name the_object_files.o ...
In a single line, that would be just g++ -o tester *.cpp *.o. GCC will sort everything out. In particular, the *.h files are referenced via #include "" statements in the .cpp files.
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