cmake:DEBUG_POSTFIX 根据debug/release类型指定target的输出文件名

本文介绍如何使用CMake设置调试(debug)与发布(release)版本的输出文件名不同,通过利用OUTPUT_NAME_DEBUG属性或DEBUG_POSTFIX属性实现目标文件名区分。

在用cmake生成工程文件(such as Makefile)编译项目的时候,有时我们希望debug/release生成的二进制文件在文件名上有区别:
比如对于target project1,在debug模式编译的dll,希望在Debug模式下生成的文件名为project1_d.dll,以与release模式下编译的project1.dll区别开。该怎么实现呢?

(本文末尾有更新内容)

这就要用到CMAKE的一个target属性:OUTPUT_NAME
OUTPUT_NAME预定义target的生成目标文件名,如果没有指定,则默认为target的名字。
对于Debug/Release等不同的配置,还有对应的属性OUTPUT_NAME_DEBUGOUTPUT_NAME_RELEASE,默认也是target的名字。
可以通过set_target_properties设置OUTPUT_NAME_<CONFIG>的值。
所以我们只要修改OUTPUT_NAME_DEBUG的值就可以达到上述的要求。

下面的cmake脚本以一个functin实现了对指定的target,在debug模式下自动对输出的文件名加_d后缀:

# debug模式下对输出文件名加_d后缀
# targets 输入参数,一组target
function(set_target_output_name targets)
foreach(target ${targets})
  # 获取 OUTPUT_NAME_DEBUG 的值
  get_target_property(_output_name ${target} OUTPUT_NAME_DEBUG)  
  if(_output_name)
    # 如果 OUTPUT_NAME_DEBUG已经定义则直接在后面加_d
    set_target_properties(${target} PROPERTIES OUTPUT_NAME_DEBUG "${_output_name}_d" )
  else()
    # 否则直接修改OUTPUT_NAME_DEBUG 
    set_target_properties(${target} PROPERTIES OUTPUT_NAME_DEBUG "${target}_d" )
  endif()  
  get_target_property(_output_name ${target} OUTPUT_NAME_DEBUG)
  # 显示修改后的结果
  message(STATUS "TARGET:${target} OUTPUT_NAME_DEBUG=${_output_name}")
  # 清除临时变量
  unset(_output_name)
endforeach()
endfunction()

实际调用的效果如下:

– TARGET:fse_cas_static OUTPUT_NAME_DEBUG=fse_cas_static_d
– TARGET:fse_cas OUTPUT_NAME_DEBUG=fse_cas_d
– TARGET:fse_cas_static_mt OUTPUT_NAME_DEBUG=fse_cas_static_mt_d

也可以利用cmake-generator-expressions让写法更简化:

  set_target_properties(${target} PROPERTIES OUTPUT_NAME "${target}$<$<CONFIG:Debug>:_d>" )

实际应用的例子参见:
https://gitee.com/l0km/feature_se/blob/master/feature_se/CMakeLists.txt

DEBUG_POSTFIX

cmake的内容实在是太多了,了解也是一步步深入的,今天找到了DEBUG_POSTFIX这个target property,才知道上面的过程都太low了。
cmake已经提供了DEBUG_POSTFIX这个target属性,用于指定deuug版本的文件结尾符,这才是最正确的打开方式。
所以要指定Target的debug版结尾符

只需要调用set_target_propertiesset_property

set_target_properties (myTarget PROPERTIES DEBUG_POSTFIX _d)
	
set_property(TARGET myTarget PROPERTY DEBUG_POSTFIX _d)	

也可以通过set(CMAKE_DEBUG_POSTFIX _d)预定义所有target的DEBUG_POSTFIX

NOTE
实际测试证明:使用DEBUG_POSTFIX指定输出文件结尾对executable target(可执行文件)无效。

参考资料

https://cmake.org/cmake/help/v3.1/prop_tgt/CONFIG_POSTFIX.html
https://cmake.org/cmake/help/v3.1/prop_tgt/DEBUG_POSTFIX.html
https://cmake.org/cmake/help/v3.1/variable/CMAKE_DEBUG_POSTFIX.html

