12

I'm having troubles with linking freetype 2 under linux using cmake when building a C++11 project with an extern C library.

With cmake and freetype 2 I basically have 2 options :

  • use the utility freetype-config like freetype-config --libs
  • use the FindFreetype cmake module

Now I'm trying to implement the second option and I'm not very skilled with cmake nor I understand the logic of it.

My problem is the linking phase, I have no idea how to do that properly plus this module is not as complete as the result of freetype-config --libs which really includes all the libraries and flags that I need, and not just the path of a file; so I'm assuming that I have to do the same for zlib and libpng.

CMakeLists.txt

cmake_minimum_required (VERSION 2.6)
project (FreetypeTutorials1)

include(FindFreetype)
include_directories(${FREETYPE_INCLUDE_DIRS})

SET(CMAKE_CXX_FLAGS "-O2 -std=c++11")

SET(CMAKE_EXE_LINKER_FLAGS "-v -lfreetype")

add_executable( demo "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp")

./src/main.cpp ( just some random code so I have something to feed to the compiler )

extern "C" {
#include <ft2build.h>
#include FT_FREETYPE_H
}
#include <iostream>
int main()
{
  FT_Library library;
  auto error = FT_Init_FreeType(&library);
  if (error)
  {
    std::cout << "An error !\n";
  }
}
user2485710
  • 9,451
  • 13
  • 58
  • 102

1 Answers1

18

To load a module like FindFreetype.cmake you need to use it in cmake with the find_package-command. The first argument is the package name. The "Find" of its corresponding filename is added automatically by cmake.

While include might work with find_package you can add some flags. For example, as shown below, REQUIRED, to make cmake fail when freetype wasn't found.

Additionally linking with cmake should be done with the command target_link_libraries.

This is how I would write you CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (FreetypeTutorials1)

find_package(Freetype REQUIRED)

SET(CMAKE_CXX_FLAGS "-O2 -std=c++11")

SET(CMAKE_EXE_LINKER_FLAGS "-v")

add_executable( demo src/main.cpp) # CMAKE_CURRENT_SOURCE_DIR is implicit here
target_link_libraries(demo ${FREETYPE_LIBRARIES})
target_include_directories(demo PRIVATE ${FREETYPE_INCLUDE_DIRS})

target_link_libraries is platform independent whereas '-lfreetype in CMAKE_EXE_LINKER_FLAGS is not.

The CMakeLists.txt will work on other platforms where freetype is available.

(Edit 2019: use target_include_directories() instead of include_directories()

Patrick B.
  • 11,773
  • 8
  • 58
  • 101
  • I need a complete example because this is my first time with this. – user2485710 May 27 '14 at 11:47
  • so using the `include(FindFreetype)` is wrong ? I also found out that `target_link_libraries(demo freetype)` works as well, there are any differences ? – user2485710 May 27 '14 at 13:43
  • so the difference is that if `include` fails there will be no message or interruption, and `include` is a really generic command. `find_package` is a more specific macro with more control and options. But the result in both cases is the inclusion of the package that I want ? I mean if you set aside the "controls" and the business logic for a minute, the effect is the same ? – user2485710 May 28 '14 at 07:46
  • 2
    Use `target_include_directories` with modern CMake (3.0+) to avoid polluting other projects with global flags. – Xeverous Dec 04 '19 at 20:31