通用 CMakeLists.txt
还在为编写CMakeLists.txt而烦恼吗
试试我这款通用的CMakeLists.txt, 加到你的工程里,让你不再需要编写CMakeLists.txt了
一、先是一个开胃菜:universalCMakeList.cmake
######################################################
####文件universalCMakeList.cmake, 相当于C里的 XXX.h文件###
###当然了,你也可以直接加到CMakeLists.txt 的最顶部 ###
######################################################
#获取当前目录的子目录列表
macro(listSubDir curdir result)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
foreach(child ${children})
if(IS_DIRECTORY ${curdir}/${child})
list(APPEND dirlist ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
#各目录下CMakeLists.txt内容,用于生成编译各模块的Makefile
macro(universalCMakeList)
# 获取当前目录下的源文件名列表
unset(SRC_FILE)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_FILE)
#如果当前目录下有源文件
list(LENGTH SRC_FILE SRC_LEN)
if(${SRC_LEN})
#自动设置目标名称(上级目录名称_当前目录名称)
get_filename_component(UPPER_FOLDER_DIRECTOR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(UPPER_FOLDER ${UPPER_FOLDER_DIRECTOR} NAME)
get_filename_component(CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME)
set(TARGET_NAME "${UPPER_FOLDER}_${CURRENT_FOLDER}")
#保存目标名称
set(TARGET_NAME_LIST ${TARGET_NAME_LIST} ${TARGET_NAME} CACHE STRING INTERNAL FORCE)
#生成目标
add_library(${TARGET_NAME} OBJECT ${SRC_FILE})
endif()
#自动轮询子目录
listSubDir(${CMAKE_CURRENT_SOURCE_DIR} CHILD_DIR_LIST)
foreach(dir ${CHILD_DIR_LIST})
add_subdirectory(${dir})
endforeach(dir)
endmacro()
#创建或者删除各目录下CMakeLists.txt
function(cmakeListsCtrl curdir isrmfile)
if(NOT IS_DIRECTORY ${curdir})
return()
endif()
#创建一个文件CMakeLists.txt,并写入指定内容
if(isrmfile)
file(REMOVE "${curdir}/CMakeLists.txt")
message(STATUS "remove ${curdir}/CMakeLists.txt")
else()
file(WRITE "${curdir}/CMakeLists.txt" "universalCMakeList()")
message(STATUS "write msg to ${curdir}/CMakeLists.txt")
endif()
#获取当前目录下的所有子目录列表
set(filelist "")
file(GLOB filelist RELATIVE ${curdir} ${curdir}/*)
set(filename "")
set(childdirlist "")
foreach(filename ${filelist})
if(IS_DIRECTORY ${curdir}/${filename})
set(rmflag isrmfile)
cmakeListsCtrl(${curdir}/${filename} ${isrmfile})
endif()
endforeach()
endfunction(cmakeListsCtrl)
二、现在是上主菜的时候了
cmake_minimum_required(VERSION 3.20.1)
project(universalCMakeList)
include(cmake/universalCMakeList.cmake)
#################################################
#根据变量CMD值,来删除或者更新各目录下的CMakeLists.txt#
#使用方式 cmake .. -DCMD=remove
#使用方式 cmake .. -DCMD=update
#使用方式 cmake ..
#################################################
if(DEFINED CMD)
if(${CMD} STREQUAL "remove")
message("remove:${CMD}")
cmakeListsCtrl(${PROJECT_SOURCE_DIR}/main ON)
cmakeListsCtrl(${PROJECT_SOURCE_DIR}/src ON)
return()
elseif(${CMD} STREQUAL "update")
message("update:${CMD}")
cmakeListsCtrl(${PROJECT_SOURCE_DIR}/main OFF)
cmakeListsCtrl(${PROJECT_SOURCE_DIR}/src OFF)
endif()
endif()
#################################################
#编译器相关设置
set(CMAKE_BUILD_TYPE DEBUGE)
SET(CMAKE_C_COMPILER "gcc")
SET(CMAKE_CXX_FLAGES "${CAMKE_CXX_FLAGES} -g")
SET(CMAKE_CXX_COMPILER "g++")
SET(CMAKE_CXX_FLAGES "${CAMKE_CXX_FLAGES} -g -std=c++11")
#设置生成的库的输出目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
#设置可执行文件的输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#添加头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/main)
include_directories(${PROJECT_SOURCE_DIR}/src)
#添加引用的库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
#设置全局变量,用来保存所有需要链接的目标名称
unset(TARGET_NAME_LIST CACHE)
set(TARGET_NAME_LIST "" CACHE STRING INTERNAL)
#依次添加需要编译的各个子目录
add_subdirectory(src)
add_subdirectory(main)
#去除重复名称
list(REMOVE_DUPLICATES TARGET_NAME_LIST)
message("${TARGET_NAME_LIST}")
#生成可行性目标
add_executable(${PROJECT_NAME})
#链接所有目标
target_link_libraries(${PROJECT_NAME} ${TARGET_NAME_LIST})