CMake:如何在调试构建中使用不同的ADD_EXECUTABLE?

4
我希望构建我的应用程序,使得调试模式为控制台应用程序,发布模式为Win32应用程序。根据文档,我需要根据是否需要控制台应用程序来将WIN32添加到add_executable中。
因为我正在使用Visual Studio,所以无法使用CMAKE_BUILD_TYPE(生成的项目包含多个配置)。如何告诉CMAKE在发布构建时使用WIN32,而在调试构建时省略它?
2个回答

7

引用自http://www.cmake.org/Wiki/VSConfigSpecificSettings

此页面介绍了CMake如何生成Visual Studio项目文件,并向其添加配置特定的设置。这些设置可以包括编译器标志、链接器选项和其他构建过程中需要的设置。

if(WIN32)
   set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
   set_target_properties(WindowApplicationExample PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
   set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
   set_target_properties(WindowApplicationExample PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "_CONSOLE")
   set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:windows")
   set_target_properties(WindowApplicationExample PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:windows")
endif(WIN32)

更新:由于错误,近期版本中该功能已损坏。我发现一种解决方法是将“/SUBSYSTEM:WINDOWS”改为“/SUBSYSTEM:windows”。出于某种原因,这似乎有效。


我有同样的问题,但这个解决方案在VC++ 2010上不起作用。 - fbafelipe
@fbafelipe,我在编写这个答案时使用的是VC++ 2010,所以除非有什么改变(在VC++或CMake中),否则它应该可以工作。你是否应用了底部提到的解决方法? - Gili
1
是的,我试过了,但还是不行。我忘了提到,我使用的是VC++ 2010 express打开这个项目(尽管CMake生成了VC++ 2010项目,我不认为这会有任何区别)。我尝试了很多方法,我尝试将LINK_FLAGS更改为所有配置,但它并没有更改为WINDOWS子系统。我唯一能够使用Windows子系统的方法是ADD_EXECUTABLE(name WIN32 sources),但这样我就无法在控制台中进行调试,并且在Windows中发布。 - fbafelipe
1
我建议@fbafelipe把这个问题提交到CMake邮件列表,并请求CMake的作者最终解决这个问题。 - Gili
你应该将示例代码更改为使用小写字母的 windows - Joakim
显示剩余2条评论

5
不确定CMake是否已经修复了这个错误。我使用的是VC++ 2010 Express和CMake v2.8.10.1(目前是最新版本),但我仍然遇到了完全相同的问题。 这里提供了一个可行的解决方案:通过添加以下内容修改您的源代码(例如main.cpp/main.c):
#ifndef NDEBUG
#pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#endif

或者,您可以将链接器标志“/SUBSYSTEM:WINDOWS”添加到发布模式构建中。我正在使用此定义,似乎有效:

#ifdef _MSC_VER
#    ifdef NDEBUG
#        pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#    else
#        pragma comment(linker, "/SUBSYSTEM:CONSOLE")
#    endif
#endif

请使用入口点设置,以避免在定义了以下内容时出现链接器错误:
int main(int argc, char* argv[]) { ... }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接