简体   繁体   English

CMake & C++:链接器错误:未定义的函数引用

[英]CMake & C++ : linker error : undefined reference to function

I am trying to compile a simple C++ program with CMake, but I am getting a linker error :我正在尝试使用 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.

I have tried looking at some questions with similar issues but couldn't find what I did wrong.我曾尝试查看一些具有类似问题的问题,但找不到我做错了什么。 There must be a problem with my directory structure and CMake files.我的目录结构和 CMake 文件一定有问题。 I could change the directory structure to make things easier, but I may be missing something important and I'd like to figure out why.我可以更改目录结构以使事情变得更容易,但我可能会遗漏一些重要的东西,我想弄清楚原因。 Also, I am new to C++ so I might be doing something wrong in the code itself, but my IDE doesn't find any issue.另外,我是 C++ 新手,所以我可能在代码本身中做错了,但我的 IDE 没有发现任何问题。

My directory structure is :我的目录结构是:

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

The top-level CMakeLists.txt is :顶级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)

and utils/CMakeLists.txt :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)

Finally, the source files :最后,源文件:

// 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);
  }
}

Does anyone have an idea of what's going on ?有谁知道发生了什么? Thanks !谢谢 !

The first sentence in the manuallink_libraries手册中的第一句话link_libraries

Link libraries to all targets added later .将库链接到以后添加的所有目标。

You use this directive after the target MY_PROGRAM is added - the target MY_PROGRAM is added prior link_libraries.在添加目标 MY_PROGRAM 后使用此指令 - 目标 MY_PROGRAM 是在 link_libraries之前添加的。

Prefer use target_link_libraries(MY_PROGRAM MY_LIBRARY) - other targets can require different dependencies and it's better not use a global set of dependencies for all targets.首选使用target_link_libraries(MY_PROGRAM MY_LIBRARY) - 其他目标可能需要不同的依赖项,最好不要对所有目标使用全局依赖项集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM