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 的输出只包含最相关的部分时,我是如何发现这一点的,它已成功编译和链接。这让我做了更多的测试来找出它链接成功的原因,等等。