13

I am trying to include SFML sources in my project. My directories are laid out like this:

main
  SFML (subtree synced with the official git repo)
  src
    <various modules>
    General (here lies the binary)

From the main level I am adding SFML subdirectory first and then src. As I've seen looking at the build log, this produces libraries:

sfml‑system
sfml‑window
sfml‑network
sfml‑graphics
sfml‑audio
sfml‑main

Now I want to link them to my binary in the General directory like this:

add_executable(main ${main_SRCS})
target_link_libraries (main
  sfml‑system
  sfml‑window
  sfml‑network
  sfml‑graphics
  sfml‑audio
  sfml‑main
  # Other stuff here
)

But I get:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑system
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑window
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑network
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑graphics
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑audio
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lsfml‑main

Why does CMake try to use system libraries instead of those it just built and how do I fix this?

Tommalla
  • 297
  • 1
  • 2
  • 10
  • Are those libraries targets of the same CMake project? If so, is `sfml‑system` etc. the actual name of the target? – Baum mit Augen May 04 '15 at 13:11
  • The top-level CMakeLists does: `add_subdirectory(SFML) add_subdirectory(src)` I can see the library names on the build log: `Linking CXX shared library ../../../lib/libsfml-graphics.so` etc. – Tommalla May 04 '15 at 13:12
  • @BaummitAugen I just realized that the SFML subdirectory defines its own project. I guess that answers your question and changes things for me somehow? – Tommalla May 04 '15 at 13:48
  • If `sfml-system` is no known target in the current CMake-File, you obviously cannot say *"Link to that target!"*. You can add additional link directories (i.e. directories to search for libs in) though, see e.g. http://www.cmake.org/pipermail/cmake/2011-May/044295.html – Baum mit Augen May 04 '15 at 13:53
  • @BaummitAugen I don't know why your link says not to use `link_directories`, but an easy answer to this question is "use `link_directories(`". OP should express the path as `${CMAKE_BUILD_DIR}/buildSubDirectory` – Antonio May 04 '15 at 19:34
  • @Antonio I don't know either. For all I know, `link_directories` is fine. But maybe one should doublecheck if there are pitfalls I can't think of right now. – Baum mit Augen May 04 '15 at 20:52
  • @BaummitAugen It's a 4 year old post, could be there were pitfalls at the time. – Antonio May 05 '15 at 08:08
  • @BaummitAugen @Antonio The advice from that post is still valid. Giving relative paths to `target_link_libraries` is fragile and can break in subtle and unexpected ways. Always prefer `find_library` + absolute paths to `target_link_libraries`. – ComicSansMS May 05 '15 at 08:41

1 Answers1

14

This should just work.

Tried the following with Visual Studio generator on Windows and Makefile generator on Linux on CMake 3.2:

cmake_minimum_required(VERSION 2.8)

project(test)

add_subdirectory(SFML-2.2)

add_executable(foo bar.cpp)
target_link_libraries(foo sfml-system)

SFML is built correctly and foo links correctly to sfml-system.

The fact that you build your executable from another subdirectory should not have an impact here.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
  • 1
    Your answer is correct, but for some reason does not work in my project (works in a dummy project however). For that reason I am choosing it as the accepted answer. – Tommalla May 05 '15 at 12:35
  • 2
    In the current CMake the order between `add_subdirectory` call, which creates target `sfml-system`, and `target_link_libraries` call, which links **with** that target, does NOT matter: Even if you reorder these calls, CMake still correctly determines, that `sfml-system` is a target, not a plain file. However, the order between `add_executable` call, which creates `foo` target, and `target_link_libraries` call, which links this target **to** others, DOES matter. With reverted order CMake will emit an error. – Tsyvarev Sep 08 '20 at 08:06