1

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

Vinograd
  • 29
  • 6
  • 1
    Your library is called `arcade-lib` but you want to link `arcade-games-lib`. – Friedrich Aug 17 '23 at 11:00
  • 1
    It happens. Sometimes you need another person to take a look at your code. – Friedrich Aug 17 '23 at 11:02
  • 1
    Collecting sources with `GLOB` is a known anti-pattern. – Botje Aug 17 '23 at 11:04
  • Can you please give me some advice on how to do it better? I'm very, very bad at the moment with CMake. – Vinograd Aug 17 '23 at 11:14
  • You could just put the file names there: `add_library(arcade-lib STATIC src/foo.cpp src/bar.cpp ...)` – Friedrich Aug 17 '23 at 11:16
  • Okay. Thanks. And if I may, I will ask the last question. Why if I make a SHARED library, then nothing will work? There will be errors about multiple redefinitions of functions. And I can’t delete the SFML library anywhere, because there will be errors that headers were not found. And I would like to actually make a SHARED library. This is the last question honestly – Vinograd Aug 17 '23 at 11:21
  • I posted an answer to address some of the issues. You can ask as many questions as you like, just use the "Ask Question" button at the top right of the page :-) Make sure to include the full error message you get. You probably link the sfml libs twice (once in the lib and once in the exe) but that's just a guess. – Friedrich Aug 17 '23 at 11:31

1 Answers1

3

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)
Friedrich
  • 2,011
  • 2
  • 17
  • 19