How to create a static library with g++?

155,036

Solution 1

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

Solution 2

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 

Solution 3

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!

Share:
155,036

Related videos on Youtube

linuxx
Author by

linuxx

Updated on July 08, 2022

Comments

  • linuxx
    linuxx almost 2 years

    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.

  • linuxx
    linuxx about 13 years
    and what is with lib/libHeader.a? ar rcs ...isn't it better than ar crf?
  • Sriram
    Sriram about 13 years
    @linuxx: main.o will be the object file you create out of main.cc
  • linuxx
    linuxx about 13 years
    g++ test.cpp header.a -o test,no?
  • Admin
    Admin about 13 years
    @linuxx only if you want to create an executable called test, something you should never do. Without the -o flag, an executable called a.out will be created. Us old Unix programmers like it that way.
  • Sriram
    Sriram about 13 years
    @linuxx: the exact flags you use with the ar utility are your decision based on your requirements. Looking up the man pages for ar would be a good idea.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @unapersson: Why? The executable is not in a.out format so this is highly misleading. And why should you "never" create an executable called test?
  • linuxx
    linuxx about 13 years
    how to test the library using test.cpp?
  • ereOn
    ereOn about 13 years
    @Tomalak Geret'kal: I guess this has to do with the fact that test is a system command. But since test programs usually never are installed in the system bin directory and require you to write ./test it is not that much a problem to me either...
  • Sriram
    Sriram about 13 years
    Replace main in the above code with test and C with cpp. In other words, my main.C (that I have used for illustration) and your test.cpp are, in all likelihood, equivalent.
  • linuxx
    linuxx about 13 years
    Can you please tell me what is main.o? In my code i have header.cpp, header.h and the test.cpp(the code where i would like to test the header.a library).
  • Admin
    Admin about 13 years
    @Tomalak Because test is a shell built-in and if you don't run the program explicitly as ./test (which you will inevitably fail to do) you will pick it up instead of your program, with extremely confusing results. And are you saying that the command does not produce an executable called a.out?
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    Anyway, the point is, you can call your output executable anything you like, or leave it as the default by omitting the -o parameter entirely. You are not bound by strict constructs that you might have been [poorly] taught at school, like "you must write g++ A.cpp B.a -o A".
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @unapersson: No. I'm saying exactly what I said. Executables are no longer produced in a.out format, but the name remains for legacy reasons. (And if you're incapable of using a shell properly then that's your problem; I for one know how to run an executable from the current directory. test is just fine for an executable name, as long as you're writing just a quick test snippet of course.)
  • Admin
    Admin about 13 years
    @Tomalak Please point out where I said anything about "a.out format". An as someone who has trained literally hundreds of Unix programmers, I can assure you that test is not a good name. Now please find someone else to raise your non-issues with.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @unapersson: (a) You didn't. I'm pointing out a fact. Please look up the a.out format as you don't seem to know what it is. (b) You're painting your opinion as a fact, and one which many highly experienced professionals do not share. (c) You raised it. (d) I will not respond further to this conversation.
  • Sriram
    Sriram about 13 years
    @linuxx: If this worked for you, you should mark this answer as correct.
  • greyfade
    greyfade almost 13 years
    @Tomalak: It's how GCC and other *nix compilers have worked for years. They always output an a.out file, whether it's actually in a.out format or ELF or COFF. (On Windows, I think MinGW GCC actually outputs a.exe.) I'm not surprised Neil considers it irrelevant.
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    @greyfade: You're completely right. They've worked that way for years. It's unfortunate that it's the case, because the a.out format is obsolete. Just because that's the default output filename isn't reason to prefer it.
  • greyfade
    greyfade almost 13 years
    @Tomalak: It's not a.out he suggested preferring. He seems quite explicit in preferring not using a name like test.
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    @greyfade: His preference is to omit a name like test; perhaps I'm missing something, but his recommendation appears to be omitting the -o parameter, which produces an output file called a.out.
  • greyfade
    greyfade almost 13 years
    @Tomalak: My takeaway is that it's unimportant and unrelated to the question, and hence requiring no discussion.
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    @greyfade: You may be right there. I thought it worth bringing up as a passing point, but I'm starting to regret that now. :)
  • Dolanor
    Dolanor over 11 years
    Wouldn't it be -lHeader instead of -llibHeader ?
  • President James K. Polk
    President James K. Polk over 11 years
    Naming an executable test is something that I have learned the hard way to regret and I am "perfectly capable of using a shell". It is a bad idea, and I've seen it bite many others who are "perfectly capable of using a shell".
  • Sidhin S Thomas
    Sidhin S Thomas over 7 years
    How do we include multiple modules?
  • Viet
    Viet almost 7 years
    Good one! Sometimes we see ranlib which in GNU simply means ar s.
  • Dan
    Dan about 6 years
    This is a great answer and he have OP more than he asked for
  • n. m.
    n. m. over 5 years
    @JamesKPolk if you have . in your $PATH you will certainly regret something at one point or another.
  • President James K. Polk
    President James K. Polk over 5 years
    @n.m. It's not about having . in your path, but rather the other way around. You run test, forgetting correctly run it as ./test, and instead of getting command not found it simply returns without error (or output).