4

I have a Project with the following folder structure

/
 |- build
 |- MyLib1
 |  |- source
 |  |  |- lib1_s1.cpp
 |  |  |- lib2_s2.cpp
 |  |- include
 |  |  |- lib1_s1.hpp
 |  |  |- lib2_s2.hpp
 |  |- CMakeLists.txt
 |- app
 |  |- source
 |  |  |- app_s1.cpp
 |  |  |- app_s2.cpp
 |  |- include
 |  |  |- app_s1.hpp
 |  |  |- app_s2.hpp
 |  |- CMakeLists.txt
 |
 |- CMakeLists.txt

My app depends on MyLib1 (compiled as a static library). lib1/CMakeLists.txt is as follows:

add_library(MyLib1 STATIC ${LIB_SRC})
install(TARGETS MyLib1 DESTINATION ${CMAKE_SOURCE_DIR}/bin)

And my app/CMakeLists.txt is as follows:

add_executable(app ${APP_SRC}/main.cpp)
target_link_libraries(app ${CMAKE_SOURCE_DIR}/bin/libMyLib1.a )
install(TARGETS app DESTINATION ${CMAKE_SOURCE_DIR}/bin)

In my build folder, I call cmake which builds MyLib1 successfully, but doesn't install it. The error generated is:

make[2]: *** No rule to make target `../bin/libMyLib1.a', needed by`/app'.  Stop.

My Cmake version is:

cmake version 3.11.0-rc3

CMake suite maintained and supported by Kitware (kitware.com/cmake).

I've already seen a few answers on stack overflow with the most relevant being this. But, the proposed solution doesn't seem to solve my problem.

What could I do differently to resolve the issue?

newkid
  • 1,368
  • 1
  • 11
  • 27
  • What happens if you simply put `target_link_libraries(app MyLib1 )` in the linkage of `app` instead of using the relative location of your lib? Notice that using the lib's name directly will make this build non-portable, which is one of CMake strengths. – Henrique Jung Apr 17 '18 at 23:17
  • 1
    @Henrique, that works! I also found the same suggestions [here](https://stackoverflow.com/questions/33599583/no-rule-to-make-target-with-internal-static-library). See comment1. – newkid Apr 17 '18 at 23:57
  • Cool. I'll submit as an answer then. – Henrique Jung Apr 18 '18 at 00:58

1 Answers1

3

Instead of linking your program directly with a .a file, you should use the CMake target instead.

So this

target_link_libraries(app ${CMAKE_SOURCE_DIR}/bin/libMyLib1.a)

Becomes this

target_link_libraries(app MyLib1)

MyLib1 being the name you used on your add_library command. This way CMake will generate the build files (e.g. makefiles) that orchestrate your build process in the correct order of dependencies on parallel builds (MyLib1 always before app). I think the install command is no longer necessary.

Notice that using CMake target names is the most correct way, since CMake strength is to generate cross-platform build files. If you use a hardcoded reference to a .a file, you're restricting the generated build scripts to compilers that generate static libraries in this format.

Henrique Jung
  • 1,408
  • 1
  • 15
  • 23