0

So, I have a project with CMakeLists, the tree like the following:

proj dir:  
  --include
      window.h
      scene.h
      etc.  
  --src
      window.cpp
      scene.cpp
      main.cpp
      etc.
  --external
      --glad
      --SOIL
      --Catch2
  --tests
      CMakeLists.txt
      window_test.cpp
      main.cpp
 CMakeLists.txt

And I trying in tests root make project for unit tests using Catch2 lib. But when I'm trying build my unit_test proj get following errors:

Undefined symbols for architecture x86_64:
  "_glfwCreateWindow", referenced from:
      mlg::System::Window::create() in libSimplePaint.a(window.cpp.o)
  "_glfwInit", referenced from:
      mlg::System::Window::Window(int, int, char const*) in libSimplePaint.a(window.cpp.o)
  "_glfwMakeContextCurrent", referenced from:
      mlg::System::Window::create() in libSimplePaint.a(window.cpp.o)
  "_glfwSetFramebufferSizeCallback", referenced from:
      mlg::System::Window::setFramebufferSizeCallback() const in libSimplePaint.a(window.cpp.o)
  "_glfwTerminate", referenced from:
      mlg::System::Window::close() const in libSimplePaint.a(window.cpp.o)
      mlg::System::Window::create() in libSimplePaint.a(window.cpp.o)
  "_glfwWindowHint", referenced from:
      mlg::System::Window::Window(int, int, char const*) in libSimplePaint.a(window.cpp.o)
  "_glfwWindowShouldClose", referenced from:
      mlg::System::Window::isOpen() const in libSimplePaint.a(window.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [SimplePaint_UnitTests] Error 1
make[1]: *** [CMakeFiles/SimplePaint_UnitTests.dir/all] Error 2
make: *** [all] Error 2

project CMakeLists:

cmake_minimum_required(VERSION 3.11 FATAL_ERROR) 

project(SimplePaint)

set(CMAKE_CXX_FLAGS        "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo")

set(SRC_DIR     "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(LIBS_DIR    "${CMAKE_CURRENT_SOURCE_DIR}/external")
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
set(BUILD_DIR   "${CMAKE_CURRENT_SOURCE_DIR}/build")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIR}/bin")

file(GLOB SOURCES "${SRC_DIR}/*.cpp" "${SRC_DIR}/*.vert" "${SRC_DIR}/*.frag")
file(GLOB HEADERS "${INCLUDE_DIR}/*.h" "${INCLUDE_DIR}/*.hpp")

add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})

# SOIL
include_directories(${soil_lib})
set(SOIL_LIBRARY ${LIBS_DIR}/SOIL/libsoil.a)
target_link_libraries(${PROJECT_NAME} ${SOIL_LIBRARY})

# glad
set(GLAD_DIR "${LIBS_DIR}/glad")
add_library("GLAD" "${GLAD_DIR}/src/glad.c")
target_include_directories("GLAD" PRIVATE "${GLAD_DIR}/include")
target_include_directories(${PROJECT_NAME} PRIVATE "${GLAD_DIR}/include")
target_link_libraries(${PROJECT_NAME} "GLAD" "${CMAKE_DL_LIBS}")

unit tests CMakeLists:

cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

project(SimplePaint_UnitTests)
# This module will be used for downloading third party code.
include(ExternalProject)

set(THIRDPARTY "${CMAKE_CURRENT_SOURCE_DIR}/../external")

ExternalProject_Add(
    Catch2

    GIT_REPOSITORY      "https://github.com/catchorg/Catch2.git"
    GIT_TAG             "master"

    SOURCE_DIR          "${THIRDPARTY}/Catch2-master"

    # Don't update and patch.
    UPDATE_COMMAND      ""
    PATCH_COMMAND       ""

    # Don't configure and build.
    CONFIGURE_COMMAND   ""
    BUILD_COMMAND       ""

    # Don't test and install.
    TEST_COMMAND        ""
    INSTALL_COMMAND     "")


set(Catch2_INCLUDE_DIR "${THIRDPARTY}/Catch2-master/single_include")

ExternalProject_Add(
    GLM

    GIT_REPOSITORY      "https://github.com/g-truc/glm.git"
    GIT_TAG             "0.9.4.6"

    SOURCE_DIR          "${THIRDPARTY}/glm-0.9.4.6"

    # Don't update and patch.
    UPDATE_COMMAND      ""
    PATCH_COMMAND       ""

    # Don't configure and build.
    CONFIGURE_COMMAND   ""
    BUILD_COMMAND       ""

    # Don't test and install.
    TEST_COMMAND        ""
    INSTALL_COMMAND     "")

