提问人:p3zhy 提问时间:5/20/2023 更新时间:5/20/2023 访问量:128
在 C 语言中使用 Rust 代码和 CMake 时出现链接错误
Linking error when using Rust code in C with CMake
问:
在 C 中使用 Rust 代码和 CMake 时出现链接问题。
我正在尝试使用 CMake 将一些 Rust 代码合并到我的 C 项目中。我已经成功编译了 Rust 代码,生成为 Rust 静态库。我在 CMake 配置中将此库传递给链接器。但是,当我尝试编译 C 项目时,遇到以下错误:librust_lib.a
未定义对
rust_function
以下是我的项目结构和配置的摘要:
toolchain-gcc.cmake:
这是 CMake 用于设置 GCC 工具链的配置文件。它设置与交叉编译环境相关的各种选项和变量。
# Configures CMake for using GCC
set(CMAKE_SYSTEM_NAME Generic)
find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
find_program(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
find_program(CMAKE_READELF ${CROSS_COMPILE}readelf)
set(CMAKE_EXECUTABLE_SUFFIX_ASM .elf)
set(CMAKE_EXECUTABLE_SUFFIX_C .elf)
set(CMAKE_EXECUTABLE_SUFFIX_CXX .elf)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE gcc_version OUTPUT_STRIP_TRAILING_WHITESPACE)
set(abi_options -mcpu=cortex-a5 -mtune=generic-armv7-a -mthumb -mfpu=neon-vfpv4
-mfloat-abi=hard -mno-unaligned-access)
set(partial_link_options)
set(libc_file_name ${CMAKE_CURRENT_SOURCE_DIR}/components/newlib/armca5/libc.a)
set(libm_file_name ${CMAKE_CURRENT_SOURCE_DIR}/components/newlib/armca5/libm.a)
# specify the location of the Rust library file rust_lib.a
set(rust_lib ${CMAKE_CURRENT_SOURCE_DIR}/rust_lib.a)
if(CONFIG_ENABLE_GCC_LTO)
set(lto_compile_option -flto -ffat-lto-objects)
set(lto_link_option -flto)
endif()
add_compile_options(${abi_options} -g -Os ${lto_compile_option}
-Wall
-fno-strict-aliasing
-ffunction-sections -fdata-sections
)
add_link_options(${abi_options} -Os ${lto_link_option})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-exceptions -fno-rtti -fno-threadsafe-statics")
# GNU ar will alreay create index
set(CMAKE_C_ARCHIVE_FINISH "")
set(CMAKE_CXX_ARCHIVE_FINISH "")
if(WITH_WERROR)
add_compile_options(-Werror)
endif()
if(WITH_LINK_CREF)
set(link_cref_option -Wl,-cref)
endif()
set(multilib_opions ${abi_options})
if((${gcc_version} VERSION_GREATER 8) AND (CONFIG_CPU_ARM_CA5))
set(multilib_opions -march=armv7-a+neon-vfpv4 -mthumb -mfloat-abi=hard)
endif()
execute_process(COMMAND ${CMAKE_C_COMPILER} ${multilib_opions} --print-file-name libgcc.a
OUTPUT_VARIABLE libgcc_file_name
OUTPUT_STRIP_TRAILING_WHITESPACE
)
CMakeLists.txt:
这是项目的主要 CMake 配置文件。它包括 toolchain-gcc.cmake 文件并设置项目构建过程。
include(toolchain-gcc.cmake)
cmake_minimum_required(VERSION 3.13)
# Use a global property to collect all application libraries
define_property(GLOBAL PROPERTY app_libraries
BRIEF_DOCS "app libraries"
FULL_DOCS "app libraries"
)
# Other configuration options...
# "all_libs" is a target to link all app libraries
set(target all_libs)
set(all_libs_out ${out_lib_dir}/all_libs.a)
get_property(app_libraries GLOBAL PROPERTY app_libraries)
# Append the rust library to the list of application libraries
# to ensure it is linked during the build process
list(APPEND app_libraries ${libc_file_name} ${libm_file_name} ${libgcc_file_name} ${QL_LIBS_PATH} ${rust_lib})
add_custom_command(OUTPUT ${all_libs_out}
COMMAND python3 ${groupgen_py} --base ${BINARY_TOP_DIR} ${all_libs_out} ${app_libraries}
DEPENDS ${groupgen_py} ${app_libraries}
WORKING_DIRECTORY ${BINARY_TOP_DIR}
)
add_custom_target(build_${target} DEPENDS ${all_libs_out})
add_library(${target} STATIC IMPORTED GLOBAL)
set_target_properties(${target} PROPERTIES IMPORTED_LOCATION ${all_libs_out})
add_dependencies(${target} build_${target})
rust_lib/lib.rs:
这是包含 .rust_function()
#[no_mangle]
pub extern "C" fn rust_function() {
// Rust function implementation...
}
rust_lib/Cargo.toml:
这是 Rust 库的 Cargo 清单文件。
[lib]
name = "rust_lib"
crate-type = ["staticlib"]
# Other Rust configuration options...
main.h:
这是 main.c 的头文件,它声明了rust_function()
void rust_function();
main.c:
这是调用 .rust_function()
#include "main.h"
int main() {
// Other code...
rust_function();
// Other code...
return 0;
}
尽管成功编译了 Rust 代码并将库传递给我的 CMake 配置中的链接器,但我在编译 C 项目时遇到了以下错误:librust_lib.a
未定义对
rust_function
为了进一步研究,我使用该命令来验证 Rust 对象文件 () 中存在的符号,并且它确实包含rust_function符号。nm -gC
librust_lib.a
我不确定为什么链接器找不到对rust_function的引用。我是否遗漏了任何其他配置?
答: 暂无答案
评论
include(toolchain-gcc.cmake)
- 这是在 CMake 中包含工具链文件的错误方法。正确的方法是将工具链文件的路径分配给变量:cmake.org/cmake/help/latest/manual/...CMAKE_TOOLCHAIN_FILE。工具链将在第一次调用时激活。project()
VERBOSE=1
VERBOSE=1
librust_lib.a