C++ 如何使用CMake添加编译器参数?

C++ 如何使用CMake添加编译器参数?,c++,c,makefile,cmake,gtk,C++,C,Makefile,Cmake,Gtk,我一直在使用Clion IDE,并且正在尝试使用它来编译一个简单的GTK程序。我发现Clion使用CMake,所以问题出在这里,而不是IDE本身。我能够直接从终端成功编译和运行程序,但使用CMake失败 问题很简单:当我尝试编译时,编译器找不到gtk.h,它位于/usr/include/gtk-3.0/gtk/gtk.h中。我发现命令编译器参数'pkg-config--libs--cflags gtk+-3.0'以某种方式解决了这个问题,但我无法使用CMake添加这个参数 我试过: set(CM

我一直在使用Clion IDE,并且正在尝试使用它来编译一个简单的GTK程序。我发现Clion使用CMake,所以问题出在这里,而不是IDE本身。我能够直接从终端成功编译和运行程序,但使用CMake失败

问题很简单:当我尝试编译时,编译器找不到gtk.h,它位于
/usr/include/gtk-3.0/gtk/gtk.h
中。我发现命令编译器参数
'pkg-config--libs--cflags gtk+-3.0'
以某种方式解决了这个问题,但我无法使用CMake添加这个参数

我试过:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `pkg-config --libs --cflags gtk+-3.0`")
但是我遇到了:

Linking CXX executable test
c++: error: `pkg-config: No such file or directory
c++: error: gtk+-3.0`: No such file or directory
c++: error: unrecognized command line option ‘--libs’
c++: error: unrecognized command line option ‘--cflags’
make[3]: *** [test] Error 1
make[2]: *** [CMakeFiles/test.dir/all] Error 2
make[1]: *** [CMakeFiles/test.dir/rule] Error 2
make: *** [test] Error 2
有什么建议吗


进一步的研究揭示了我所面临的问题。它就像一个魔咒,但似乎把许多似乎未定义的变量投入到组合中。有人能解释一下这是怎么回事吗

# Set the name and the supported language of the project
project(hello-world C)
# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 2.6)
# Use the package PkgConfig to detect GTK+ headers/library files
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
# Setup CMake to use GTK+, tell the compiler where to look for headers
# and to the linker where to look for libraries
include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
# Add other flags to the compiler
add_definitions(${GTK3_CFLAGS_OTHER})
# Add an executable compiled from hello.c
add_executable(hello main.c)
# Link the target to the GTK+ libraries
target_link_libraries(hello ${GTK3_LIBRARIES})

使用FindPkgConfig模块

cmake_minimum_required(VERSION <your cmake version>)
project(myproject CXX)

# Find the GTK module using pkg-config
include(FindPkgConfig)
pkg_check_modules(GTK REQUIRED "gtk+-3.0")

# Add the path to its header files to the compiler command line
include_directories(${GTK_INCLUDE_DIRS})

# Add any compiler flags it requires
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GTK_CFLAGS} <other flags>")

# Add the makefile target for your executable and link in the GTK library
add_executable(${CMAKE_PROJECT_NAME} <list of source files>)    
target_link_libraries(${CMAKE_PROJECT_NAME} ${GTK_LDFLAGS} <other libraries>)
基本上,
include(FindPkgConfig)
行引入了一些宏,它还确保pkg配置在环境中可用。然后,对
pkg\u check\u modules
的调用有效地运行
pkg config
,解析输出,并使用第一个参数创建一组变量

从帮助中,这是一个基本列表(XPREFIX通常是您提供的stem)

\u找到了。。。如果存在模块,则设置为1
_图书馆。。。只有库(不带'-l')
_图书馆指南。。。库的路径(不带'-L')
_LDFLAGS。。。所有必需的链接器标志
_LDU其他。。。所有其他链接器标志
_包括_DIRS。。。'-I'预处理器标志(不带'-I')
_CFLAGS。。。所有要求的CFLAG
_其他。。。其他编译器标志
=对于常见情况
=\u静态用于静态链接

手动键入编译命令时,您必须了解

`pkg-config …`
实际上不是编译器的参数,而是使用参数使shell执行pkg config,并将此执行的输出用作编译器的命令。我建议您只在shell中键入pkg config子命令,查看它的输出。在我的笔记本电脑上是

dw@narfi ~/ % pkg-config --libs --cflags gtk+-3.0

-pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0
-I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo
-I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0
-I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1
-I/usr/include/freetype2 -I/usr/include/libdrm -I/usr/include/gdk-pixbuf-2.0
-I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo
-lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 
这些是传递给编译器的实际参数


CMake不是一个空壳。它有自己的包检测和配置机制。有关详细信息,请参阅@kdopen的答案。

我不知道,但当您得到答案时,请注意:您的include path和pkg config行不匹配。您想使用GTK+2还是GTK+3?这对于避免以后出现问题很重要。谢谢。我修好了。我使用2.0从网站复制了该字符串,但忘了编辑它以反映3.0。在
路径
(环境)变量中是否有
/usr/include
?这一点用处都没有。@EtanReisner,我写这篇文章的时候一定弄错了,可能是想
/usr/local..
。例如,我知道,
iostream
位于
/usr/include/c++..
。如果这样的目录不在路径中,编译器如何知道在哪里可以找到这些头?
PATH
被shell用于查找二进制文件。编译器使用一组内置的位置和由
-I
标志指示的任何位置。我用类似的代码位更新了OP。
GTK_INCLUDE_DIRS
和其他似乎未定义的变量在哪里定义?pkg_check_模块将其第一个参数(在本例中为GTK)作为一个干,并附加诸如_LDFLAGS、_CFLAGS、_INCLUDE_DIRS等后缀,以形成变量名,用于返回搜索更新后的我的答案的结果,以作进一步解释,并回答你的补充问题:)
`pkg-config …`
dw@narfi ~/ % pkg-config --libs --cflags gtk+-3.0

-pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0
-I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo
-I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0
-I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1
-I/usr/include/freetype2 -I/usr/include/libdrm -I/usr/include/gdk-pixbuf-2.0
-I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo
-lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0