C++ - static library built using GLFW won't link

I’m creating a static library for my game engine which is constructed using the following CMake script:

cmake_minimum_required(VERSION 3.10)
project(FaceEngine)

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

include_directories("../Lib/glad/include")
include_directories("../Lib/glfw-3.3.2/include")
include_directories("include")

file(GLOB SOURCES "src/*.cpp")
file(GLOB SOURCES "src/glad.c")
#file(GLOB SOURCES "../Lib/glfw-3.3.2/src/*.c")
#file(GLOB SOURCES "../Lib/glad/src/glad.c")

#add_subdirectory("src/glfw")

add_library(FaceEngine STATIC ${SOURCES})
#target_link_libraries(FaceEngine glfw)

I compile GLFW from source and link it according to its official guide. As you can see, I originally tried compiling GLFW and linking it inside of the static library.
This is the CMake script of the application I am trying to make use my static library:
cmake_minimum_required(VERSION 3.10)
project(FaceEngineTest)

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("glfw")

link_directories("../FaceEngine")

include_directories("../Lib/glad/include")
include_directories("../Lib/glfw-3.3.2/include")
include_directories("../FaceEngine/include")

file(GLOB SOURCES "./*.cpp")

add_executable(FaceEngineTest ${SOURCES})
target_link_libraries(FaceEngineTest glfw)
target_link_libraries(FaceEngineTest libFaceEngine.a)

When I attempt to use any feature of my engine it comes up with an undefined reference. The headers are properly referenced and VSCode recognises all the contents of my static library. However, I can still use all GLFW functions, and I can make a class that derives from a class from my engine:
class MyGame : public FaceEngine::Game
Why can my program use GLFW functions fine but not my own library?

Hi @silent_ptr welcome to the GLFW forums!

When asking compilation and link related questions it’s useful to mention the toolchain (clang, gcc or MS compiler etc.) and OS and also add the error lines from the compilation output. Without these it’s difficult to know the exact error.

In this case I think the problem is that you need to explicitly link FaceEngine to GLFW - you were doing this in the first script for FaceEngine but have commented it out.

Also you’re not using add_subdirectory("FaceEngine") to include the FaceEngine library cmake script. I would either use that approach or combine your two cmake scripts into one.

I’m using Ubuntu Desktop and GCC/G++. Since my post I’ve made my engine static library require GLFW, and then I make my application require my engine, which then compiles GLFW and then the static library, but I still get undefined references. These are my CMake scripts for the static library and application respectively:
cmake_minimum_required(VERSION 3.10)
project(FaceEngine)

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

include_directories("../Lib/glad/include")
include_directories("../Lib/glfw-3.3.2/include")
include_directories("include")

file(GLOB SOURCES "src/*.cpp" "src/glad.c")
#file(GLOB SOURCES "src/glad.c")

add_subdirectory("../Lib/glfw-3.3.2" "glfw-binaries")

add_library(FaceEngine STATIC ${SOURCES})
target_link_libraries(FaceEngine glfw)

Application:

cmake_minimum_required(VERSION 3.10)
project(FaceEngineTest)

add_subdirectory("../FaceEngine" "faceengine-binaries")

include_directories("../Lib/glad/include" "../Lib/glfw-3.3.2/include" "../FaceEngine/include")

file(GLOB SOURCES "./*.cpp")

add_executable(FaceEngineTest ${SOURCES})
target_link_libraries(FaceEngineTest FaceEngine)

I only get undefined reference errors to the members in my engine.

Could you post the compile/link output so I can see the errors?

[ 65%] Built target glfw
[ 92%] Built target FaceEngine
[ 96%] Linking CXX executable FaceEngineTest
/usr/bin/ld: faceengine-binaries/libFaceEngine.a(FaceEngine.cpp.o): in function `FaceEngine::Engine::RunGame(FaceEngine::Game*, int*)':
FaceEngine.cpp:(.text+0x35): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0x51): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0x61): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: faceengine-binaries/libFaceEngine.a(FaceEngine.cpp.o): in function `FaceEngine::Engine::ExitGame()':
FaceEngine.cpp:(.text+0xe1): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0xf1): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: faceengine-binaries/libFaceEngine.a(FaceEngine.cpp.o): in function `FaceEngine::Engine::GameThread(int*)':
FaceEngine.cpp:(.text+0x14d): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0x1a9): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x1b0): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x1c2): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x1ec): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0x1fd): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x245): undefined reference to `FaceEngine::Engine::running'
/usr/bin/ld: FaceEngine.cpp:(.text+0x256): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x275): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x27c): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x292): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: FaceEngine.cpp:(.text+0x299): undefined reference to `FaceEngine::Engine::GamePtr'
/usr/bin/ld: faceengine-binaries/libFaceEngine.a(FaceEngine.cpp.o):FaceEngine.cpp:(.text+0x2af): more undefined references to `FaceEngine::Engine::GamePtr' follow
/usr/bin/ld: faceengine-binaries/libFaceEngine.a(FaceEngine.cpp.o): in function `FaceEngine::Engine::GameThread(int*)':
FaceEngine.cpp:(.text+0x313): undefined reference to `FaceEngine::Engine::running'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/FaceEngineTest.dir/build.make:89: FaceEngineTest] Error 1
make[1]: *** [CMakeFiles/Makefile2:136: CMakeFiles/FaceEngineTest.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

It looks like your code for FaceEngine is not compiled/linked to all the required source / libraries.

So ${SOURCES} in project FaceEngine cmake file is probably missing the source which defines FaceEngine::Engine::running and FaceEngine::Engine::GamePtr.

Those are variables in a class in a header file. They are definitely defined. The source includes FaceEngine.cpp, which #include’s FaceEngine.h, which defines the classes with those members.

The variables were static and I wasn’t declaring them in the .cpp, so I’m gonna try it again now.

you should try:

target_link_libraries(FaceEngine PUBLIC glfw)

also you should use cmake --build <build_dir> -v so if cmake is in verbose we should see the full link command used…