Skip to content

Instantly share code, notes, and snippets.

@fracek
Last active August 12, 2023 13:52
Show Gist options
  • Star 78 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • 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);
}
@WaltWilliams
Copy link

Most excellent. This worked.
Thanks.

@SY-HHK
Copy link

SY-HHK commented Feb 4, 2020

ty

@Medghofran
Copy link

it worked for me as well, thank you so much !

@mulderp
Copy link

mulderp commented Mar 21, 2020

thanks, that is a nice quick start. Also working with OpenSuse I found the gtk3-devel package helpful see a full list here https://de.opensuse.org/GTK%2B-Entwicklung

@gp42
Copy link

gp42 commented Apr 26, 2020

thx :)

@x0rld
Copy link

x0rld commented May 11, 2020

for people on linux you must add set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -rdynamic") to make work the signals for functions

@leomorpho
Copy link

leomorpho commented May 22, 2020

Thank you! That worked on macos with the brew version!

@hykilpikonna
Copy link

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

@Honghe
Copy link

Honghe commented Feb 24, 2021

Don't forget sudo apt install libgtk-3-dev

@triplejam
Copy link

@hykilpikonna thanks

@melroy89
Copy link

melroy89 commented Apr 4, 2021

For gtkmm-3.0:
...

I think it should be now:

project(test-app C CXX)

set(PROJECT_TARGET test_app)

# Use the package PkgConfig to detect Gtkmm headers/library/include folders
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)

set(SOURCES 
  main.cpp
)

# Create the executable
add_executable(${PROJECT_TARGET} ${SOURCES})
target_link_libraries(${PROJECT_TARGET} PRIVATE ${GTKMM_LIBRARIES})

# Add include and library directories, tell the compiler where to look for headers
# and to the linker where to look for libraries
target_include_directories(${PROJECT_TARGET} PRIVATE ${GTKMM_INCLUDE_DIRS})
target_link_directories(${PROJECT_TARGET} PRIVATE ${GTKMM_LIBRARY_DIRS})
target_compile_options(${PROJECT_TARGET} PRIVATE ${GTKMM_CFLAGS_OTHER})

@llothar
Copy link

llothar commented Apr 9, 2021

Please for god sake, update this example to modern CMake.

Its one of the top lists when you google "Gtk CMakeLists.txt" but its 9 years old.

@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