I'm struggling with properly setting up my CMake project. I've been trying to fix this error for the past 2 days. I'm currently learning CMake so please, pardon a "nooby" question.
I have a library, let's call it "InternalLibrary" and an executable project, called "App". InternalLibrary uses a static library, let's call it "ExternalLibrary". Since I want to actively test InternalLibrary while developing it, I setup a multi-directory project.
Here's how directory structure looks like:
Root
├───App
│ └───src/
└───InternalLibrary
├───include/
├───Libs/
│ └───ExternalLibrary/
│ ├───include/
│ └───lib/
└───src/
Here's root's CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(LibraryProject)
add_subdirectory(InternalLibrary)
add_subdirectory(App)
InternalLibrary's CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(InternalLibrary)
set(CMAKE_CXX_STANDARD 17)
add_library(InternalLibrary STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/internallibrary.cpp)
target_include_directories(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Libs/ExternalLibrary/include)
target_include_directories(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Libs/ExternalLibrary/lib/ExternalLibrary)
App's CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(App)
set(CMAKE_CXX_STANDARD 17)
add_executable(App ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
target_link_libraries(App InternalLibrary)
And as you can see, because InternalLibrary uses ExternalLibrary, when compiling there's an error:
No rule to make target 'DIRECTORY/Root/InternalLibrary/Libs/ExternalLibrary/lib/ExternalLibrary', needed by 'App/App.exe'. Stop.
There's no error when compiling InternalLibrary alone, so there's probably some thing I need to add in my App's CMakeLists.txt to tell CMake to include that ExternalLibrary used by InternalLibrary.
CodePudding user response:
The parameters passed to the target_link_library
command as any parameter other than the first one can be:
- A library target name
- A full path to a library file
- A plain library name
- [other stuff for different use cases]
Given the parameter you're passing in
target_link_libraries(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Libs/ExternalLibrary/lib/ExternalLibrary)
you're closest to the "a full path to a library file" case, but ExternalLibrary
is not the name of the library, at least not for any common library type I know of. Possible file names could be e.g. (depending on the lib type and OS)
libExternalLibrary.so
libExternalLibrary.a
ExternalLibrary.lib
You could use the appropriate file name here.
# may need to be adjusted depending on the exact lib file name
target_link_libraries(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Libs/ExternalLibrary/lib/libExternalLibrary.so)
Alternatively you could specify a link directory and use the "A plain library name" option:
# add directory to search for libs
target_link_directories(InternalLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Libs/ExternalLibrary/lib)
# would find e.g. libExtenalLibrary.so in .../Libs/ExternalLibrary/lib
target_link_libraries(InternalLibrary PUBLIC ExternalLibrary)