set(GLM_INCLUDE_DIRS "${THIRDPARTY}/glm-0.9.4.6")

add_library(SimplePaint STATIC

    "${THIRDPARTY}/glad/src/glad.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/../src/main.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/../src/window.cpp"
    )

target_include_directories(SimplePaint PUBLIC

    "${THIRDPARTY}/glad/include"
    "${CMAKE_CURRENT_SOURCE_DIR}/../include"
    "${CMAKE_CURRENT_SOURCE_DIR}/../src"
    "${GLM_INCLUDE_DIRS}"
    )

target_compile_features(SimplePaint PUBLIC cxx_std_17)

add_dependencies(SimplePaint GLM)

add_executable(${PROJECT_NAME}

    "${CMAKE_CURRENT_SOURCE_DIR}/window_test.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
    )

target_include_directories(${PROJECT_NAME} PRIVATE ${Catch2_INCLUDE_DIR})

target_link_libraries(${PROJECT_NAME} SimplePaint)

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND "$<TARGET_FILE:${PROJECT_NAME}>")

add_dependencies(${PROJECT_NAME} Catch2)

What I'm doing wrong? I including GLFW and glad like this:

#include <glad/glad.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

And if I building only my project without unit tests all working and building. Compiler Clang 10.0

adziri
  • 291
  • 3
  • 15
  • Like `-l` flag, `framework` one should also be passed to `target_link_libraries`, not to the `CMAKE_EXE_LINKER_FLAGS` variable. – Tsyvarev Nov 07 '18 at 15:21
  • @Tsyvarev, Sorry, I'm a bit bad in CMake commands, if it not hard for u, can u say where I make mistake? As I understand in `set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo")` ? – adziri Nov 07 '18 at 15:33
  • Yes, assigning `CMAKE_EXE_LINKER_FLAGS` is wrong in your case. You should use `target_link_libraries` command for link with a libraries. – Tsyvarev Nov 07 '18 at 15:37
  • @Tsyvarev, But why than all working when I building without unit tests? And as I understand I need use `target_link_libraries` for `-lglfw` command? Other may stay? – adziri Nov 07 '18 at 15:39
  • For **every** flag `-l` use `target_link_libraries( )`. For **every** flag `-framework ` use `target_link_libraries( -framework )`. – Tsyvarev Nov 07 '18 at 16:58
  • @Tsyvarev, have the same error with SOIL, I try linking it as u recomend with `find_library(SOIL NAMES soil PATH ${CMAKE_CURRENT_SOURCE_DIR}/../external/SOIL/libsoil.a NO_DEFAULT_PATH)` first and then `target_link_libraries(${PROJECT_NAME} glfw SimplePaint ${SOIL})` but have error: CMake Error: The following variables are used in this project, but they are set to NOTFOUND. Please set them or make sure they are set and tested correctly in the CMake files: SOIL linked by target "SimplePaint_UnitTests" in directory /Users/akukh/Documents/Projects/simple-paint/tests whats wrong? – adziri Nov 08 '18 at 15:41
  • Why you search the library (with `find_library`) when you already know the library's path? Simply use this path in `target_link_libraries` call. – Tsyvarev Nov 08 '18 at 15:52
  • @Tsyvarev, ty I change to `target_link_libraries(${PROJECT_NAME} glfw SimplePaint "${CMAKE_CURRENT_SOURCE_DIR}/../external/SOIL/libsoil.a")` but still have error `Undefined symbols for architecture x86_64: "_CFBundleCreate", referenced from: _query_DXT_capability in libsoil.a(SOIL.c.o) "_CFBundleGetFunctionPointerForName", referenced from: _query_DXT_capability in libsoil.a(SOIL.c.o) "_CFRelease", referenced from: _query_DXT_capability in libsoil.a(SOIL.c.o)` etc. – adziri Nov 08 '18 at 15:57
  • Read the error message carefully: it is about the symbols **used by** `libsoil.a` library itself. So you need to additionally link with a library which provides those symbols. Make sure to place this library **after** the `libsoil.a` in the `target_link_libraries` call. – Tsyvarev Nov 08 '18 at 16:04

0 Answers0