2014-12-16 4 views
3

Я использую Clion IDE и пытаюсь получить простую программу GTK для ее компиляции. Я обнаружил, что Clion использует CMake, поэтому проблемы здесь, а не с самой IDE. Я могу успешно скомпилировать и запустить программу непосредственно с терминала, но не удалось использовать CMake.Как добавить аргументы компилятора с помощью 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 

Любые предложения?


Дальнейшие исследования показали 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}) 
+0

Я не знаю, но когда вы получите ответ, обратите внимание: ваш путь include и строка pkg-config не совпадают. Вы хотите использовать GTK + 2 или GTK + 3? Это будет важно, чтобы избежать проблем позже. – andlabs

+0

Спасибо. Я это исправил. Я скопировал эту строку с веб-сайта с использованием 2.0 и забыл отредактировать его, чтобы отразить 3.0. – sherrellbc

+0

У вас есть '/ usr/include' в переменной' PATH' (окружение)? Это совсем не полезно. –

ответ

7

Используйте модуль 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>) 

биты в шевронов (<...>) должны быть заменены реальными значениями

вы можете узнать больше с

cmake --help-module FindPkgConfig 

В основном строка include(FindPkgConfig) содержит несколько макросов - это также гарантирует, что pkg-c onfig доступен в среде. Затем вызов 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 
+0

Я обновил OP с помощью аналогичного кода. Где «GTK_INCLUDE_DIRS» и другие, казалось бы, неопределенные переменные, определенные? – sherrellbc

+0

pkg_check_modules принимает свой первый аргумент (GTK в этом случае) в качестве основы и добавляет суффиксы типа _LDFLAGS, _CFLAGS, _INCLUDE_DIRS и т. Д. Для формирования имен переменных, которые он использует для возврата результатов поиска. – kdopen

+0

Обновлен мой ответ, чтобы объяснить немного больше, и ответьте ваши дополнительные вопросы :) – kdopen

1

Вы должны понимать, что, когда вы вручную ввести команду компиляции

`pkg-config …` 

не является на самом деле аргумент компилятору, но заставляет оболочку выполнить pkg-config с аргументами и использует вывод этого исполнения, который используется в качестве команд компилятору. Я предлагаю вам ввести только команду pkg-config в вашу оболочку, чтобы увидеть, что она выводит. Например. на моем ноутбуке это

[email protected] ~/ % 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 для деталей.

Смежные вопросы