【问题标题】:How to add compiler arguments using CMake?如何使用 CMake 添加编译器参数?
【发布时间】:2015-02-15 08:01:32
【问题描述】:

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

问题很简单:当我尝试编译时,编译器找不到位于/usr/include/gtk-3.0/gtk/gtk.h 的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

有什么建议吗?


进一步的研究揭示了this 教程正是我遇到的问题。它就像一种魅力,但似乎将许多看似未定义的变量混入其中。谁能解释这是如何以及为什么起作用的?

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

【问题讨论】:

  • 我不知道,但是当您得到答案时,请注意:您的包含路径和 pkg-config 行不匹配。你想使用 GTK+ 2 还是 GTK+ 3?这对于避免以后出现问题很重要。
  • 谢谢。我修好了。我使用 2.0 从网站复制了该字符串,但忘记对其进行编辑以反映 3.0。
  • 您在PATH(环境)变量中有/usr/include?这一点用处都没有。
  • @EtanReisner,我写的时候一定是搞错了,可能是在考虑/usr/local..。例如,我知道iostream 位于/usr/include/c++..。如果这样的目录不在 PATH 中,编译器怎么知道在哪里可以找到这些头文件?
  • PATH 被 shell 用于查找二进制文件。编译器使用一组内置位置和-I 标志指示的任何位置。

标签: c++ c makefile cmake gtk


【解决方案1】:

使用 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>)

人字形 (&lt;...&gt;) 中的位需要替换为实际值

您可以通过

了解更多信息
cmake --help-module FindPkgConfig

基本上include(FindPkgConfig) 行引入了一些宏 - 它还确保 pkg-config 在环境中可用。然后对pkg_check_modules 的调用有效地运行pkg-config,解析输出,并使用第一个参数作为词干创建一组变量。

根据帮助,这是一个基本列表(XPREFIX 通常是您提供的词干)

      <XPREFIX>_FOUND          ... set to 1 if module(s) exist
      <XPREFIX>_LIBRARIES      ... only the libraries (w/o the '-l')
      <XPREFIX>_LIBRARY_DIRS   ... the paths of the libraries (w/o the '-L')
      <XPREFIX>_LDFLAGS        ... all required linker flags
      <XPREFIX>_LDFLAGS_OTHER  ... all other linker flags
      <XPREFIX>_INCLUDE_DIRS   ... the '-I' preprocessor flags (w/o the '-I')
      <XPREFIX>_CFLAGS         ... all required cflags
      <XPREFIX>_CFLAGS_OTHER   ... the other compiler flags



      <XPREFIX> = <PREFIX>        for common case
      <XPREFIX> = <PREFIX>_STATIC for static linking

【讨论】:

  • 我用类似的代码更新了 OP。 GTK_INCLUDE_DIRS 和其他看似未定义的变量在哪里定义?
  • pkg_check_modules 将其第一个参数(在本例中为 GTK)作为词干,并附加诸如 _LDFLAGS、_CFLAGS、_INCLUDE_DIRS 等后缀以形成用于返回搜索结果的变量名称
  • 更新了我的答案以解释更多,并回答您的补充问题:)
【解决方案2】:

你要明白,当你手动输入编译命令时

`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 不是通过 shell 的。它有自己的包检测和配置机制。有关详细信息,请参阅@kdopen 的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 2019-02-02
    相关资源
    最近更新 更多