简体   繁体   English

CMake + MSys2 对所有内容的未定义引用(包括 c++ 运行时)

[英]CMake + MSys2 undefined references to everything (including c++ runtime)

I'm playing around with developing a cross-platform C++ project.我正在开发一个跨平台的 C++ 项目。 Things build fine on Linux, but on Windows (10) + MSys2 I've run into a strange issue.在 Linux 上一切正常,但在 Windows (10) + MSys2 上我遇到了一个奇怪的问题。 Compile works fine (picks up my include dirs, etc.), but linking fails with all sorts of undefined reference errors to a static imported library I have, and even the C++ runtime.编译工作正常(拿起我的包含目录等),但链接失败,各种未定义的引用错误到我拥有的 static 导入库,甚至 C++ 运行时。

I've tried setting CMAKE_C[XX]_COMPILER, CMAKE_MAKE_PROGRAM, but the output from the configuration step is always the same:我试过设置 CMAKE_C[XX]_COMPILER、CMAKE_MAKE_PROGRAM,但配置步骤中的 output 始终相同:

$ cmake ..
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
System is unknown to cmake, create:
Platform/MINGW64_NT-10.0-19041 to use this system, please post your config file on discourse.cmake.org so it can be added to cmake
-- Detecting C compiler ABI info
System is unknown to cmake, create:
Platform/MINGW64_NT-10.0-19041 to use this system, please post your config file on discourse.cmake.org so it can be added to cmake
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
System is unknown to cmake, create:
Platform/MINGW64_NT-10.0-19041 to use this system, please post your config file on discourse.cmake.org so it can be added to cmake
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /mingw64/bin/CC.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: <....>

As mentioned earlier the compile works, but linking the executable fails spectacularly.如前所述,编译工作,但链接可执行文件失败了。 Here is my minimal working example:这是我的最小工作示例:

$ cat ../CMakeLists.txt
project(example)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_executable(example
        main.cpp
)

Here is an sample of the output (the rest is omitted for brevity):这是 output 的示例(为简洁起见,省略了 rest):

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.cpp.obj:main.cpp:(.text+0x51): undefined reference to `std::ios_base::Init::~Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.cpp.obj:main.cpp:(.text+0x81): undefined reference to `std::ios_base::Init::Init()'

Adding -v to cmake produces the following commands.将 -v 添加到 cmake 会产生以下命令。

Compile:编译:

/mingw64/bin/CC.exe   -std=gnu++17 -o CMakeFiles/example.dir/main.cpp.obj -c /home/.../Development/minex/main.cpp

Link:关联:

/mingw64/bin/CC.exe CMakeFiles/example.dir/main.cpp.obj -o example

CC.exe seems off... and it's used if I set the CXX compiler flag or not... CC.exe 似乎关闭了......如果我设置了 CXX 编译器标志,它就会被使用......

I also tried generating "MSYS2 Makefiles" but that also fails (doesn't know the generator).我也尝试生成“MSYS2 Makefiles”,但这也失败了(不知道生成器)。

I can reproduce the output by running我可以通过运行重现 output

$ CC main.cpp -o example

while尽管

$ g++ main.cpp -o example

works fine.工作正常。

CMake version is 3.18.4. CMake 版本为 3.18.4。

Edit: This is the entire output of running make VERBOSE=1 (using mingw64-cmake seems to produce the same output, except the 'entering directory' and 'leaving directory' paths are absolute windows paths):编辑:这是运行make VERBOSE=1的整个 output (使用mingw64-cmake似乎产生相同的 output,除了“进入目录”和“离开目录”路径是绝对的 Z0F4C54207ED3AA258B 路径)

    $ cat log
/usr/bin/cmake.exe -S/home/<...>/Development/minex -B/home/<...>/Development/minex/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake.exe -E cmake_progress_start /home/<...>/Development/minex/build/CMakeFiles /home/<...>/Development/minex/build//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/<...>/Development/minex/build'
make  -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/depend
make[2]: Entering directory '/home/<...>/Development/minex/build'
cd /home/<...>/Development/minex/build && /usr/bin/cmake.exe -E cmake_depends "Unix Makefiles" /home/<...>/Development/minex /home/<...>/Development/minex /home/<...>/Development/minex/build /home/<...>/Development/minex/build /home/<...>/Development/minex/build/CMakeFiles/example.dir/DependInfo.cmake --color=
Dependee "/home/<...>/Development/minex/build/CMakeFiles/example.dir/DependInfo.cmake" is newer than depender "/home/<...>/Development/minex/build/CMakeFiles/example.dir/depend.internal".
Dependee "/home/<...>/Development/minex/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/<...>/Development/minex/build/CMakeFiles/example.dir/depend.internal".
Scanning dependencies of target example
make[2]: Leaving directory '/home/<...>/Development/minex/build'
make  -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/build
make[2]: Entering directory '/home/<...>/Development/minex/build'
[ 50%] Building CXX object CMakeFiles/example.dir/main.obj
/mingw64/bin/CC.exe   -std=gnu++17 -o CMakeFiles/example.dir/main.obj -c /home/<...>/Development/minex/main.cpp
[100%] Linking CXX executable example
/usr/bin/cmake.exe -E cmake_link_script CMakeFiles/example.dir/link.txt --verbose=1
/mingw64/bin/CC.exe CMakeFiles/example.dir/main.obj -o example
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.text+0x23): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.text+0x32): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.text+0x51): undefined reference to `std::ios_base::Init::~Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.text+0x81): undefined reference to `std::ios_base::Init::Init()'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.rdata$.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_[.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_]+0x0): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/example.dir/main.obj:main.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/example.dir/build.make:103: example] Error 1
make[2]: Leaving directory '/home/<...>/Development/minex/build'
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/example.dir/all] Error 2
make[1]: Leaving directory '/home/<...>/Development/minex/build'
make: *** [Makefile:103: all] Error 2

