0

My team is working on a super light-weight project written in C, where we want to render shapes and GUI elements using Xlib and Cairo. We're working with Kdevelop and thus depend on CMake, but none of us is really well acquainted with it. We managed to bind Xlib, but we just can't get Cairo up and running.

I included PkgConfig and we're importing Cairo with #include <cairo/cairo.h>. I also tried the following:

find_package(Cairo REQUIRED)
link_libraries(${Cairo_LIBRARIES})
include_directories(${Cairo_INCLUDE_DIR})

but it didn't work.

Our current CMake file:

cmake_minimum_required(VERSION 3.10)

project(SAGE VERSION 1.0)

set(BASEPATH "${SAGE_SOURCE_DIR}/src")
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SAGE_BINARY_DIR}/build)

file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "${BASEPATH}/*.c")
# Link X11 libraries
# Removing any of the following three lines results in an error
find_package(X11 REQUIRED)
link_libraries(${X11_LIBRARIES})
include_directories(${X11_INCLUDE_DIR})

add_executable(SAGE "${BASEPATH}/main.c" ${SOURCES})
aux_source_directory(dir src)
target_include_directories(SAGE PRIVATE "${BASEPATH}")

find_package(PkgConfig)
pkg_check_modules(Cairo REQUIRED cairo)
include_directories(${Cairo_INCLUDE_DIRS})
# include_directories(src)

When executing code we get the following error message in Kdevelop:

/usr/bin/ld: /home/luxdragon/Dokumente/GitHub/SAGE/src/main.c:134: undefined reference to `cairo_new_path'
/usr/bin/ld: /home/luxdragon/Dokumente/GitHub/SAGE/src/main.c:135: undefined reference to `cairo_translate'
/usr/bin/ld: /home/luxdragon/Dokumente/GitHub/SAGE/src/main.c:138: undefined reference to `cairo_fill'
/usr/bin/ld: /home/luxdragon/Dokumente/GitHub/SAGE/src/main.c:140: undefined reference to `cairo_stroke'

How do we integrate Cairo into CMake? Note that Xlib works flawlessly. Any help would be greatly appreciated.

EDIT I tried the following: I put message("Cairo libs: '${Cairo_LIBRARIES}'") after pkg_check_modules(Cairo REQUIRED cairo). I also added:

target_link_libraries(SAGE PUBLIC 
    PkgConfig::Cairo)

The output is as follows:

Cairo libs: 'cairo'
-- Configuring done
CMake Error at CMakeLists.txt:23 (target_link_libraries):
  Target "SAGE" links to:

    PkgConfig::Cairo

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.

NEW EDIT I changed

pkg_check_modules(Cairo REQUIRED cairo)

to

pkg_check_modules(Cairo REQUIRED IMPORTED_TARGET cairo)

and when running cmake -S . no error message is returned. This looks good:

-- Checking for module 'cairo'
--   Found cairo, version 1.17.6
Cairo libs: 'cairo'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/luxdragon/Dokumente/SAGE

LAST EDIT and it works in Kdevelop now!

  • There is no linking to Cairo in the code you posted. Also post the output of `message("Cairo libs: '${Cairo_LIBRARIES}'")` (put it after `pkg_check_modules(Cairo REQUIRED cairo)`) – ixSci Apr 23 '22 at 10:24
  • After `find_package(PkgConfig)` call you forgot to **link libraries** it provides. In CMake linking is performed with `target_link_libraries`. See duplicate question for more details. – Tsyvarev Apr 23 '22 at 10:26
  • @Tsyvarev they claim to have tried linking, check the top of the quesion. – ixSci Apr 23 '22 at 10:27
  • @ixSci: "it didn't work" is too vague verdict of trying. E.g. it could mean that `link_libraries` doesn't affect on the target created **before** it. And approach to search the Cairo using `find_package(Cairo REQUIRED)` differs from the one which uses `pkg_check_modules(Cairo REQUIRED cairo)`. – Tsyvarev Apr 23 '22 at 10:35
  • 1
    @Tsyvarev yeah, the question needs more details. That I don't argue with. – ixSci Apr 23 '22 at 10:36
  • @ixSci the output is:`Cairo libs: 'cairo' -- Configuring done CMake Error at CMakeLists.txt:23 (target_link_libraries): Target "SAGE" links to: PkgConfig::Cairo but the target was not found. Possible reasons include: * There is a typo in the target name. * A find_package call is missing for an IMPORTED target. * An ALIAS target is missing.` –  Apr 23 '22 at 11:06
  • @Tsyvarev with `target_link_libraries(SAGE PUBLIC PkgConfig::Cairo)` the error doesn't go away. –  Apr 23 '22 at 11:08
  • @Luxdragon: Please, update the **question post** with your **fair attempt**: the exact code and the exact error message it causes. Attempts which obviously misses function's calls noted in the guides are not useful. – Tsyvarev Apr 23 '22 at 11:15
  • @Tsyvarev will do! –  Apr 23 '22 at 11:29
  • Imported targets (like `PkgConfig::Cairo`) are available only if `pkg_check_modules` is called with `IMPORTED_TARGET` keyword. – Tsyvarev Apr 23 '22 at 11:35
  • @Tsyvarev this fixed the previous error message when running `cmake -S .` but I still can't run the code in Kdevelop –  Apr 23 '22 at 11:40
  • Note on the line `-- Build files have been written to: /home/luxdragon/Dokumente/SAGE`. It tells that build files are generated NOT under `/home/luxdragon/Dokumente/SAGE/build` directory where you attempt to run `ninja`. Note, that CMake silently ignores specification of build directory if previously you have performed an *in-source* build. In that case, for allow **out-of-source** builds again you need to remove `CMakeCache.txt` (not a `CMakeLists.txt` !!) from the source directory. – Tsyvarev Apr 23 '22 at 11:51
  • @Tsyvarev just fixed the issue, the `IMPORTED_TARGET` was enough - I just accidentally edited the CMake file of another branch and it's no surprise Kdevelop didn't work - but now everything is fine. Thanks for your help! –  Apr 23 '22 at 13:26

0 Answers0