Issue
I am trying to create a CMake project with 2 targets. One of them must be a library and the other an executable. But when I try to build the executable, I get an error saying that the library could not be found.
Library CMake:
file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp)
set(HEADERS include)
add_library(arcade-lib STATIC ${SOURCES})
target_include_directories(arcade-lib PUBLIC ${HEADERS})
target_link_libraries(arcade-lib PRIVATE sfml-window sfml-graphics)
executable CMake:
file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp)
set(INCLUDE include)
set(ARCADE_GAMES_LIB_INCLUDE ../arcade-games-lib/include)
add_executable(snake-game snake-game.cpp ${SOURCES})
target_link_libraries(snake-game PRIVATE arcade-games-lib sfml-graphics sfml-window sfml-system sfml-main )
target_include_directories(snake-game PRIVATE ${INCLUDE} ${ARCADE_GAMES_LIB_INCLUDE})
main CMake:
cmake_minimum_required(VERSION 3.25)
project(arcade_games)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc")
set(SFML_STATIC_LIBRARIES TRUE)
find_package(SFML 2.5 COMPONENTS graphics window system REQUIRED)
add_subdirectory(arcade-games-lib)
add_subdirectory(snake-game)
Error message:
C:\Program Files\JetBrains\CLion 2022.3.2\bin\mingw\bin/ld.exe: cannot find -larcade-games-lib
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
I don't even know what to do, because everything looks right. I expected that an executable file would be built that would include my library
Solution
The problem, as pointed out in the comments, was that the names of the library in add_library
and target_link_libraries
need to match.
Using file(GLOB
to collect source files is problematic as pointed out by @Botje and in Why is cmake file GLOB evil?
I took the liberty of removing some bloat from your CMakeLists.txt:
Library CMake:
add_library(arcade-lib STATIC
src/foo.cpp
src/bar.cpp
include/my_header.h # the compiler will work without it but headers may not show up in IDEs
)
target_include_directories(arcade-lib PUBLIC include) # no need for a variable, just use relative path
target_link_libraries(arcade-lib PRIVATE sfml-window sfml-graphics)
Executable CMake:
# no need for ARCADE_GAMES_LIB_INCLUDE once you specify the right library name
add_executable(snake-game
snake-game.cpp
src/more_snake.cpp
)
# use the same library name you used in add_library:
target_link_libraries(snake-game PRIVATE arcade-lib sfml-graphics sfml-window sfml-system sfml-main)
target_include_directories(snake-game PRIVATE include)
Answered By - Friedrich Answer Checked By - Gilberto Lyons (WPSolving Admin)