英文:
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}")
。参考文档:
- https://cmake.org/cmake/help/latest/command/target_compile_features.html
- https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#high-level-meta-features-indicating-c-standard-support
英文:
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 <VISIBILITY> "cxx_std_${CPP_VERSION_TEST_CXX_LANGUAGE_STANDARD}")
. See docs:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论