Bjørn Moholt
Bjørn Moholt

Reputation: 488

How to link the right libraries with GLFW as an external project in cmake?

I'm including glfw like this:

ExternalProject_Add(glfw-external
  URL https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip
  PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glfw
  INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/install
  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)

add_dependencies(ShittyLife glfw-external)

if(UNIX)
  set(GLFW_LIB <What to put here?> libglfw3.a)
else()
  set(GLFW_LIB ${install_dir}/lib/glfw3.lib)
endif()

The libs are linked later using the GLFW_LIB variable.

It works great on windows, but on Linux I'm missing some libs. The glfw webpage has solutions for this, but none of them seem to be compatible with how ExternalProject_add.

Any idea on how I can figure out what the required libs are, preferably in a way that will work across different machines/distros?

In case it's helpful here's the error i get when trying to build:

Relevant bits:

/usr/bin/ld: /home/molion/Desktop/ShittyLife/build/install/lib/libglfw3.a(x11_window.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line

All of it:

[ 94%] Building CXX object CMakeFiles/ShittyLife.dir/src/main.cpp.o
[100%] Linking CXX executable ShittyLife
/usr/bin/ld: /home/molion/Desktop/ShittyLife/build/install/lib/libglfw3.a(x11_window.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
CMakeFiles/ShittyLife.dir/build.make:95: recipe for target 'ShittyLife' failed
make[2]: *** [ShittyLife] Error 1
CMakeFiles/Makefile2:68: recipe for target 'CMakeFiles/ShittyLife.dir/all' failed
make[1]: *** [CMakeFiles/ShittyLife.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

Upvotes: 0

Views: 3131

Answers (3)

Matthew
Matthew

Reputation: 850

This is one of my CMakeLists.txt that I have been using for a while. pretty simple you tell CMake where glfw3 is located so its CMake can do its job and then add glfw as a link library and give it the include directory. This is not much different than including GLFW in visual studio.

cmake_minimum_required(VERSION 3.7)
project(SkyGames)

set(CMAKE_CXX_STANDARD 14)

set(SOURCE_FILES main.cpp)
add_executable(SkyGames ${SOURCE_FILES})

###########################
# GLFW
###########################

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

add_subdirectory(${PROJECT_SOURCE_DIR}/Externals/GLFW3)

target_link_libraries(SkyGames glfw)
include_directories(SkyGames ${GLFW_INCLUDE_DIR})

###########################
# GLEW
###########################
add_definitions(-DGLEW_STATIC)
set(GLEW_ROOT_DIR ${PROJECT_SOURCE_DIR}/Externals/glew2s)
set(GLEW_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/Externals/glew2s/include)
set(GLEW_LIBRARY ${PROJECT_SOURCE_DIR}/Externals/glew2s/lib/Release/Win32/glew32s.lib)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIR})

##########################
# OPENGL
##########################

find_package(OpenGL REQUIRED)
target_link_libraries(SkyGames ${GLEW_LIBRARY} ${OPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})

Upvotes: 0

v1bri
v1bri

Reputation: 1428

If you are open to using a package manager to handle the dependency you might consider using Hunter to add GLFW to your project. Hunter is written in native CMake and already uses ExternalProject under the hood. However it's much easier to use imo.

There is a short (and sparse) documentation page. Basically your CMakeLists.txt will look something like the following...

# CMake version 3.0 or higher is required for the Hunter package manager.
cmake_minimum_required(VERSION 3.0)

# Include the Hunter package manager module.
include("cmake/HunterGate.cmake")

# Ensure a reproducible build by locking down the Hunter package versions.
HunterGate(
    URL "https://github.com/ruslo/hunter/archive/v0.19.77.tar.gz"
    SHA1 "8898dd07756c408c63c63add903c8600c4cf4c0e")

# Your project name here.
project(my_project_name)

# Tell Hunter which packages to pull in for our project.
hunter_add_package(glfw)
find_package(glfw3 REQUIRED)

# Link against your target.
target_link_libraries(my_target_name glfw)

The magic HunterGate line can be found with each new Hunter release. I recently published a codecast on Hunter that will help walk you through the steps if you get lost.

Upvotes: 1

Darklighter
Darklighter

Reputation: 2192

GLFW provides a CMake config-file package and you should therefore use find_package to find it.

But since this is only available after ExternalProject_Add was run and not at configure time, you have to create a super-project and add your own project as ExternalProject too, like so:

ExternalProject_Add(glfw-test
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    INSTALL_COMMAND ""
    CMAKE_CACHE_ARGS "-DCMAKE_PREFIX_PATH:STRING=${GLFW_INSTALL_PREFIX}/lib/cmake"
    DEPENDS glfw-external
)

with set(GLFW_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/glfw_install") and GLFW_INSTALL_PREFIX also used in GLFWs ExternalProject_Add.

You can then use

find_package(glfw3 REQUIRED)
find_package(OpenGL REQUIRED)

and

target_link_libraries(${PROJECT_NAME}
    glfw
    OpenGL::GL 
)

in your project.


Instead of using ExternalProject you can also follow the GLFW suggestion.

Upvotes: 5

Related Questions