关于C#:cmake中gcc的-mwindows选项相当于什么?

What's the equivalent of gcc's -mwindows option in cmake?

我正在关注tuto:

http://zetcode.com/tutorials/gtktutorial/firstprograms/

它可以工作,但是每次我双击可执行文件时,都有一个我不想要的控制台。

我如何摆脱那个控制台?

我尝试了这个:

1
add_executable(Cmd WIN32 cmd.c)

但是出现了致命错误:

1
2
MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
Cmd.exe : fatal error LNK1120: 1 unresolved externals

直接使用gcc时:

1
gcc -o Cmd cmd.c -mwindows ..

我猜想它与入口函数int main( int argc, char *argv[])有关,但是为什么gcc可以工作?

如何使其与cmake一起使用?

更新

为了方便起见,请在此处粘贴源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
  GtkWidget *window;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_show(window);

  gtk_main();

  return 0;
}

更新2

为什么gcc -mwindows有效但add_executable(Cmd WIN32 cmd.c)无效?

也许这与cmake中的-mwindows等效吗?


add_executable(Cmd WIN32 cmd.c)

告诉CMake这是Windows程序,它将查找WinMain而不是main。如果要查看正在使用的标志,可以运行make VERBOSE = 1。问题可能是如何为gtk应用程序定义WinMain?我知道使用Qt,您可以链接到为您定义它的库中。


您可以将这些链接器标志设置为具有main()入口点,并且没有控制台:

1
2
SET(CMAKE_EXE_LINKER_FLAGS
   "${CMAKE_EXE_LINKER_FLAGS} /subsystem:windows /ENTRY:mainCRTStartup")

有关更多信息,请参见此答案以了解链接器标志,以及有关如何在cmake中设置标志的答案。


如果希望程序在控制台模式下运行(即main函数),则必须在MSVC的项目属性中指定它。您现在正在使用的是处于窗口模式的项目(即WinMain函数,您没有此功能,因此会出现错误)。

但是,如果您不想获取丑陋的控制台窗口,则可以使用窗口模式(即,将main函数转换为适当的WinMain函数)。这样,您的普通窗口便会显示出来。

编辑:顺便说一句,您真的不应该将程序命名为" cmd",这是Windows命令解释器的名称。


根据CMake文档,将WIN32标志用于ADD_EXECUTABLE:

When this property is set to true the executable when linked on Windows will be created with a WinMain() entry point instead of of just main().This makes it a GUI executable instead of a console application. See the CMAKE_MFC_FLAG variable documentation to configure use of MFC for WinMain executables.

但是,程序的入口点是main()而不是WinMain()。相反,您应该做的是忽略WIN32标志,但是您需要针对libgtk进行链接。因此,您将使用TARGET_LINK_LIBRARIES:

1
2
3
4
5
FIND_PACKAGE(GTK2 2.6 REQUIRED gtk)
INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK2_LIBRARIES})
ADD_EXECUTABLE(myprogramname source1 source2 ... sourceN)
TARGET_LINK_LIBRARIES(myprogramname ${GTK2_LIBRARIES})


对于CMake 3.13及更高版本,您可以使用

1
target_link_options(target PRIVATE"/SUBSYSTEM:WINDOWS""/ENTRY:mainCRTStartup")