Solution:解决方案:

I was setting CMAKE_CXX_COMPILER wrong:/.我设置 CMAKE_CXX_COMPILER 错误:/。 I was doing it from memory, and I just did我是从 memory 做的,我刚刚做了

CMAKE_CXX_COMPILER=... cmake ..

not不是

cmake .. -DCMAKE_CXX_COMPILER=...

However!然而! It's still weird that CC is used to successfully compile cpp files, but it can't link the object files.用CC成功编译cpp文件还是很奇怪,但是却无法链接object文件。

If you are using mingw64 compiler in MSYS2 make sure you are using mingw64 version of cmake too.如果您在MSYS2中使用mingw64编译器,请确保您使用的是cmakemingw64版本。

Using cmake not aligned with gcc eg:使用 cmake 未与 gcc 对齐,例如:

MINGW64
# which gcc
/mingw64/bin/gcc

MINGW64
# which cmake
/usr/bin/cmake

Will led to following error when running cmake:运行cmake时会导致如下错误:

...
-- The CXX compiler identification is GNU 10.2.0
System is unknown to cmake, create:
Platform/MINGW64_NT-10.0-19041 to use this system, please post your config file on discourse.cmake.org so it can be added to cmake
...

and linker error in build step.以及构建步骤中的 linker 错误。

So make sure you install mingw64 version of cmake:所以一定要安装 mingw64 版本的 cmake:

MINGW64
pacman -S mingw-w64-x86_64-cmake

You need to close terminal and open it again after cmake is installed.安装 cmake 后需要关闭终端并再次打开。 Then make sure you have aligned versions of gcc and cmake installed:然后确保您安装了 gcc 和 cmake 的对齐版本:

MINGW64
# which gcc
/mingw64/bin/gcc

MINGW64
# which cmake
/mingw64/bin/cmake

Now cmake should work properly.现在 cmake 应该可以正常工作了。

You have these errors because you are trying to compile/link c++ program with a c compiler.您遇到这些错误是因为您尝试使用 c 编译器编译/链接 c++ 程序。 For example the two undefined references you are mentioning are part of libstdc++.例如,您提到的两个未定义引用是 libstdc++ 的一部分。 It is used by default when using g++ but not with CC .使用g++但不使用CC时默认使用它。 If you want to use CC you have to add it manually -lstdc++ .如果要使用 CC,则必须手动添加-lstdc++

The easiest way is to compile and link c++ programs by using g++.最简单的方法是使用 g++ 编译和链接 c++ 程序。

For some reason the /mingw64/bin/CC.exe is considered as the CXX compiler and the working detection is skipped.由于某种原因,/mingw64/bin/CC.exe 被认为是 CXX 编译器,并且跳过了工作检测。 to avoid the skipp of the working detection you can add set(CMAKE_CXX_COMPILER_WORKS 1) .为避免跳过工作检测,您可以添加set(CMAKE_CXX_COMPILER_WORKS 1) to modify the compiler it self you can set CMAKE_CXX_COMPILER as explained in CMAKE_CXX_COMPILER or set CXX as explained in CXX .要自行修改编译器,您可以按照CMAKE_CXX_COMPILER 中的说明设置 CMAKE_CXX_COMPILER CMAKE_CXX_COMPILER按照CXX中的说明设置CXX be careful to clean the cache.小心清理缓存。

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

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