Issue
I am trying to include a project within a project. The relevant structure is as such:
projectA
/CMakeLists.txt (PA1)
/src
/main.cpp
/req/projectB
/CMakeLists.txt (PB1)
/src
/projb.hpp
/projb.cpp
/CMakeLists.txt (PB2)
After compiling, linking SUCCEEDS if I comment out everything in projb.cpp, (and define it in the header) but FAILS with undefined reference (to any function defined in projb.cpp).
-(PA1)-
add_subdirectory("req/projectB")
include_directories(${PROJECT_NAME} "req/projectB/src")
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} INTERFACE projectB)
-(PB1)-
add_subdirectory(src)
-(PB2)-
add_library(projectB projb.hpp projb.cpp)
main.cpp
int main() {
project_b::doStuff();
return 1;
}
projb.hpp
namespace project_b {
void doStuff(); // fails
void doStuff() {} // works if nothing defined in .cpp
// (only one or the other version is declared not both)
} // end namespace
projb.cpp
namespace project_b {
void doStuff() {} // fails with undefined reference error when called from main
} // end namespace
Solution
Turns out that another part of projectA which I thought was irrelevant was actually very relevant.
Thus I just needed to add this line:
# projAadep is included by main.cpp from projectA
target_link_libraries(projAdep PRIVATE projectB)
before this line:
target_link_libraries(${PROJECT_NAME} PUBLIC projectB)
My understanding was that by using:
target_link_libraries(${PROJECT_NAME} list of all used libs here)
was all that is necessary.
How discovered this was when I was commenting out various things in order to get the output of make VERBOSE=1
to just include the most relevent parts, it compiled and linked successfully. This then led me to do more testing to figure out why it linked successfully, and so on.
Answered By - R. Smyth