You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:05:41