链接错误的原因是当我尝试按名称将可执行文件链接到库时发生了什么?

huangapple go评论74阅读模式
英文:

What's the cause of this link error when I try to link my executable to my library by name?

问题

以下是翻译好的部分:

"我正在尝试构建和运行基于所选的C++标准链接文件的项目。 项目文件结构如下:

.
├── CMakeLists.txt
├── cpp-version-test
│   ├── CMakeLists.txt
│   ├── test-cpp17.cpp
│   ├── test-cpp17.hpp
│   ├── test-cpp20.cpp
│   └── test-cpp20.hpp
└── main.cpp

在顶层的CMakeLists.txt中,我设置C++标准如下:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

cpp-version-test的CMakeLists.txt文件中,我运行条件语句:

if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
    message("选择了C++20,正在构建test-cpp20")
    add_library(cpp_version_test OBJECT test-cpp20.cpp)
else()
    message("未选择C++20,正在构建test-cpp17")
    add_library(cpp_version_test OBJECT test-cpp17.cpp)
endif()

target_include_directories(cpp_version_test INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

然后,回到顶层的CMakeLists.txt,我使用以下代码将它连接起来:

add_subdirectory(cpp-version-test)
list(APPEND EXTRA_LIBS cpp-version-test)

add_executable(Template main.cpp)
target_link_libraries(Template PUBLIC ${EXTRA_LIBS} compiler_flags)

target_include_directories(Template PUBLIC
    "${PROJECT_BINARY_DIR}"
)

cmake --build 运行正常,但Clang在链接时出现问题:

[ 33%] Building CXX object CMakeFiles/Template.dir/main.cpp.o
[ 66%] Linking CXX executable Template
/usr/bin/ld: 无法找到-lcpp-version-test:没有那个文件或目录
clang-15:错误:链接器命令失败,退出代码1(使用-v查看调用)
make[2]: *** [CMakeFiles/Template.dir/build.make:97: Template] Error 1
make[1]: *** [CMakeFiles/Makefile2:100: CMakeFiles/Template.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

非常感谢任何帮助。这是我学习CMake时的反复尝试。"

英文:

I'm trying to build and run project that links files based on the picked C++ standard.
The project file structure looks like this:

.
├── CMakeLists.txt
├── cpp-version-test
│   ├── CMakeLists.txt
│   ├── test-cpp17.cpp
│   ├── test-cpp17.hpp
│   ├── test-cpp20.cpp
│   └── test-cpp20.hpp
└── main.cpp

In the top CMakeLists.txt I set C++ standard like this:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

Inside cpp-version-test CMakeLists.txt file I run conditional:

if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
    message("C++20 choosen, building test-cpp20")
    add_library(cpp_version_test OBJECT test-cpp20.cpp)
else()
    message("C++20 not choosen, building test-cpp17")
    add_library(cpp_version_test OBJECT test-cpp17.cpp)
endif()

target_include_directories(cpp_version_test INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

And back inside the top CMakeLists.txt I glue it with the following snippet:

add_subdirectory(cpp-version-test)
list(APPEND EXTRA_LIBS cpp-version-test)

add_executable(Template main.cpp)
target_link_libraries(Template PUBLIC ${EXTRA_LIBS} compiler_flags)

target_include_directories(Template PUBLIC
    "${PROJECT_BINARY_DIR}"
)

cmake --build runs fine, Clang clogs up on linking:

[ 33%] Building CXX object CMakeFiles/Template.dir/main.cpp.o
[ 66%] Linking CXX executable Template
/usr/bin/ld: cannot find -lcpp-version-test: No such file or directory
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [CMakeFiles/Template.dir/build.make:97: Template] Error 1
make[1]: *** [CMakeFiles/Makefile2:100: CMakeFiles/Template.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Any help would be greatly appreciated. It's my back and forth with learning CMake.

答案1

得分: 1

在你的子目录中执行以下操作:

add_library(cpp_version_test OBJECT ...)

然后在你的顶层 CMakeLists.txt 文件中执行以下操作:

add_subdirectory(cpp-version-test)
list(APPEND EXTRA_LIBS cpp-version-test)
add_executable(Template main.cpp)
target_link_libraries(Template PUBLIC ${EXTRA_LIBS} compiler_flags)

你混淆了目录的名称和目标的名称。你的目标使用下划线命名,而你的目录使用破折号命名。target_link_libraries 使用目标名称而不是目录名称。你的 "list(APPEND EXTRA_LIBS cpp-version-test)" 应该改成 "list(APPEND EXTRA_LIBS cpp_version_test)"。

一些额外的反馈:与其按照你当前的方式操作,我建议让用户设置一个名为 "CPP_VERSION_TEST_CXX_LANGUAGE_STANDARD" 的缓存变量,以选择要使用的 C++ 语言版本号,然后执行 target_compile_features(cpp_version_test <VISIBILITY> "cxx_std_${CPP_VERSION_TEST_CXX_LANGUAGE_STANDARD}")。参考文档:

英文:

You do this in your subdirectory:

add_library(cpp_version_test OBJECT ...)

Then in your top CMakeLists.txt:

add_subdirectory(cpp-version-test)
list(APPEND EXTRA_LIBS cpp-version-test)
add_executable(Template main.cpp)
target_link_libraries(Template PUBLIC ${EXTRA_LIBS} compiler_flags)

You mixed up the name of your directory and the name of your target. You target is named with underscores and your directory with dashes. target_link_libraries works with target names and not directory names. Your "list(APPEND EXTRA_LIBS cpp-version-test)" should instead be "list(APPEND EXTRA_LIBS cpp_version_test)".

Some additional feedback: Instead of doing things the way you're doing, I would let the user set a cache variable named something like "CPP_VERSION_TEST_CXX_LANGUAGE_STANDARD" to choose the number of the C++ language version to use and then target_compile_features(cpp_version_test &lt;VISIBILITY&gt; &quot;cxx_std_${CPP_VERSION_TEST_CXX_LANGUAGE_STANDARD}&quot;). See docs:

huangapple
  • 本文由 发表于 2023年3月1日 11:49:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599413.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定