I want to make a simple static library, and link to it from another project. There are three source files (all in the same directory) from which to create the library: main1.cpp
, header1.h
, and header2.h
. main1.cpp
contains the line #include "header1.h"
, and in turn header1.h
contains the line #include "header2.h"
. To create the library, I use add_library(foo STATIC main1.cpp)
in my CMakeLists.txt
file. Running cmake
and then make
creates the file libfoo.a
as expected.
I then have another project, with a file main2.cpp
, which contains the line #include "header1.h"
. In the CMakeLists.txt
file for this project, I use add_executable(bar main2.cpp)
and target_link_libraries(bar foo.a)
to create an executable which is linked to my static library. I then copy the foo.a
and header1.h
files and place them in the same directory as this project.
The problem is, during compilation of the second project, I get the following error:
header1.h: fatal error: header2.h: No such file or directory
So it is telling me that header2.h
cannot be found, even though it is referenced in header1.h
. However, I would have thought that the contents of foo.a
would contain all of the content of header2.h
when the library was built? Surely I am not supposed to include all of the header files from the first project when I want to build the second project?
Thanks :)
Short answer: You will need all the header files that expose functionality that you wish your library to export. In other words, if the header file contains functions that are only used within the library you do not need to expose those header files unless some header file you do expose includes that header file.
There seems to be some disconnect between what a library contains and what a header file does. For simplicity lets limit the purpose of header files to having function prototypes (this simplification will be removed later). The purpose of the header file is to tell your new code (that is not part of the library) what the function looks like, as in its name, its parameters and its return type. When you are compiling your new application if it does not have this information it would not know how to handle things such as how to pass arguments and how to handle the return value. Note I did not include that the header file says what the function does, as in the machine code for the function. This is what the library contains. You need both parts in order to properly compile your application.
This can be extended to other things you find in header files, such as structs. The key idea is that your application still needs some information such as function prototypes and struct definitions.
Also you need to remember what #include
does. In its simplest form it just grabs the contents of the specified file. So if one header file includes another, the contents of the second are also grabbed.
Note that this is applies whether it is a static or shared library.
This next part might not be what you are trying to do but it is information future visitors and yourself might find useful:
Now lets say header1.h
contained the functions you wish to expose while header2.h
contained only functions you wish to be internal. Then instead of having header1.h
include header2.h
you should include them separately in the source files, wrap them in another header file that you can include, or have header2.h
include header1.h
if the dependencies allow that. This way you only need to ship header1.h
for your library users. This is not to say that they cannot use the functions in header2.h
as they will still be exposed by the library, as the header files do not control that, but it will make it slightly more difficult to use them. If you want to really prevent a library user from using a function you do not intend to expose check out this SO question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With