Compiling freetype2 as a dependency in my cmake project

1.2k views Asked by At

I'm trying to compile freetype2 from source and link it in my own project, but I'm running into a CMake error:

CMake Error: install(EXPORT "freetype-targets" ...) includes target "freetype" which requires target "zlib" that is not in any export set.

Presumably, this means that zlib is not recognizable to the freetype2 target.

I am compiling and using zlib in this project for other things (libpng, specifically), so am I correct in assuming that I simply need to somehow make my compiled zlib available to freetype2? How would I go about doing this?

Here is the entirety of my CMakeLists.txt:

cmake_minimum_required(VERSION 3.17)
project(zgl)

set(CMAKE_CXX_STANDARD 17)

set(SKIP_INSTALL_EXPORT TRUE)

# If this is built standalone, and not part of an embedded project, define the build directory.
string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} IS_ROOT_PROJECT)

if(IS_ROOT_PROJECT)
    if(NOT DEFINED DEPS_INSTALL_PREFIX)
        set(DEPS_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/build" CACHE STRING "Installation Prefix" FORCE)
    endif()
    get_property(CMAKE_INSTALL_PREFIX_DOCS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY CMAKE_INSTALL_PREFIX FULL_DOCS)
    set(CMAKE_INSTALL_PREFIX ${DEPS_INSTALL_PREFIX} CACHE STRING "${CMAKE_INSTALL_PREFIX_DOCS}" FORCE)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
    set(CMAKE_PDB_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
endif()

set(THIRD_PARTY_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third-party)

set(ZLIB_DIRECTORY ${THIRD_PARTY_DIRECTORY}/zlib)
add_subdirectory(${ZLIB_DIRECTORY})

# Explicitly set the ZLIB_BUILD_DIRECTORY for libpng (?)
get_directory_property(ZLIB_BUILD_DIRECTORY DIRECTORY ${ZLIB_DIRECTORY} DEFINITION CMAKE_CURRENT_BINARY_DIR)

option(PNG_LINK_ZLIB_STATIC "Use a static zlib library for libpng builds" OFF)

get_directory_property(zlib DIRECTORY ${ZLIB_DIRECTORY} DEFINITION zlib)
get_directory_property(zlibstatic DIRECTORY ${ZLIB_DIRECTORY} DEFINITION zlibstatic)

if (PNG_LINK_ZLIB_STATIC)
    set(ZLIB_LIBRARY zlibstatic)
else()
    set(ZLIB_LIBRARY zlib)
endif()

set(ZLIB_INCLUDE_DIR ${ZLIB_DIRECTORY})
set(LIBPNG_DIRECTORY "${THIRD_PARTY_DIRECTORY}/libpng")

if (WIN32)
    file(TO_NATIVE_PATH ${LIBPNG_DIRECTORY}/scripts/pnglibconf.h.prebuilt PNGLIBCONF_PATH_SRC)
    file(TO_NATIVE_PATH ${LIBPNG_DIRECTORY}/pnglibconf.h PNGLIBCONF_PATH_DST)
    execute_process(COMMAND cmd /c copy ${PNGLIBCONF_PATH_SRC} ${PNGLIBCONF_PATH_DST})
endif(WIN32)

include_directories(${ZLIB_DIRECTORY} ${ZLIB_BUILD_DIRECTORY} ${LIBPNG_DIRECTORY} ${LIBPNG_BUILD_DIRECTORY})
add_subdirectory(${LIBPNG_DIRECTORY})

get_directory_property(LIBPNG_BUILD_DIRECTORY DIRECTORY ${LIBPNG_DIRECTORY} DEFINITION CMAKE_CURRENT_BINARY_DIR)
get_directory_property(LIBPNG_STATIC DIRECTORY ${LIBPNG_DIRECTORY} DEFINITION PNG_LIB_NAME_STATIC)
get_directory_property(LIBPNG_SHARED DIRECTORY ${LIBPNG_DIRECTORY} DEFINITION PNG_LIB_NAME)

add_executable(zgl src/main.cpp src/resources/images/Image.cpp src/Game.cpp src/Game.h src/platform/Platform.cpp src/platform/Platform.h src/platform/Window.cpp src/platform/Window.h src/components/GameComponent.cpp src/components/GameComponent.h src/input/InputEvent.h src/input/Joystick.cpp src/input/Joystick.h src/utilities/StringUtilities.cpp src/utilities/StringUtilities.h src/input/InputEvent.cpp src/Actor.cpp src/Actor.h src/Scene.cpp src/Scene.h src/math/Range.h src/components/CameraComponent.cpp src/components/CameraComponent.h src/components/GameComponentCollection.h src/FreeCamera.cpp src/FreeCamera.h src/input/InputManager.cpp src/input/InputManager.h src/math/Rectangle.h src/input/InputSubscription.cpp src/input/InputSubscription.h src/Application.cpp src/Application.h src/math/Interpolation.h src/graphics/Texture.cpp src/graphics/Texture.h src/graphics/Gpu.cpp src/graphics/Gpu.h src/graphics/ColorType.h src/graphics/TextureFormat.h src/input/InputSubscriber.cpp src/input/InputSubscriber.h src/graphics/ColorType.cpp src/resources/images/formats/ImageFormatPng.cpp src/resources/images/formats/ImageFormatPng.h src/resources/ResourceManager.cpp src/resources/ResourceManager.h src/resources/images/formats/ImageFormat.cpp src/resources/images/formats/ImageFormat.h src/resources/Resource.cpp src/resources/Resource.h src/graphics/FrameBuffer.cpp src/graphics/FrameBuffer.h src/graphics/GpuTypes.h src/graphics/GpuProgram.cpp src/graphics/GpuProgram.h src/input/joysticks/XboxController.h src/input/InputAction.cpp src/input/InputAction.h src/utilities/FlagMacros.h src/input/Pointer.cpp src/input/Pointer.h src/input/Keyboard.cpp src/input/Keyboard.h src/input/KeyboardKey.cpp src/input/KeyboardKey.h src/components/FreeCameraControllerComponent.cpp src/components/FreeCameraControllerComponent.h src/components/GameComponentRegistry.cpp src/components/GameComponentRegistry.h src/platform/Cursor.cpp src/platform/Cursor.h src/graphics/GpuBuffer.cpp src/graphics/GpuBuffer.h src/graphics/GpuIndexBuffer.h src/components/MeshComponent.cpp src/components/MeshComponent.h src/graphics/GpuVertexBuffer.h src/resources/mesh/Mesh.cpp src/resources/mesh/Mesh.h src/ActorDefinition.cpp src/ActorDefinition.h src/graphics/CameraParameters.h)

# Compiling GLEW requires CYGWIN to be installed on Windows!

#glew
set(GLEW_DIRECTORY "${THIRD_PARTY_DIRECTORY}/glew-cmake")
message("${GLEW_DIRECTORY}")
add_subdirectory(${GLEW_DIRECTORY})
include_directories(${GLEW_DIRECTORY}/include)
target_link_libraries(zgl libglew_static)

#glfw
set(GLFW_DIRECTORY "${THIRD_PARTY_DIRECTORY}/glfw")
add_subdirectory(${GLFW_DIRECTORY})
include_directories(${GLFW_DIRECTORY}/include)

#opengl
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS})

