什么相当于cmake中gcc的-mwindows选项?

时间:2010-05-02 07:44:36

标签: c windows gtk cmake

我正在关注tuto:

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

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

如何摆脱该控制台?

我试过了:

add_executable(Cmd WIN32 cmd.c)

但得到了这个致命的错误:

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

使用gcc直接工作:

gcc -o Cmd cmd.c -mwindows ..

我猜这与入门函数有关:int main( int argc, char *argv[]),但为什么gcc有效?

如何使其与cmake一起使用?

更新

让我在这里粘贴源代码以方便:

#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;
}

UPDATE2

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

也许这不等同于cmake中的-mwindows

5 个答案:

答案 0 :(得分:5)

add_executable(Cmd WIN32 cmd.c)

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

答案 1 :(得分:2)

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

但是如果您不想获得丑陋的控制台窗口,则需要使用窗口模式(即将main函数转换为propper WinMain函数)。通过这种方式,您可以显示正常的窗口。

编辑:顺便说一句,你真的不应该把你的程序命名为“cmd”,这就是Windows命令解释器的名称。

答案 2 :(得分:2)

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

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

有关详细信息,请参阅this answer以获取链接器标志,并this answer了解如何在cmake中设置标志。

答案 3 :(得分:1)

根据CMake documentation for using the WIN32 flag with ADD_EXECUTABLE

  

当此属性设置为true时,在Windows上链接的可执行文件将使用WinMain()入口点而不是main()创建。这使得它成为GUI可执行文件而不是控制台应用程序。请参阅CMAKE_MFC_FLAG变量文档以配置MFC for WinMain可执行文件的使用。

但是,您的计划的切入点是main()而不是WinMain()。相反,你应该做的是省略WIN32标志,但你需要链接libgtk。因此,您可以使用TARGET_LINK_LIBRARIES:

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})

答案 4 :(得分:0)

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

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