C++ 链接器找到 header 但找不到 .cpp 文件(使用 cmake、gcc)
C++ linker finds header but cannot find .cpp file (using cmake, gcc)
我正在尝试将一个项目包含在一个项目中。
相关结构如下:
projectA
/CMakeLists.txt (PA1)
/src
/main.cpp
/req/projectB
/CMakeLists.txt (PB1)
/src
/projb.hpp
/projb.cpp
/CMakeLists.txt (PB2)
编译后,如果我注释掉 projb.cpp 中的所有内容(并在 header 中定义它),则链接成功,但未定义引用(对 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
Libraries following INTERFACE are appended to the link interface and are not used for linking .
参见:https://cmake.org/cmake/help/latest/command/target_link_libraries.html
所以,我建议将 INTERFACE 更改为 PUBLIC 或 PRIVATE
事实证明,projectA 中我认为不相关的另一部分实际上非常相关。
因此我只需要添加这一行:
# projAadep is included by main.cpp from projectA
target_link_libraries(projAdep PRIVATE projectB)
在这一行之前:
target_link_libraries(${PROJECT_NAME} PUBLIC projectB)
我的理解是通过使用:
target_link_libraries(${PROJECT_NAME} list of all used libs here)
是所有必要的。
当我注释掉各种内容以使 make VERBOSE=1
的输出只包含最相关的部分时,我是如何发现这一点的,它已成功编译和链接。这让我做了更多的测试来找出它链接成功的原因,等等。
我正在尝试将一个项目包含在一个项目中。 相关结构如下:
projectA
/CMakeLists.txt (PA1)
/src
/main.cpp
/req/projectB
/CMakeLists.txt (PB1)
/src
/projb.hpp
/projb.cpp
/CMakeLists.txt (PB2)
编译后,如果我注释掉 projb.cpp 中的所有内容(并在 header 中定义它),则链接成功,但未定义引用(对 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
Libraries following INTERFACE are appended to the link interface and are not used for linking .
参见:https://cmake.org/cmake/help/latest/command/target_link_libraries.html
所以,我建议将 INTERFACE 更改为 PUBLIC 或 PRIVATE
事实证明,projectA 中我认为不相关的另一部分实际上非常相关。
因此我只需要添加这一行:
# projAadep is included by main.cpp from projectA
target_link_libraries(projAdep PRIVATE projectB)
在这一行之前:
target_link_libraries(${PROJECT_NAME} PUBLIC projectB)
我的理解是通过使用:
target_link_libraries(${PROJECT_NAME} list of all used libs here)
是所有必要的。
当我注释掉各种内容以使 make VERBOSE=1
的输出只包含最相关的部分时,我是如何发现这一点的,它已成功编译和链接。这让我做了更多的测试来找出它链接成功的原因,等等。