引言
在 【创建你自己的库】 这篇文章中,我们遇到一个问题,就是必须先创建库,然后才能编译我们的源程序,那么有没有办法让我们的源程序与库同时编译呢?答案是肯定的。
构造同步编译
其实思路很简单,就是在根 CMakeLists.txt 文件中,把创建库的指令写好,然后目标文件引入即可。我们来看一下具体内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| cmake_minimum_required(VERSION 3.21) project(test VERSION 0.0.1 LANGUAGES C)
set(CMAKE_C_STANDARD 11)
set(LIB_INSTALL_DIR ${PROJECT_SOURCE_DIR}/libs/lib) set(LIB_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/libs/include)
option(EMBED_SOURCE "using embed source to build" ON)
if (EMBED_SOURCE) message(STATUS "start build...") include_directories(${PROJECT_SOURCE_DIR}/utils)
set(UTILS_SOURCE ${PROJECT_SOURCE_DIR}/utils/utils.c )
file(STRINGS ${PROJECT_SOURCE_DIR}/utils/VERSION version)
add_library(utils STATIC ${UTILS_SOURCE}) add_library(utils-share SHARED ${UTILS_SOURCE}) set_target_properties(utils-share PROPERTIES OUTPUT_NAME utils VERSION ${version} PUBLIC_HEADER utils/utils.h )
install(TARGETS utils utils-share ARCHIVE DESTINATION ${LIB_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} PUBLIC_HEADER DESTINATION ${LIB_INCLUDE_DIR} PUBLIC_HEADER DESTINATION ${LIB_INCLUDE_DIR} )
endif ()
add_subdirectory(src)
|
有了前几篇文章的基础,这段代码就不难理解了。
- 10 行,我们添加一个开关,是否采用内嵌代码编译。
- 12 ~ 37 行进行编译库。
- 13 行,我们打印构建日志,这里只是单纯的标记构建开始。
- 14 行,引入头文件。
- 16 行,指定源码路径。
- 20 行,指定动态库的版本号。
- 22 ~ 23 行,添加库。
- 24 行,设置库属性。
- 30 行,将库安装到指定路径。
我们再看一下 src 下的 CMakeLists.txt 文件:
1 2 3 4 5 6 7 8 9 10
| set(MAIN_SOURCE main.c )
add_executable(test ${MAIN_SOURCE}) target_link_libraries(test PRIVATE utils)
install(TARGETS test RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin )
|
这里我们去掉了之前的 target_include_directories(test PRIVATE ${UTILS_HEADER})
,因为已经 include_directories(${PROJECT_SOURCE_DIR}/utils)
过了。然后 target_link_libraries(test PRIVATE utils)
这里,我们用 utils 库的名字(即 add_library(utils STATIC ${UTILS_SOURCE})
指定的名字)取代之前的变量。
最后我们使用 install 命令,将源码打包成 bin 文件,并放到 ${PROJECT_SOURCE_DIR}/bin 路径下,其中 RUNTIME 代表可执行文件的意思。