#freetype
set(FREETYPE_DIRECTORY "${THIRD_PARTY_DIRECTORY}/freetype2")
add_subdirectory(${FREETYPE_DIRECTORY})
include_directories(${FREETYPE_DIRECTORY}/include)

#glm
set(GLM_DIRECTORY "${THIRD_PARTY_DIRECTORY}/glm")
include_directories(${GLM_DIRECTORY})

#yaml-cpp
set(YAML_DIRECTORY "${THIRD_PARTY_DIRECTORY}/yaml-cpp")
add_subdirectory(${YAML_DIRECTORY})
set(YAML_LIBRARIES yaml-cpp)
include_directories(${YAML_DIRECTORY}/include)

#magic_enum
set(MAGIC_ENUM_DIRECTORY "${THIRD_PARTY_DIRECTORY}/magic_enum")
include_directories(${MAGIC_ENUM_DIRECTORY}/include)

#zgl
set(ZGL_SRC_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src")
include_directories(${ZGL_SRC_DIRECTORY})

target_link_libraries(zgl ${OPENGL_LIBRARIES})
target_link_libraries(zgl ${ZLIB_LIBRARY})
target_link_libraries(zgl ${FREETYPE_LIBRARY})
target_link_libraries(zgl ${LIBPNG_STATIC})
target_link_libraries(zgl glfw ${GLFW_LIBRARIES})
target_link_libraries(zgl ${BULLET3_LIRRARIES})
target_link_libraries(zgl ${YAML_LIBRARIES})

target_include_directories(zgl PUBLIC ${ZLIB_DIRECTORY})
target_include_directories(zgl PUBLIC ${LIBPNG_DIRECTORY})
1

There are 1 answers

1
Tsyvarev On

The error message

CMake Error: install(EXPORT "freetype-targets" ...) includes target "freetype" which requires target "zlib" that is not in any export set.

refers to lines

  install(
    TARGETS freetype
      EXPORT freetype-targets
      <...>)

in the freetype2's CMakeLists.txt.

These lines mark freetype target for installation and add this target to the export set, so that installation could be found via find_package.

The target freetype is linked with the target zlib because you specify

set(ZLIB_LIBRARY zlib)

And here the problem CMake points to:

while zlib target is installed, it is part of none export sets.

Because of that CMake doesn't know how to translate linkage of freetype with zlib after they are installed, so CMake is unable to generate config file for freetype installation.

For overcome the error, you may tell CMake to link freetype with ALIAS library instead:

add_library(ZLIB::ZLIB ALIAS zlib)
set(ZLIB_LIBRARY ZLIB::ZLIB)

CMake knows that ALIAS targets are never installed, and won't emit an error.


Note, that while with ALIAS target the error will be gone, find_package still won't work for the installed freetype2. But otherwise the installation will be correct and usable.