«неопределенная ссылка» при использовании GTK с CMake

Я пытаюсь создать базовый код GTK+ (один из его руководств) с помощью CMake, но я продолжаю получать «неопределенную ссылку на *», где * — любая функция GTK, которая есть в коде. Я пытался искать руководства/учебники по этому вопросу, но большинство из них в основном похожи на то, что у меня есть.

Обычная компиляция из терминала работает без проблем с помощью команды:

g++ ./test.cpp -o test `pkg-config --cflags --libs gtk+-3.0`

Когда я пытаюсь использовать CMake, мой CMakeLists.txt выглядит так:

cmake_minimum_required(VERSION 3.0.2)
project(gtktest)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)

include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
add_definitions(${GTK3_CFLAGS_OTHER})

add_executable(gtktest test.cpp)
target_link_libraries(gtktest ${GKT3_LIBRARIES})

Теперь cmake . вроде работает без проблем

cmake .
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Checking for module 'gtk+-3.0'
--   Found gtk+-3.0, version 3.22.30
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dfdark/Desktop/gtk test

Но сделать команду после этого проблема:

make
Scanning dependencies of target gtktest
[ 50%] Building CXX object CMakeFiles/gtktest.dir/test.cpp.o
[100%] Linking CXX executable gtktest
CMakeFiles/gtktest.dir/test.cpp.o: In function `activate(_GtkApplication*, void*)':
test.cpp:(.text+0x27): undefined reference to `gtk_application_window_new'
test.cpp:(.text+0x30): undefined reference to `gtk_window_get_type'
test.cpp:(.text+0x42): undefined reference to `g_type_check_instance_cast'
test.cpp:(.text+0x51): undefined reference to `gtk_window_set_title'
test.cpp:(.text+0x56): undefined reference to `gtk_window_get_type'
test.cpp:(.text+0x68): undefined reference to `g_type_check_instance_cast'
test.cpp:(.text+0x7a): undefined reference to `gtk_window_set_default_size'
test.cpp:(.text+0x86): undefined reference to `gtk_widget_show_all'
CMakeFiles/gtktest.dir/test.cpp.o: In function `main':
test.cpp:(.text+0xcc): undefined reference to `gtk_application_new'
test.cpp:(.text+0xfb): undefined reference to `g_signal_connect_data'
test.cpp:(.text+0x100): undefined reference to `g_application_get_type'
test.cpp:(.text+0x112): undefined reference to `g_type_check_instance_cast'
test.cpp:(.text+0x126): undefined reference to `g_application_run'
test.cpp:(.text+0x135): undefined reference to `g_object_unref'
collect2: error: ld returned 1 exit status
CMakeFiles/gtktest.dir/build.make:94: recipe for target 'gtktest' failed
make[2]: *** [gtktest] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/gtktest.dir/all' failed
make[1]: *** [CMakeFiles/gtktest.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

код test.cpp (из руководств по GTK+)

#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

Является ли проблема перепутанным порядком команд CMake?

Как указано в ответе комментарии, CMakeLists.txt содержит опечатку (GKT вместо GTK). С исправлением опечатки код правильный и работает. В Stack Overflow у нас, как правило, нет вопросов, которые можно решить, просто исправив опечатку.

Tsyvarev 31.05.2019 10:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
1 277
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте GTK в вашем CMakeLists.txt вместо GTK3:

cmake_minimum_required(VERSION 3.0.2)
project(gtktest)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED gtk+-3.0)

include_directories(${GTK_INCLUDE_DIRS})
link_directories(${GTK_LIBRARY_DIRS})
add_definitions(${GTK_CFLAGS_OTHER})

add_executable(gtktest test.cpp)
target_link_libraries(gtktest ${GTK_LIBRARIES})

Пытаясь ответить на ваш ответ, я заметил, что ошибся в target_link_libraries(gtktest ${GKT3_LIBRARIES}) (должно быть GTK3_LIBRARIES), что решило мою проблему. Есть ли разница между использованием GTK и GTK3? Я пробовал оба, и оба, кажется, работают.

DFDark 31.05.2019 04:25

Не уверен, должен ли я добавить свой ответ с исправлением или отметить ваш ответ как правильный. На данный момент я отметил это как правильное.

DFDark 31.05.2019 04:26

@DFDark Я бы использовал GKT_LIBRARIES, так как он находится в официальных документах cmake здесь: cmake.org/cmake/help/latest/module/FindGTK.html, а GKT3_LIBRARIES не так далеко, как я могу найти, поэтому он может быть удален позже.

user3147395 31.05.2019 04:55

В ответе та же опечатка - GKT вместо GTK как в вопросе. Первый параметр pkg_check_modules влияет только на имена переменных, которые будут установлены; использовать ли GTK или GTK3 — вопрос выбора. Модуль [FindGTK.cmake](cmake.org/cmake/help/latest/module/FindGTK.h‌​tml) представляет собой альтернативный путь для поиска GTK с использованием find_package(GTK) вместо pkg_check_modules.

Tsyvarev 31.05.2019 10:04

Другие вопросы по теме