将Make项目转为CMake时如何兼容Makefile的include指令?
处理Makefile include的CMake兼容方案
导入Makefile定义的变量到CMake
如果那些include的Makefile主要是定义变量(比如编译选项、路径),可以通过临时Makefile脚本提取变量,再导入CMake:- 编写临时Makefile脚本,设置好已转换的变量后include目标文件,把需要的变量输出到文本文件
- 用CMake的
execute_process调用make执行这个脚本 - 读取输出的文本文件,在CMake中设置对应变量
示例CMake代码:
# 先设置框架路径和已转换的变量 set(FRAMEWORK_DIR "/实际框架路径") set(MY_VARIABLE "no") set(MY_OTHER_VARIABLE "yes") # 生成临时Makefile用于提取变量 file(WRITE ${CMAKE_BINARY_DIR}/extract_make_vars.mk " MY_VARIABLE := ${MY_VARIABLE} MY_OTHER_VARIABLE := ${MY_OTHER_VARIABLE} include ${FRAMEWORK_DIR}/some_makefile.mk # 把需要的变量写入临时文件 \$(file > imported_vars.txt,FRAMEWORK_CFLAGS=\$(FRAMEWORK_CFLAGS)) \$(file >> imported_vars.txt,FRAMEWORK_INCLUDE_DIRS=\$(FRAMEWORK_INCLUDE_DIRS)) ") # 执行make提取变量 execute_process( COMMAND make -f ${CMAKE_BINARY_DIR}/extract_make_vars.mk WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE MAKE_EXEC_RESULT ) # 读取并设置变量 if(EXISTS ${CMAKE_BINARY_DIR}/imported_vars.txt) file(STRINGS ${CMAKE_BINARY_DIR}/imported_vars.txt IMPORTED_VAR_LINES) foreach(VAR_LINE IN LISTS IMPORTED_VAR_LINES) string(REGEX MATCH "^([A-Z_]+)=(.*)$" _VAR_MATCH ${VAR_LINE}) if(_VAR_MATCH) set(${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "从框架Makefile导入的变量") endif() endforeach() endif() # 之后就可以在CMake中使用这些导入的变量了 add_compile_options(${FRAMEWORK_CFLAGS}) include_directories(${FRAMEWORK_INCLUDE_DIRS})让CMake调用Make处理部分构建
如果include的Makefile包含复杂的编译、链接规则,直接转CMake成本太高,可以让CMake调用make生成目标文件,再整合到CMake的构建流程中:# 自定义命令调用make生成目标文件 add_custom_command( OUTPUT plugin_core.o COMMAND make -f ${CMAKE_CURRENT_SOURCE_DIR}/plugin_build.mk DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/plugin_src.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # 用生成的目标文件创建最终库 add_library(plugin SHARED plugin_core.o)这种方式不用修改框架的Makefile,框架更新后只要重新构建就能自动同步。
内容的提问来源于stack exchange,提问作者NateM
相关产品推荐
相关产品推荐

