简体   繁体   中英

Dependencies between static library subdirectories and include paths

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM