一、简单配置
-
列出所有
.c文件, 头文件h放在根目录无需列出cmakeminimumrequired(VERSION 3.5.0) project(c-ascii-roguelite VERSION 0.1.0 LANGUAGES C)
# 列出所有 .c 源文件(用空格分隔) add_executable(c-ascii-roguelite main.c player.c map.c ) -
用
file(GLOB)自动收集源文件cmakeminimumrequired(VERSION 3.5.0) project(c-ascii-roguelite VERSION 0.1.0 LANGUAGES C)
# 自动收集 src 目录下所有 .c 文件(假设所有 .c 都在 src 文件夹) file(GLOB SOURCES "src/*.c") # SOURCES 变量会包含所有匹配的文件
add_executable(c-ascii-roguelite ${SOURCES})
二、头文件路径处理(不在根目录)
cmakeminimumrequired(VERSION 3.5.0)
project(c-ascii-roguelite VERSION 0.1.0 LANGUAGES C)
add_executable(c-ascii-roguelite
main.c
player.c
map.c
)
# 指定头文件所在目录(让编译器能找到 #include "player.h")
targetincludedirectories(c-ascii-roguelite PRIVATE
${CMAKECURRENTSOURCE_DIR}/include # 假设头文件在 include 文件夹
)
三、添加自定义命令
执行顺序
-
file(GLOB)在配置阶段获取 *.c 的文件,存入 SOURCES 变量 -
list(APPEND)手动添加动态生成文件 -
adddependencies构建主目标c-ascii-roguelite前先完成generatemap;必须在add_executable后,确保依赖关系能关联到已定义的主目标
构建产物
-
动态生成的源码:参与编译,需加入
SOURCES,参考object.c -
辅助构建产物:不参与编译,仅生成文件,参考
map.pngcmakeminimumrequired(VERSION 3.5.0) project(c-ascii-roguelite VERSION 0.1.0 LANGUAGES C)
set(CMAKECSTANDARD 11) set(CMAKECSTANDARD_REQUIRED ON)
addcustomcommand( OUTPUT ${CMAKESOURCEDIR}/object.h COMMAND awk -v pass=h -f ${CMAKESOURCEDIR}/object.awk ${CMAKESOURCEDIR}/object.txt > ${CMAKESOURCEDIR}/object.h DEPENDS ${CMAKESOURCEDIR}/object.awk ${CMAKESOURCEDIR}/object.txt COMMENT "Generating object.h" )
addcustomcommand( OUTPUT ${CMAKESOURCEDIR}/object.c COMMAND awk -v pass=c1 -f ${CMAKESOURCEDIR}/object.awk ${CMAKESOURCEDIR}/object.txt > ${CMAKESOURCEDIR}/object.c COMMAND awk -v pass=c2 -f ${CMAKESOURCEDIR}/object.awk ${CMAKESOURCEDIR}/object.txt >> ${CMAKESOURCEDIR}/object.c DEPENDS ${CMAKESOURCEDIR}/object.awk ${CMAKESOURCEDIR}/object.txt ${CMAKESOURCEDIR}/object.h COMMENT "Generating object.c" )
addcustomcommand( OUTPUT ${CMAKESOURCEDIR}/map.gv # 生成的 map.gv 放在构建目录 COMMAND awk -f ${CMAKESOURCEDIR}/map.awk ${CMAKESOURCEDIR}/object.txt > ${CMAKESOURCEDIR}/map.gv DEPENDS ${CMAKESOURCEDIR}/map.awk # 依赖的 awk 脚本(源目录) ${CMAKESOURCEDIR}/object.txt # 依赖的输入文件(源目录) COMMENT "Generating map.gv using map.awk" )
# 生成 map.png(依赖 map.gv 和 dot 工具) addcustomcommand( OUTPUT ${CMAKESOURCEDIR}/map.png # 生成的 map.png 放在构建目录 COMMAND dot -Tpng -o ${CMAKESOURCEDIR}/map.png ${CMAKESOURCEDIR}/map.gv DEPENDS ${CMAKESOURCEDIR}/map.gv # 依赖前面生成的 map.gv COMMENT "Generating map.png using dot" )
addcustomtarget( generate_map DEPENDS ${CMAKESOURCEDIR}/map.gv ${CMAKESOURCEDIR}/map.png ${CMAKESOURCEDIR}/object.c COMMENT "Generating map.gv and map.png" )
file(GLOB SOURCES "*.c") list(APPEND SOURCES object.c)
add_executable(c-ascii-roguelite ${SOURCES}) adddependencies(c-ascii-roguelite generatemap)
四、多目录复杂构建
list(APPEND)追加
file(GLOB SOURCES "${SRC_DIR}/*.c")
file(GLOB SRCUTILFILES "${SRCUTILDIR}/*.c")
# 将util目录的源文件和生成的object.c加入项目(核心修改:追加SRCUTILFILES)
list(APPEND SOURCES
${SRCUTILFILES} # 新增:加入util目录的tokenize.c
${GEN_DIR}/object.c
)
# 可执行文件
add_executable(c-mud-adventure ${SOURCES})
file(GLOB)普通合并
file(GLOB) 是直接覆盖,错误使用:
file(GLOB SOURCES "${SRC_DIR}/*.c")
file(GLOB SOURCES "${GEN_DIR}/object.c")
正确使用:
file(GLOB SOURCES "${SRC_DIR}/*.c")
file(GLOB SRCUTILFILES "${SRCUTILDIR}/*.c")
# 合并所有源文件(核心修改:直接合并SRCUTILFILES)
set(SOURCES
${SOURCES}
${SRCUTILFILES}
${GEN_DIR}/object.c
)
# 可执行文件
add_executable(c-mud-adventure ${SOURCES})
file(GLOB_RECURSE)递归合并(推荐)
file(GLOB_RECURSE) 是递归匹配指定目录
file(GLOBRECURSE SRCROOTFILES "${SRCDIR}/*.c")
# 3. 合并所有源文件
set(SOURCES
${SRCROOTFILES}
${GEN_DIR}/object.c
# 可执行文件
add_executable(c-mud-adventure ${SOURCES})
五、指定 C 语言标准
# 显式指定 C 标准为 C11
set(CMAKECSTANDARD 11)
# 强制要求编译器支持该标准(避免降级)
set(CMAKECSTANDARD_REQUIRED ON)