将这个CMakeLists.txt文件: cmake_minimum_required(VERSION 3.20) if(MSVC) # 设置工具集为v141(VS2017) set(CMAKE_GENERATOR_TOOLSET "v141" CACHE STRING "Platform Toolset" FORCE) set(CMAKE_GENERATOR_PLATFORM "x64") # 设置Windows SDK版本(根据实际安装版本修改) set(CMAKE_SYSTEM_VERSION "10.0.17763.0") endif() project(MCUSim LANGUAGES C) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif() # 设置项目版本(可选) set(MCUSim_VERSION 1.0.0) # 设置C标准 set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) # 根据配置类型设置不同的编译选项 set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Add a postfix, usually for debug builds") # 设置可执行文件输出目录 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) # 定义源文件和头文件 set(APP_SOURCES "source/APP/Control/src/Control_can_api.c" "source/APP/Control/src/Control_config_api.c" "source/APP/Control/src/Control_emergencybraking_api.c" "source/APP/Control/src/Control_main_task.c" "source/APP/Control/src/Control_soc_api.c" "source/COM/com_log.c" "source/COM/seqqueue.c" "source/HAL/CAN/hal_can.c" "source/HAL/CAN/hal_can_api.c" "source/HAL/CAN/hal_can_ring_queue.c" "source/MID/CAN/mid_can_ctrl_api.c" "source/MID/CAN/mid_can_ctrl_drv.c" "source/MID/CAN/mid_can_ctrl_gen_acu_il.c" "source/MID/CAN/mid_can_ctrl_gen_asc_il.c" "source/MID/CAN/mid_can_ctrl_gen_eps_il.c" "source/MID/CAN/mid_can_ctrl_gen_esc_il.c" "source/MID/CAN/mid_can_ctrl_gen_gw_il.c" "source/MID/CAN/mid_can_ctrl_gen_ibooster_il.c" "source/MID/CAN/mid_can_ctrl_gen_il.c" "source/MID/CAN/mid_can_ctrl_gen_uss_il.c" "source/MID/CAN/mid_can_ctrl_gen_vcu_il.c" "source/MID/CAN/mid_can_ctrl_il.c" "source/MID/CAN/mid_can_ctrl_nm.c" "source/MID/CAN/mid_can_ctrl_task.c" "source/MID/CAN/mid_can_parser.c" "source/MID/Serial/DataLinkCtrl/mid_dl_ctrl_api.c" "source/MID/Serial/DataLinkCtrl/mid_dl_ctrl_callback.c" "source/MID/Serial/DataLinkCtrl/mid_dl_ctrl_main.c" "source/MID/ShareOBJ/mid_share_common_api.c" "source/MID/ShareOBJ/mid_share_control.c" "source/MID/ShareOBJ/mid_share_gen_acu_api.c" "source/MID/ShareOBJ/mid_share_gen_asc_api.c" "source/MID/ShareOBJ/mid_share_gen_eps_api.c" "source/MID/ShareOBJ/mid_share_gen_esc_api.c" "source/MID/ShareOBJ/mid_share_gen_gw_api.c" "source/MID/ShareOBJ/mid_share_gen_ibooster_api.c" "source/MID/ShareOBJ/mid_share_gen_uss_api.c" "source/MID/ShareOBJ/mid_share_gen_vcu_api.c" "source/OSM/osm.c" "source/OSM/osm_timer.c" "source/main.c" ) # 头文件路径(用于IDE显示,不是必须的,但为了清晰可以列出) file(GLOB_RECURSE HEADERS "source/APP/Control/include/*.h" "source/MID/Serial/DataLinkCtrl/*.h" "source/FreeRTOSv202012.00/FreeRTOS/Source/include/FreeRTOS.h" "source/FreeRTOSv202012.00/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h" "source/FreeRTOSv202012.00/FreeRTOS/Source/include/*.h" ) # include_directories( # AFTER # SYSTEM "D:/mingw64/x86_64-w64-mingw32/include" # 标记为系统目录 # ) # add_compile_options(-isystem "D:/mingw64/x86_64-w64-mingw32/include") # 隔离系统头文件[^4] if(MSVC) add_compile_options(/w) # MSVC编译器 add_compile_options(/Zi) add_link_options(/DEBUG) else() add_compile_options(-w) # GCC/Clang编译器 endif() set(CMAKE_BUILD_TYPE Debug) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") # -ggdb3 生成GDB专用调试信息,-O0 禁用优化 add_compile_options(-ggdb3 -O0 -fno-inline) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g") endif() # 创建可执行目标 add_executable(${PROJECT_NAME} ${APP_SOURCES} ${HEADERS}) # 包含目录 target_include_directories(${PROJECT_NAME} PRIVATE "source/ALL_INCLUDE" "source/COM" "source/ALL_INCLUDE/OSM" "source/MID/ShareOBJ" "source/APP/Control/include" "source/APP/Control/lib/include" "source/HAL/CAN" "source/MID/Serial/DataLinkCtrl" "source/FreeRTOSv202012.00/FreeRTOS/Source/include" "source/FreeRTOSv202012.00/FreeRTOS/Demo/WIN32-MingW" "source/FreeRTOSv202012.00/FreeRTOS/Source/portable/MSVC-MingW" "source/CanOSS" # "source/FreeRTOSv202012.00/FreeRTOS/Source/portable/MSVC-MingW" # "C:/Program Files (x86)/Kvaser/Canlib/INC" ) # 预处理器定义 target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:WIN32;_DEBUG;_CONSOLE;WIN32_SIM;_CRT_SECURE_NO_WARNINGS> $<$<CONFIG:Release>:WIN32;NDEBUG;_CONSOLE> ) # 链接库目录 target_link_directories(${PROJECT_NAME} PRIVATE source/APP/Control/lib/X86 source/CanOSS # "C:/Program Files (x86)/Kvaser/Canlib/Lib/x64" ) # 链接库 target_link_libraries(${PROJECT_NAME} PRIVATE canlib32 ControlModelCal ) # 设置编译器警告级别等 if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W3 /sdl /permissive- ) else() # 对于GCC或Clang,设置相应的选项 target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra # 以下安全选项可根据需要添加,注意不是所有平台都支持 # -D_FORTIFY_SOURCE=2 # -fstack-protector # 严格标准模式 -pedantic-errors ) endif() # 链接器选项 target_link_options(${PROJECT_NAME} PRIVATE /DEBUG # 生成调试信息(在Debug配置中) $<$<CONFIG:Debug>:/INCREMENTAL> # 增量链接(Debug) $<$<CONFIG:Release>:/INCREMENTAL:NO> # 非增量链接(Release) ) # 对于Release配置,开启全程序优化和优化引用 if(CMAKE_BUILD_TYPE STREQUAL "Release") target_compile_options(${PROJECT_NAME} PRIVATE /O2 # 优化级别(通常Release用/O2) /GL # 全程序优化 ) target_link_options(${PROJECT_NAME} PRIVATE /LTCG # 链接时代码生成(全程序优化) /OPT:REF # 优化引用 ) endif() # 设置字符集为Unicode(在Windows上) if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /D_UNICODE /DUNICODE # 定义Unicode宏 ) # 或者使用add_definitions,但更推荐target_compile_definitions # target_compile_definitions(${PROJECT_NAME} PRIVATE _UNICODE UNICODE) endif() 改写进下面makefile文件中: # ========================================================================= # Unity - A Test Framework for C # ThrowTheSwitch.org # Copyright (c) 2007-24 Mike Karlesky, Mark VanderVoord, & Greg Williams # SPDX-License-Identifier: MIT # ========================================================================= #We try to detect the OS we are running on, and adjust commands as needed ifeq ($(OS),Windows_NT) ifeq ($(shell uname -s),) # not in a bash-like shell CLEANUP = del /F /Q MKDIR = mkdir else # in a bash-like shell, like msys CLEANUP = rm -f MKDIR = mkdir -p endif TARGET_EXTENSION=.exe else CLEANUP = rm -f MKDIR = mkdir -p TARGET_EXTENSION=.out endif C_COMPILER=gcc ifeq ($(shell uname -s), Darwin) C_COMPILER=clang endif UNITY_ROOT=../.. CFLAGS=-std=c89 CFLAGS += -Wall CFLAGS += -Wextra CFLAGS += -Wpointer-arith CFLAGS += -Wcast-align CFLAGS += -Wwrite-strings CFLAGS += -Wswitch-default CFLAGS += -Wunreachable-code CFLAGS += -Winit-self CFLAGS += -Wmissing-field-initializers CFLAGS += -Wno-unknown-pragmas CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef CFLAGS += -Wold-style-definition #CFLAGS += -Wno-misleading-indentation TARGET_BASE1=test1 TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION) SRC_FILES1=$(UNITY_ROOT)/src/unity.c src/test_main.c test/TestControlCode.c test/test_runners/TestControlCode_Runner.c INC_DIRS=-Isrc -I$(UNITY_ROOT)/src SYMBOLS= all: clean default default: $(SRC_FILES1) $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1) - ./$(TARGET1) # test/test_runners/TestProductionCode_Runner.c: test/TestProductionCode.c # ruby $(UNITY_ROOT)/auto/generate_test_runner.rb test/TestProductionCode.c test/test_runners/TestProductionCode_Runner.c # test/test_runners/TestProductionCode2_Runner.c: test/TestProductionCode2.c # ruby $(UNITY_ROOT)/auto/generate_test_runner.rb test/TestProductionCode2.c test/test_runners/TestProductionCode2_Runner.c clean: $(CLEANUP) $(TARGET1) $(TARGET2) ci: CFLAGS += -Werror ci: default
最新发布
10-23
find_package(PCL 1.14.1 REQUIRED) if (WIN32) target_compile_definitions(${PROJECT_NAME} PRIVATE NOMINMAX) endif() target_link_libraries(${PROJECT_NAME} PRIVATE ${PCL_LIBRARIES}) D:\QT_project\untitled1\CMakeLists.txt:51: warning: Call stack: D:/QT_project/untitled1/CMakeLists.txt:51 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:556 (find_external_library) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:300 (find_qhull) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:155 (find_package) D:/QT_project/untitled1/CMakeLists.txt:51 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:559 (find_external_library) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:294 (find_boost) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:121 (find_package) D:/QT_project/untitled1/CMakeLists.txt:51 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:559 (find_external_library) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:298 (find_flann) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:253 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/Modules/FindFLANN.cmake:45 (find_package) D:/QT_project/untitled1/CMakeLists.txt:51 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:559 (find_external_library) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:294 (find_boost) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:121 (find_package) D:/QT_project/untitled1/CMakeLists.txt:51 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:559 (find_external_library) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:294 (find_boost) D:/LightSpark/QT__/PCL1.14.1/cmake/PCLConfig.cmake:121 (find_package) D:/QT_project/untitled1/build/Desktop_Qt_6_8_3_MSVC2022_64bit-Debug/.qtc/package-manager/maintenance_tool_provider.cmake:322 (find_package)
07-11
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值