如何使用CMake在Windows上将应用程序入口点设置为main()C++?
How to Set C++ Application Entry Point to main() on Windows using CMake?
我最近开始使用CMake,并试图构建一个GUI应用程序,该应用程序在Windows上没有控制台窗口。所以在我的CMakeLists.txt
文件中,我做了这个:
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_executable(${EXECUTABLE_NAME} main.cpp)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_executable(${EXECUTABLE_NAME} WIN32 main.cpp) #WIN32 So the console window does not open on Windows
endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
这样,解决方案就起作用了,并且控制台窗口无法在Windows上打开。但是,这是有代价的。当我尝试构建解决方案时,我意识到我必须将函数的签名更改为WinMain
,因此我将主代码更改为以下内容:
#ifdef _WIN32
#include <Windows.h>
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int) //Windows signature since creating WIN32 application without console
#else
int main()
#endif
{
// ... GUI code
}
不幸的是,我绝对讨厌这一点,因为它破坏了使用 CMake 的全部意义。我不想更改基于不同平台的代码中的任何内容。这就引出了我的问题。在制作 GUI 应用程序时,如何将C++应用程序入口点设置为在 Windows 上main()
,而无需在 Visual Studio 中手动设置它?我可以使用跨平台方法直接在 CMake 中执行此操作吗?还是我必须使用#if/#else/#endif
解决方案?对上述解决方案的唯一改进是使用执行预处理器条件的宏MAIN_FUNCTION
。我也想避免这种情况。
另一方面,有没有另一种方法可以在 Windows 上的 GUI 应用程序中摆脱控制台窗口,我不知道在不使用 WIN32 选项的情况下使用 CMake?
解决方案是在add_executable
之前添加set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
它隐藏了控制台,同时仍然允许您将通常的int main()
作为入口点。
你在这里混淆了两件事,但它们是密切相关的。
显示的控制台是具有 Win32 标头IMAGE_OPTIONAL_HEADER::Subsystem
值为WINDOWS_CUI
而不是WINDOWS_GUI
的应用程序的结果。这是 Win32 的事情,它适用于所有可执行文件,无论它们是用哪种语言编写的。
入口点签名是特定于编译器的选项。它是语言运行时调用的入口函数,而不是操作系统。OS 调用语言运行时的入口函数,该函数首先初始化该运行时,然后将控制权移交给入口点。
现在,VC++ 编译器使用 CRT 作为运行时。而且该 CRT 运行时确实使用两个不同的签名作为入口点。显然,std::cin
的实现必须与WINDOWS_CUI
一起使用,这就是命令行用户界面的重点。但同样的 CRT 也适用于WINDOWS_GUI
.
这就是事情变得复杂的地方。实际上,您可以将已编译应用程序的Subsystem
从 CUI 更改为 GUI。CRT不会介意,它与两个子系统兼容。但是,由于它是对已编译的应用程序完成的,因此从应用程序的一部分(CRT 启动(到另一部分(入口点(的调用不会受到影响。这是 Win32 更改,而不是C++更改。
若要返回到 CMake:此子系统更改可以在 CMake 之后完成,也可以作为自定义的生成后步骤完成。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 代码在main()中运行,但在函数中出现错误
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 如何在24位SDL_Surface上设置像素的颜色
- std::设置自定义比较器
- 如何使用CMake在Windows上将应用程序入口点设置为main()C++?
- 如何使一个成员变量等于在main()中设置的另一个成员变量