I am working on a project that is to be made of one executable linking with two libraries.
I'm making frequent chages to all of them and don't wish to go though a sudo make install
cycle for libA
and libB
, so I have laid them out in the following fashion:
myProject
├── libA
│ ├── CMakeLists.txt
│ ├── include
│ │ └── libA
│ │ └── *.h
│ └── src
│ └── *.cpp
│
├── libB
│ ├── CMakeLists.txt
│ ├── include
│ │ └── libB
│ │ └── *.h
│ └── src
│ └── *.cpp
│
├── CMakeLists.txt
├── include
│ └── *.h
└── src
└── *.cpp
I'm using CMake subdirectories to automatically link in libA
and libB
into myProject
, and it works fine. The CMakeList.txt
s are set up as follows:
# myProject/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(myProject)
add_subdirectory(libA)
add_subdirectory(libB)
# Compiler flags, listing of the source files into ${SOURCE_FILES}, etc.
add_executable(myProject ${SOURCE_FILES})
target_link_libraries(myProject libA libB)
# myProject/libA/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(libA)
# Compiler flags, listing of the source files into ${SOURCE_FILES}, etc.
add_library(libA STATIC ${SOURCE_FILES})
target_include_directories(libA PUBLIC include)
install(
TARGETS libA
ARCHIVE DESTINATION lib
)
install(
DIRECTORY include/glk
DESTINATION include
)
myProject/libB/CMakeLists.txt
is similar.
Now here's the issue: libB
has a dependency on libA
, and includes libA
's headers through #include <libA/foo.h>
, and will need symbols from libA
upon linking (though I guess that's a non-issue with static libraries).
How can I set up this dependency correctly so that libB
finds everything it needs about this local libA
, ideally by modifying only myProject
's configuration?
You need to specify a link dependency of libB
on libA
. Yes, they might be static libraries, but CMake allows you to specify that you link one library to another even if they are static. Where the libraries are static, such a link relationship is then only used for providing transitive dependencies between the targets (ie those provided as PUBLIC or INTERFACE items in the various target_...
commands). So I'd expect your libB
's CMakeLists.txt to look similar to libA
', except you'd also add the following line:
target_link_library(libB PRIVATE libA)
Or if libB
uses parts of libA
in its own public API, make the above link dependency PUBLIC rather than PRIVATE. By doing this, anywhere that you have a target link against libB
, CMake will ensure that libA
appears after it on the final command line. In your example, the top level CMakeLists.txt file links libB
after libA
, so without the above target_link_library()
relationship, the linker would complain about symbols from libA
being missing, even though libA
would have been on the linker command line, just in the wrong order. Your syntax for target_link_libraries()
in your top level CMakeLists.txt files is also incorrect (presumably just a typo in your example). Arguments should not be comma-separated.
The other effect of explicitly linking libB
to libA
is that now libB
picks up PUBLIC and INTERFACE properties from libA
, which in this case will be the header search path that libA
defines. You should find that libB
will now find libA
's headers too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.