编译RISC-V汇编项目时CMake无法确定链接器语言的问题
问题:RISC-V项目CMake构建报错无法确定链接语言
错误信息
-- The C compiler identification is GNU 12.1.0 -- The CXX compiler identification is GNU 12.1.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /opt/riscv32-unknown-elf.gcc-12.1.0/bin/riscv32-unknown-elf-gcc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /opt/riscv32-unknown-elf.gcc-12.1.0/bin/riscv32-unknown-elf-g++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done CMake Error: Cannot determine link language for target "test.elf". CMake Error: CMake can not determine linker language for target: test.elf -- Generating done CMake Generate step failed. Build files cannot be regenerated correctly.
项目情况
- 项目由两个汇编文件
startup.s和main.s组成;替换main.s为仅含空main函数的main.c时,CMake可正常执行。 - 构建命令:
mkdir build cd build cmake ..
- 目录结构:
. ├── toolchain-riscv.cmake ├── src │ ├── startup.s │ ├── main.s │ ├── main.c │ └── CMakeLists.txt ├── linker.ld └── CMakeLists.txt
配置文件内容
toolchain-riscv.cmake
# Set cross compilation information set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR riscv) set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") # GCC toolchain prefix set(TOOLCHAIN_PREFIX "/opt/riscv32-unknown-elf.gcc-12.1.0/bin/riscv32-unknown-elf") set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) # TODO this should be the assembler, but ${CMAKE_ASM_FLAGS} are # actually gcc flags, therefore they won't work with as set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-gcc) set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar) set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy) set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump) # TODO These are actually gcc flags. The assembler should be # used and these flags replaced set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv32g -mabi=ilp32 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g -O0") set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -march=rv32g -mabi=ilp32 -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g -O0") set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") set(CMAKE_EXPORT_COMPILE_COMMANDS true)
./CMakeLists.txt
cmake_minimum_required(VERSION 3.13.1) include(toolchain-riscv.cmake) project(test) add_library(${CMAKE_PROJECT_NAME}.elf STATIC) target_link_options(${CMAKE_PROJECT_NAME}.elf PRIVATE -T${CMAKE_SOURCE_DIR}/linker.ld ) add_subdirectory(src)
src/CMakeLists.txt
target_sources(${CMAKE_PROJECT_NAME}.elf PRIVATE main.s startup.s )
解决方案
报错原因是:当目标仅包含汇编文件时,CMake无法自动推断链接语言;加入C文件时,CMake会默认以C语言作为链接语言,因此不会报错。有两种解决方法:
方法1:显式指定目标的链接语言
在顶层CMakeLists.txt的add_library语句后,添加配置指定链接语言为C:
set_target_properties(${CMAKE_PROJECT_NAME}.elf PROPERTIES LINKER_LANGUAGE C)
修改后的顶层CMakeLists.txt:
cmake_minimum_required(VERSION 3.13.1) include(toolchain-riscv.cmake) project(test) add_library(${CMAKE_PROJECT_NAME}.elf STATIC) # 显式指定链接语言为C set_target_properties(${CMAKE_PROJECT_NAME}.elf PROPERTIES LINKER_LANGUAGE C) target_link_options(${CMAKE_PROJECT_NAME}.elf PRIVATE -T${CMAKE_SOURCE_DIR}/linker.ld ) add_subdirectory(src)
方法2:启用ASM语言支持
在toolchain-riscv.cmake中添加启用ASM语言的配置,帮助CMake识别汇编文件对应的语言类型:
enable_language(ASM)
补充说明
注意toolchain-riscv.cmake中的TODO注释:如果后续要改用纯汇编器(riscv32-unknown-elf-as),需要调整CMAKE_ASM_COMPILER和CMAKE_ASM_FLAGS——当前用gcc作为汇编器,传递的是gcc参数,这在当前场景可行,但切换到纯汇编器时,需将CMAKE_ASM_FLAGS替换为适合as的参数。
内容的提问来源于stack exchange,提问作者Martel
相关产品推荐
相关产品推荐

