简体   繁体   中英

CMake Project structure: When to use add_library/target_link_library over target_sources?

I'm creating a C++ project in which I can compartmentalize my source code in the following way

project
│   README.md
│   Dockerfile    
│   CMakeLists.txt <---- Entrypoint
│
└───lib/spdlog (headers)
│
└───src
│   │   main.cpp
│   │   CMakeLists.txt
│   │
│   └───mongo
│   │   │   CMakeLists.txt
│   │   │   mongo.h
│   │   │   mongo.cpp
│   │   │   mongo_utils.h
│   │   │   mongo_utils.cpp
│   │   │   ...
│   │
│   └───core
│       │   CMakeLists.txt
│       │   some_stuff.h
│       │   some_stuff.cpp
│       │   ...
│   
└───tests
    │   CMakeLists.txt
    │   tests

I'm trying to create a solid structure with CMake. I noticed that I have the following options:

  • Either compile all of the subdirectories in src as libraries using add_library and tie them up in the src/CMakeLists.txt where I create my executable using only the main.cpp source file. The downside to this approach is that all libraries depend on the spdlog header files, and core depends on the other libs in src like mongo.
  • Simply use target_sources in each directory and use all these files in the add_executable in src/CMakeLists.txt

I have the feeling that I should make the modules into libraries whenever they do not depend on other code, such as mongo (standalone mongocxx wrapper). If however, mongo where to depend on files in core (having a circular import so to say), then I would use target_sources to wrap them all together in add_executable .

Is this correct? And is using add_library wherever possible the prefered way? How do we efficiently include the lib/spdlog header files in each library?

Compiling separated libraries for each part of a program is usually preferable. This is useful since you can have multiple executable linking to it. For example, automated tests usually are separated executable targets that need to call the part that is testing.

It can also be useful since different part of your program may link to different external libraries, sometimes privately.

However, target_sources is still useful. If you have a source code generator for one of your libraries, you may want to add the generated sources in a different place than the place you call add_library to keep the build clean.

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