【问题标题】:AtmelStudio recipe for target *.elf failed目标 *.elf 的 Atmel Studio 配方失败
【发布时间】:2021-08-17 09:53:54
【问题描述】:

我已将代码分成文件(*.c 和 *.h)并包含它们。我有保护标头,并且所有分离的文件都被报告为正在构建:

Finished building: .././test.c

但我的项目构建导致此错误:

recipe for target 'Midi.elf' failed

,因为

undefined reference to 'some_test()'

(所有对函数的调用)在这些单独的文件中定义。 而且我不知道如何调试它。我插入了编译器警告,并且可以证明要处理的函数定义和声明。可能无法链接 avr-g++.exe 和 avr-gcc.exe 构建输出?

Sketch.cpp:

#include "test.h"
void setup() {
   some_test();
}

void loop() {
}

test.h:

#ifndef TEST_H
#define TEST_H

void some_test(void);
#warning "processing test.h"

#endif //TEST_H

test.c:

#include "test.h"

void some_test(void){
    #warning "processing test.c"
}

输出(项目相关部分):

...
Done building project "ArduinoCore.cppproj".

Build succeeded.
------ Build started: Project: Midi, Configuration: Debug AVR ------
Build started.
Project "Midi.cppproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files\Atmel\Studio\7.0\Vs\Compiler.targets" from project "D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\Midi\Midi.cppproj" (target "Build" depends on it):
    Task "RunCompilerTask"
        Shell Utils Path C:\Program Files\Atmel\Studio\7.0\shellUtils
        C:\Program Files\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --output-sync 
        Building file: .././Sketch.cpp
        Invoking: AVR8/GNU C Compiler : 4.9.2
        "C:\Program Files\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-g++.exe" -funsigned-char -funsigned-bitfields -DDEBUG -DF_CPU=16000000L -DARDUINO=108013 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x0010 -DUSB_MANUFACTURER="\"Arduino LLC\""  -I"C:\Program Files\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\include" -I"..\\..\ArduinoCore\include\core" -I"..\\..\ArduinoCore\include\variants\mega"  -Os -fno-threadsafe-statics -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -w -mmcu=atmega2560 -B "C:\Program Files\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560" -c -std=gnu++11 -MD -MP -MF "Sketch.d" -MT"Sketch.d" -MT"Sketch.o"   -o "Sketch.o" ".././Sketch.cpp" 
        Finished building: .././Sketch.cpp
        Building file: .././test.c
        Invoking: AVR8/GNU C Compiler : 4.9.2
        "C:\Program Files\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe"  -x c -funsigned-char -funsigned-bitfields -DDEBUG -DF_CPU=16000000L -DARDUINO=108013 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x0010 -DUSB_MANUFACTURER="\"Arduino LLC\""  -I"C:\Program Files\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\include" -I"..\\..\ArduinoCore\include\core" -I"..\\..\ArduinoCore\include\variants\mega"  -Os -fno-threadsafe-statics -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega2560 -B "C:\Program Files\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560" -c -std=gnu99 -std=gnu11 -MD -MP -MF "test.d" -MT"test.d" -MT"test.o"   -o "test.o" ".././test.c" 
        Finished building: .././test.c
cc1.exe(0,0): warning: command line option '-fno-threadsafe-statics' is valid for C++/ObjC++ but not for C
        In file included from .././test.c:1:0:
D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\Midi\test.h(5,2): warning: #warning "processing test.h" [-Wcpp]
         #warning "processing test.h"
          ^
        .././test.c: In function 'some_test':
D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\Midi\test.c(4,3): warning: #warning "processing test.c" [-Wcpp]
          #warning "processing test.c"
           ^
        Building target: Midi.elf
        Invoking: AVR8/GNU Linker : 4.9.2
        "C:\Program Files\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-g++.exe" -o Midi.elf  Sketch.o test.o   -Wl,-Map="Midi.map" -Wl,--start-group -Wl,-lm -Wl,-lArduinoCore  -Wl,--end-group -Wl,-L"D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\ArduinoCore\Debug"  -Wl,--gc-sections -mrelax -mmcu=atmega2560 -B "C:\Program Files\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.1.130\gcc\dev\atmega2560" -Os  
        Sketch.o: In function `setup':
D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\Midi\Sketch.cpp(20,1): error: undefined reference to `some_test()'
collect2.exe(0,0): error: ld returned 1 exit status
        make: *** [Midi.elf] Error 1
D:\Mirror\Anwendungen\AVRStudio\Arduino\MIDIout\MIDIout\MIDIout\Midi\Debug\Makefile(123,1): error: recipe for target 'Midi.elf' failed
        The command exited with code 2.
    Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "Midi.cppproj" -- FAILED.
Done building project "Midi.cppproj" -- FAILED.

Build FAILED.
========== Build: 1 succeeded or up-to-date, 1 failed, 0 skipped ==========

【问题讨论】:

    标签: embedded avr atmelstudio


    【解决方案1】:

    Sketch.cpp 编译为 C++,包括 test.h。为了支持函数重载、类成员资格等,C++ 使用 name mangling 将这些 C++ 特征编码到符号名称中。因此,Sketch.cpp 中some_test 的符号名称与编译为 C 且未应用名称映射的 test.c 中的符号名称不同..

    解决方案是通过指定符号具有 C 链接来防止在 C++ 编译头文件时对该符号进行名称修改:

    #ifndef TEST_H
    #define TEST_H
    
    #if defined __cplusplus
    extern "C"
    {
        #warning Using C linkage in C++ for test.h
    #endif
    
    void some_test(void);
    #warning "processing test.h"
    
    #if defined __cplusplus
    }
    #endif
    
    
    #endif //TEST_H
    

    extern "C" 声明中的大括号 ({...}) 表示所有包含的符号声明都具有 C 链接。对于 C / C++ 互操作性,您的所有 C 代码头文件都应包含此包装器。

    当然,另一种解决方案是将 test.c 编译为 C++(最简单的方法是将其重命名为 text.cpp)。请注意,Arduino Sketch 代码和库 C++ 代码。通常最好始终坚持 C++ 编译,以允许访问具有 C++ 链接并且需要大量包装代码才能从 C 访问的 Arduino 库。

    当构建日志明显使用 C++ 编译时,它会显示“Invoking: AVR8/GNU C Compiler”,这是毫无帮助的。我认为这只是 Atmel Studio 的东西,不是由编译器本身生成的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 2018-06-06
      相关资源
      最近更新 更多