简体   繁体   中英

Creating C++ library with CMake

I am trying to create a reasonable library structure and CMake file which would allow other CMake projects to easily include this library. I've found a lot of similar questions, however, none of them seems to address my exact problem.

My current structure is the following:

/*MyLibrary/
├── CMakeLists.txt (including lib subdirectories)
├── external/
│   └── googletest/
├── lib/
│   ├── common/
│   │   ├── CMakeList.txt (creates static lib common)
│   │   ├── include/common/*.h
│   │   └── src/*.cpp
│   ├── cipher/
│   │   ├── CMakeList.txt (creates static lib cipher)
│   │   ├── include/cipher/*.h
│   │   └── src/*.cpp
└── test/
    ├── main.cpp (code for executing google test)
    ├── CMakeLists.txt (creates unittest executable)
    ├── common/*Test.cpp
    └── cipher/*Test.cpp
*/

Now I want to create a project with a similar directory structure but the problem occurs when I want to create a static library in that project with the same name as one of the static libraries in MyLibrary ( common for example).

I was thinking of including the library into the project using add_subdirectory(external/MyLibrary) in the projects CMakeLists, but that fails because the names of the static libraries collide.

Even when I solve this issue by renaming the library (which I don't in fact believe is an elegant solution), I end up with googletest conflicts because both, the library and my project, are dependent on googletest.

Is there any way to solve this easily? I was thinking of 2 possibilities:

  • In the MyLibrary I would create one static library from all the sub-libraries called libMyLibrary.a and include only that library (preferred option, but I don't have a clue how to achieve it in CMake)

  • Forcing the users of the library to install it and don't include the library as a project submodule (last option I would go for)

Is there some other reasonable way to solve it which would make my library compatible with most CMake projects? If not, how can I achieve at least one of the mentioned options?

In short: how can I create a CMake file for a library so the library is easy to include in other CMake projects?

How can I deal with redundant dependencies such as googletest?

How can I create a CMake file for a library so the library is easy to include in other CMake projects?

There is no universal approach for that purpose.

By including your project into another one with add_subdirectory() , you "open" internals of your project to other one. Aside of advantage in having the library's target ready for linking, this approach has disadvantages too. Target's collisions, cached variables collisions will be your headache, among with some other problems.

If you want your project to be included into other with add_subdirectory , avoid using "generic" names for your targets. Eg, use <my_project_name>_common instead of common .

Some targets you cannot rename (like gtest ). If those targets aren't really required for your project to work, create an option for disable them:

option(<my_project_name>_TESTING "Enable testing" ON)
if(<my_project_name>_TESTING)
    add_subdirectory(external/googletest)
endif()

See also my answer to the similar question about targets' names collision.

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