CMake & C++ : linker error : undefined reference to function

CMake & C++ : linker error : undefined reference to function

我正在尝试使用 CMake 编译一个简单的 C++ 程序,但出现链接器错误:

[2/2] Linking CXX executable bin/MY_PROGRAM
FAILED: bin/MY_PROGRAM
: && g++ -g  CMakeFiles/MY_PROGRAM.dir/src/main.cpp.o -o bin/MY_PROGRAM  && :
/usr/bin/ld: CMakeFiles/MY_PROGRAM.dir/src/main.cpp.o: in function `main':
/home/user/Code/root/src/main.cpp:27: undefined reference to `str_toupper(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

我尝试查看一些具有类似问题的问题,但找不到我做错了什么。肯定是我的目录结构和CMake文件有问题。我可以更改目录结构以使事情变得更容易,但我可能会遗漏一些重要的东西,我想找出原因。另外,我是 C++ 的新手,所以我可能在代码本身做错了什么,但我的 IDE 没有发现任何问题。

我的目录结构是:

root
    |-- CMakeLists.txt
    |-- src
        |-- main.cpp
    |-- utils
        |-- CMakeLists.txt
        |-- src
            |-- strutils.cpp
        |-- include
            |-- strutils.h

顶级CMakeLists.txt是:

// general stuff (standard, etc...)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin)
set(MY_PROGRAM_SRC src/main.cpp)
add_executable(MY_PROGRAM ${MY_PROGRAM_SRC})

include_directories(utils/include)
link_libraries(MY_LIBRARY)

utils/CMakeLists.txt

set(MY_LIBRARY_SRC include/strutils.h src/strutils.cpp)
add_library(MY_LIBRARY STATIC ${MY_LIBRARY_SRC})

// This is to include strutils.h in strutils.cpp 
// (but is it needed ? I could just #include <string> in strutils.cpp, I guess)
target_include_directories(MY_LIBRARY PUBLIC include)

最后,源文件:

// strutils.h
#include <string>

void str_toupper(const std::string &in, std::string &out);
// strutils.cpp
#include <algorithm>
#include <strutils.h>

void str_toupper(const std::string &in, std::string &out) {
  std::transform(in.begin(), in.end(), out.begin(), [](char c){return std::toupper(c);});
}
// main.cpp
#include <strutils.h>

#include <cstdlib>
#include <cstdio>
#include <string>

int main(int argc, char *argv[]) {
  // ...
  std::string arg_in;
  for (int i = 0; i < argc; i++) {
    str_toupper(std::string(argv[i]), arg_in);
  }
}

有谁知道发生了什么事吗?谢谢!

说明书第一句link_libraries

Link libraries to all targets added later.

您在添加目标 MY_PROGRAM 之后使用此指令 - 目标 MY_PROGRAM 是 添加之前 link_libraries.

优先使用 target_link_libraries(MY_PROGRAM MY_LIBRARY) - 其他目标可能需要不同的依赖项,最好不要对所有目标使用全局依赖项集。