Skip to content

Instantly share code, notes, and snippets.

@fracek
Last active May 12, 2024 17:13
Show Gist options
  • Save fracek/3323924 to your computer and use it in GitHub Desktop.
Save fracek/3323924 to your computer and use it in GitHub Desktop.
CMake and GTK+ 3
# Thanks to @danger89 and @Ilothar for updating the gist.
# Set the name and the supported language of the project
project(hello-world C CXX)
# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 3.10)
# Use the package PkgConfig to detect GTK+ headers/library files
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED gtkmm-3.0)
add_executable(hello main.cpp)
target_link_libraries(hello PRIVATE ${GTKMM_LIBRARIES})
# Add other flags to the compiler
target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER})
# Setup CMake to use GTK+, tell the compiler where to look for headers
# and to the linker where to look for libraries
target_include_directories(hello PRIVATE ${GTKMM_INCLUDE_DIRS})
target_link_directories(hello PRIVATE ${GTKMM_LIBRARY_DIRS})
#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), "Hello GNOME");
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);
}
@fracek
Copy link
Author

fracek commented Apr 9, 2021

Is @Danger89 version working? I can update the gist to it.

@melroy89
Copy link

melroy89 commented Apr 9, 2021

@fracek Yes that is working, I'm using this myself on libreweb project:

https://gitlab.melroy.org/libreweb/browser/-/blob/master/src/CMakeLists.txt#L24

@llothar
Copy link

llothar commented Apr 9, 2021

Its working but it shouldn't be used anymore, this is old style and obsoleted for more than 10 years.


# Set the name and the supported language of the project
project(hello-world C CXX)

# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 3.10)

# Use the package PkgConfig to detect GTK+ headers/library files
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED gtkmm-3.0)


add_executable(hello main.cpp)
target_link_libraries(hello PRIVATE ${GTKMM_LIBRARIES})


# Add other flags to the compiler
target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER})


# Setup CMake to use GTK+, tell the compiler where to look for headers
# and to the linker where to look for libraries
target_include_directories(hello PRIVATE ${GTKMM_INCLUDE_DIRS})
target_link_directories(hello PRIVATE ${GTKMM_LIBRARY_DIRS})

@melroy89
Copy link

melroy89 commented Apr 9, 2021

Its working but it shouldn't be used anymore, this is old style and obsoleted for more than 10 years.


# Set the name and the supported language of the project
project(hello-world C CXX)

# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 3.10)

# Use the package PkgConfig to detect GTK+ headers/library files
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)


add_executable(hello main.cpp)
target_link_libraries(hello PRIVATE ${GTKMM_LIBRARIES})


# Add other flags to the compiler
target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER})


# Setup CMake to use GTK+, tell the compiler where to look for headers
# and to the linker where to look for libraries
target_include_directories(hello PRIVATE ${GTKMM_INCLUDE_DIRS})
target_link_directories(hello PRIVATE ${GTKMM_LIBRARY_DIRS})

I don't know what you are talking about. But what you quoted is the new way of doing it.

@llothar
Copy link

llothar commented Apr 9, 2021

Now in "modern" cmake everything is a target and all dependencies are either Private/Public/Interface. Compared to the old way you did it where everything was a put into global variables.

The Internet now shows the problem of coming of age and you still rank #1 for "gtk cmake example" on google. Thats why i suggest going modern. Thanks for changing it

@g0bel1n
Copy link

g0bel1n commented Nov 3, 2021

For gtkmm-3.0:

# Use the package PkgConfig to detect GTK+ headers/library files
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK REQUIRED gtkmm-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(${GTK_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK_LIBRARY_DIRS})

# Add other flags to the compiler
ADD_DEFINITIONS(${GTK_CFLAGS_OTHER})

add_executable(hello main.cpp)
TARGET_LINK_LIBRARIES(hello ${GTK_LIBRARIES})

That was the way it worked for me, changing every GTKMM to GTK !

@iSerge
Copy link

iSerge commented Dec 2, 2021

This instruction:
target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER})
results in -D-pthread flag on my machine which lead to failure during compilation.

target_compile_options(hello PRIVATE ${GTKMM_CFLAGS_OTHER})
produces correct result.

@melroy89
Copy link

melroy89 commented Dec 9, 2021

Now in "modern" cmake everything is a target and all dependencies are either Private/Public/Interface. Compared to the old way you did it where everything was a put into global variables.

Thank you for you remarks! I will change all the examples I have to target_.. specific calls, incl. making it PRIVATE.

I also edit/updated the comments above!

@fracek maybe check my comment again. Also your hello.c is not a C++ example, but a C example, which doesn't make sense. So either provide a C example and use GTK. Or provide a C++ example using C++ and Gtkmm.

@leiless
Copy link

leiless commented Jan 10, 2022

@melroy89
Copy link

melroy89 commented Jan 10, 2022

@melroy89
Copy link

melroy89 commented Jan 10, 2022

https://github.com/shlomif/gtk3-cmake-examples/blob/master/CMakeLists.txt

Again, as said earlier in this thread, please use:

target_include_directories(${PROJECT_TARGET} PRIVATE ${GTK_INCLUDE_DIRS})
target_link_directories(${PROJECT_TARGET} PRIVATE ${GTK_LIBRARY_DIRS})
target_compile_options(${PROJECT_TARGET} PRIVATE ${GTK_CFLAGS_OTHER})

instead (so with target_ prefix).

So DO NOT USE the following anymore:

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

@raulpy271
Copy link

The code:

target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER})

are breaking my compilation. Because it insert the flag -D-pthread, this generate the error:

error: macro names must be identifiers

@iSerge
Copy link

iSerge commented Jan 30, 2022

Like I said earlier in this thread. Should use target_compile_options(hello PRIVATE ${GTKMM_CFLAGS_OTHER}) instead.

@melroy89
Copy link

@Fabxx
Copy link

Fabxx commented Feb 2, 2022

I'm having a problem with these three lines, it says called with incorrect number of arguments:

target_include_directories(${PROJECT_TARGET} PRIVATE ${GTK_INCLUDE_DIRS})
target_link_directories(${PROJECT_TARGET} PRIVATE ${GTK_LIBRARY_DIRS})
target_compile_options(${PROJECT_TARGET}  ${GTK_CFLAGS_OTHER})

@melroy89
Copy link

melroy89 commented Feb 2, 2022

Did you set PROJECT_TARGET variable as your target name for your project? I mean this variable should be set by you.

@melroy89
Copy link

@fracek Please, fix your mistakes.

Can you change: pkg_check_modules(GTK REQUIRED gtkmm-3.0) to: pkg_check_modules(GTKMM REQUIRED gtkmm-3.0) in your snippet. Line 10.

And change target_compile_definitions(hello PRIVATE ${GTKMM_CFLAGS_OTHER}) to target_compile_options(hello PRIVATE ${GTKMM_CFLAGS_OTHER}). On line 18.

@melroy89
Copy link

melroy89 commented Feb 14, 2022

@revix-0 I think you should target_compile_options(${PROJECT_TARGET} ${GTK_CFLAGS_OTHER}) change to target_compile_options(${PROJECT_TARGET} PRIVATE ${GTK_CFLAGS_OTHER})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment