C++项目doggo中集成第三方C代码的CMake配置咨询
Great to hear your gtest integration is running smoothly! Let’s break down how to add a new third-party C library to your existing setup—there are two main scenarios to cover, depending on whether the library comes with its own CMake configuration.
Scenario 1: The Library Has Its Own CMakeLists.txt
If the third-party library is already set up to work with CMake (many popular libraries are), this is straightforward:
Drop the library into your external directory
Place the entire library folder (e.g.,mylib) insidedoggo/external/.Update your external CMake config
Opendoggo/external/CMakeLists.txtand add a newadd_subdirectoryline for your library, right alongside the gtest entry:# Google gtest for unit testing. add_subdirectory(gtest) message("gtest include dir: ${gtest_SOURCE_DIR}") include_directories(${gtest_SOURCE_DIR}) # New third-party C library add_subdirectory(mylib)Link the library to your project target
In your top-leveldoggo/CMakeLists.txt, find where you define your project’s executable or library (e.g.,add_executable(doggo src/main.cpp)), and add the library to the link command:target_link_libraries(doggo PRIVATE mylib gtest)Most well-written CMake libraries export their include paths automatically, so you won’t need extra
include_directoriescalls. If you do need to manually add includes, use the library’s source dir variable (e.g.,${mylib_SOURCE_DIR}/include).
Scenario 2: The Library Doesn’t Have CMake Support (Raw Source Files)
For smaller or legacy C libraries that only provide .c and .h files, you’ll need to wrap them in a CMake target yourself:
Organize the library files
Create a new folder indoggo/external/(e.g.,rawclib), and structure it to separate source and include files:doggo/external/rawclib/ ├── include/ │ └── rawclib.h └── src/ ├── file1.c └── file2.cAdd a CMakeLists.txt for the library
Createdoggo/external/rawclib/CMakeLists.txtwith this content to build it as a static library (useSHAREDinstead if you need a dynamic library):# Build the third-party C code as a static library add_library(rawclib STATIC src/file1.c src/file2.c # Add all other .c files here ) # Make the include directory accessible to your project target_include_directories(rawclib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) # Set C standard if the library requires it (e.g., C99) set_target_properties(rawclib PROPERTIES C_STANDARD 99)Register the library in your external config
Addadd_subdirectory(rawclib)todoggo/external/CMakeLists.txt, just like in Scenario 1.Link it to your project
Again, update your top-level CMake target’s link command:target_link_libraries(doggo PRIVATE rawclib gtest)Now you can
#include <rawclib.h>in your project code without any extra paths.
Quick Example: Adding cJSON (a Popular C JSON Library)
Let’s put this into practice with cJSON, which is often distributed as raw source:
- Download cJSON’s
cJSON.candcJSON.hand place them indoggo/external/cjson/. - Create
doggo/external/cjson/CMakeLists.txt:add_library(cjson STATIC cJSON.c) target_include_directories(cjson PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - Add
add_subdirectory(cjson)todoggo/external/CMakeLists.txt. - Link it to your project:
You’re ready to usetarget_link_libraries(doggo PRIVATE cjson gtest)#include "cJSON.h"in your code!
Best Practices to Keep Things Clean
- Avoid global commands: Prefer
target_link_librariesandtarget_include_directoriesover globalinclude_directoriesorlink_libraries—this keeps dependencies scoped to specific targets and prevents conflicts. - Handle dependencies: If your new library relies on other third-party code, make sure to add those dependencies first in
external/CMakeLists.txt(sinceadd_subdirectoryruns in order). - Make it optional: If the library isn’t required for your core functionality, use an option to toggle it:
option(BUILD_WITH_MYLIB "Enable support for mylib" ON) if(BUILD_WITH_MYLIB) add_subdirectory(mylib) target_link_libraries(doggo PRIVATE mylib) endif()
内容的提问来源于stack exchange,提问作者BoltzmannBrain

