202 lines
7.2 KiB
CMake
202 lines
7.2 KiB
CMake
cmake_minimum_required(VERSION 3.15)
|
|
|
|
# 项目根目录
|
|
project(InfProjects C)
|
|
|
|
# 设置默认构建类型(可选)
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE "Release")
|
|
endif()
|
|
|
|
# 手动指定项目文件夹列表(根据需要修改)
|
|
set(PROJECT_DIRECTORIES
|
|
Install
|
|
RegistryOverride
|
|
Service
|
|
# SubstituteExecution
|
|
TemplateMatcher
|
|
Test
|
|
Tools
|
|
Update
|
|
)
|
|
|
|
# 设置输出目录
|
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.bin")
|
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.lib")
|
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.static")
|
|
|
|
# 全局编译选项
|
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
|
set(CMAKE_C_FLAGS_RELEASE "-O2 -s -fno-stack-protector -fno-PIC")
|
|
|
|
# 遍历所有子目录
|
|
foreach(SUBDIR ${PROJECT_DIRECTORIES})
|
|
message(STATUS "Processing directory: ${SUBDIR}")
|
|
|
|
# 检查目录是否存在
|
|
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR})
|
|
message(WARNING "Directory ${SUBDIR} does not exist - skipping")
|
|
continue()
|
|
endif()
|
|
|
|
# 检查子目录是否有 CMakeLists.txt
|
|
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/CMakeLists.txt)
|
|
message(WARNING "No CMakeLists.txt in ${SUBDIR} - skipping")
|
|
continue()
|
|
endif()
|
|
|
|
message(STATUS "Found valid project directory: ${SUBDIR}")
|
|
|
|
# 清除可能存在的旧缓存变量
|
|
unset(${SUBDIR}_PROJECT_NAME CACHE)
|
|
unset(${SUBDIR}_MAIN_SOURCE_FILE CACHE)
|
|
unset(${SUBDIR}_RESOURCE_FILE CACHE)
|
|
unset(${SUBDIR}_MANIFEST_FILE CACHE)
|
|
unset(${SUBDIR}_BUILD_AS_DLL CACHE)
|
|
unset(${SUBDIR}_LIBRARY_DIRS CACHE) # 库目录变量
|
|
unset(${SUBDIR}_INCLUDE_DIRS CACHE) # 头文件目录变量
|
|
unset(${SUBDIR}_LINK_LIBRARIES CACHE) # 链接库变量
|
|
|
|
# 进入子目录,让其定义缓存变量
|
|
add_subdirectory(${SUBDIR})
|
|
|
|
# 重命名缓存变量,添加子目录前缀以避免冲突
|
|
set(PROJECT_NAME "${${SUBDIR}_PROJECT_NAME}")
|
|
set(MAIN_SOURCE_FILE "${${SUBDIR}_MAIN_SOURCE_FILE}")
|
|
set(RESOURCE_FILE "${${SUBDIR}_RESOURCE_FILE}")
|
|
set(MANIFEST_FILE "${${SUBDIR}_MANIFEST_FILE}")
|
|
set(BUILD_AS_DLL "${${SUBDIR}_BUILD_AS_DLL}")
|
|
set(LIBRARY_DIRS "${${SUBDIR}_LIBRARY_DIRS}") # 获取子项目指定的库目录
|
|
set(INCLUDE_DIRS "${${SUBDIR}_INCLUDE_DIRS}") # 获取子项目指定的头文件目录
|
|
set(LINK_LIBRARIES "${${SUBDIR}_LINK_LIBRARIES}") # 获取子项目需要链接的库
|
|
|
|
# 验证必要变量是否定义
|
|
set(REQUIRED_VARS PROJECT_NAME MAIN_SOURCE_FILE)
|
|
set(MISSING_VARS "")
|
|
|
|
foreach(VAR ${REQUIRED_VARS})
|
|
if(NOT DEFINED ${VAR} OR "${${VAR}}" STREQUAL "")
|
|
list(APPEND MISSING_VARS ${VAR})
|
|
endif()
|
|
endforeach()
|
|
|
|
if(MISSING_VARS)
|
|
message(WARNING "Missing required variables in ${SUBDIR}: ${MISSING_VARS} - skipping project")
|
|
continue()
|
|
endif()
|
|
|
|
# 检查主源文件是否存在
|
|
set(MAIN_FILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/${MAIN_SOURCE_FILE}")
|
|
if(NOT EXISTS ${MAIN_FILE_PATH})
|
|
message(WARNING "Main source file ${MAIN_SOURCE_FILE} not found in ${SUBDIR} (looked for: ${MAIN_FILE_PATH}) - skipping project")
|
|
continue()
|
|
endif()
|
|
|
|
# 收集源文件
|
|
set(SOURCES "${SUBDIR}/${MAIN_SOURCE_FILE}")
|
|
|
|
# 处理资源文件(如果定义且存在)
|
|
if(NOT "${RESOURCE_FILE}" STREQUAL "" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/${RESOURCE_FILE}")
|
|
list(APPEND SOURCES "${SUBDIR}/${RESOURCE_FILE}")
|
|
message(STATUS "Added resource file for ${PROJECT_NAME}")
|
|
endif()
|
|
|
|
# 处理清单文件(如果定义且存在)
|
|
set(MANIFEST_PATH "")
|
|
if(NOT "${MANIFEST_FILE}" STREQUAL "" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/${MANIFEST_FILE}")
|
|
set(MANIFEST_PATH "${SUBDIR}/${MANIFEST_FILE}")
|
|
list(APPEND SOURCES ${MANIFEST_PATH})
|
|
message(STATUS "Added manifest file for ${PROJECT_NAME}")
|
|
endif()
|
|
|
|
# 判断是构建 DLL 还是 EXE
|
|
if(BUILD_AS_DLL)
|
|
message(STATUS "Building ${PROJECT_NAME} as DLL")
|
|
add_library(${PROJECT_NAME} SHARED ${SOURCES})
|
|
|
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.static"
|
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.lib"
|
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/.lib"
|
|
)
|
|
|
|
if(WIN32)
|
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
|
${PROJECT_NAME}_EXPORTS
|
|
)
|
|
endif()
|
|
else()
|
|
message(STATUS "Building ${PROJECT_NAME} as EXE")
|
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
|
endif()
|
|
|
|
# 设置清单文件(如果存在)
|
|
if(NOT "${MANIFEST_PATH}" STREQUAL "" AND MSVC)
|
|
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY LINK_FLAGS
|
|
"/MANIFEST:EMBED /MANIFESTINPUT:${MANIFEST_PATH}")
|
|
endif()
|
|
|
|
# 添加子项目指定的库目录和头文件目录
|
|
if(LIBRARY_DIRS)
|
|
message(STATUS "Adding library directories for ${PROJECT_NAME}: ${LIBRARY_DIRS}")
|
|
target_link_directories(${PROJECT_NAME} PRIVATE ${LIBRARY_DIRS})
|
|
endif()
|
|
|
|
if(INCLUDE_DIRS)
|
|
message(STATUS "Adding include directories for ${PROJECT_NAME}: ${INCLUDE_DIRS}")
|
|
target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDE_DIRS})
|
|
endif()
|
|
|
|
# 链接库 - 先链接全局库,再链接子项目指定的库
|
|
target_link_libraries(${PROJECT_NAME}
|
|
advapi32
|
|
user32
|
|
wtsapi32
|
|
userenv
|
|
psapi
|
|
shell32
|
|
kernel32
|
|
gdi32
|
|
netapi32
|
|
${LINK_LIBRARIES}
|
|
)
|
|
|
|
# 添加默认链接目录
|
|
target_link_directories(${PROJECT_NAME} PRIVATE
|
|
./.Link
|
|
)
|
|
|
|
# 添加默认头文件目录
|
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
|
./.Link
|
|
)
|
|
|
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy
|
|
"$<TARGET_FILE:${PROJECT_NAME}>"
|
|
"${CMAKE_BINARY_DIR}/.dat/${PROJECT_NAME}$<$<BOOL:${BUILD_AS_DLL}>:.dll>.dat"
|
|
COMMENT "Copying $<TARGET_FILE_NAME:${PROJECT_NAME}> to ${PROJECT_NAME}$<$<BOOL:${BUILD_AS_DLL}>:.dll>.dat"
|
|
)
|
|
|
|
message(STATUS "Successfully configured project: ${PROJECT_NAME}")
|
|
|
|
# 清除变量,避免影响其他项目
|
|
unset(PROJECT_NAME)
|
|
unset(MAIN_SOURCE_FILE)
|
|
unset(RESOURCE_FILE)
|
|
unset(MANIFEST_FILE)
|
|
unset(BUILD_AS_DLL)
|
|
unset(LIBRARY_DIRS)
|
|
unset(INCLUDE_DIRS)
|
|
unset(LINK_LIBRARIES)
|
|
endforeach()
|
|
|
|
add_custom_target(clean-all
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/.bin"
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/.lib"
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/.dat"
|
|
COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_BINARY_DIR}/CMakeCache.txt"
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/CMakeFiles"
|
|
COMMENT "Cleaning all build outputs and cache..."
|
|
)
|