我为一个AVR32 32位微处理器继承了一个稍微复杂的C程序。

但是,我没有有关如何编译它的信息。 我一直在尝试为它整理一个make-file,但一直没有成功。 希望有人可以告诉我我要去哪里错了。


基本上,我有一个如下所示的项目结构:

/
ControllerR3.c     # This is the main program file
    /FRAMEWORK
        /DRIVERS
            /ADC
                adc.c
                adc.h
            /GPIO
                gpio.c
                gpio.h
            {another 6 hardware drivers}
        /SERVICES
            /DELAY
                delay.c
                delay.h

基本上, ControllerR3.c包括adc.hgpio.h等,并调用在这些各种头文件中原型化的函数。 .c文件中实际上定义了各种FRAMEWORK标头中的实际功能。

所有.h文件都包含在include保护中:

#ifndef _USART_H_
#define _USART_H_
{snip header file contents}
#endif  // _USART_H_

现在,据我所知,我必须将各种.c文件编译成目标( .o )文件,然后调用链接程序将所有目标文件合并到最终的可执行文件中(在本例中为.elf文件)。
因此,我编写了一个小的makefile:

CC      = avr32-gcc

CFLAGS  = -mpart=uc3a0512 -O1 -ffunction-sections -masm-addr-pseudos -g3 -Wall -c -std=gnu99 
COMP_INC =  -I"./FRAMEWORK/UTILS" \
            -I"./FRAMEWORK/UTILS/PREPROCESSOR"

LIB_INC =   -I"./FRAMEWORK/UTILS/LIBS/NEWLIB_ADDONS/INCLUDE" \
            -I"./FRAMEWORK/SERVICES/DELAY" \
            -I"./FRAMEWORK/DRIVERS/USART" \
            -I"./FRAMEWORK/DRIVERS/TC" \
            -I"./FRAMEWORK/DRIVERS/SPI" \
            -I"./FRAMEWORK/DRIVERS/PWM" \
            -I"./FRAMEWORK/DRIVERS/PM" \
            -I"./FRAMEWORK/DRIVERS/INTC" \
            -I"./FRAMEWORK/DRIVERS/GPIO" \
            -I"./FRAMEWORK/DRIVERS/FLASHC" \
            -I"./FRAMEWORK/DRIVERS/CPU/CYCLE_COUNTER" \
            -I"./FRAMEWORK/BOARDS" \
            -I"./FRAMEWORK/DRIVERS/ADC" 

DRIVER_PATH = ./FRAMEWORK/DRIVERS



all: libraries main

main:
    $(CC) $(CFLAGS) $(COMP_INC) $(LIB_INC) -o"Debug/$@.o" "ControllerR3.c"
    $(CC) "Debug/adc.o" "Debug/flashc.o" "Debug/gpio.o" "Debug/intc.o" "Debug/pm.o" "Debug/pwm.o" "Debug/tc.o" "Debug/usart.o" "Debug/spi.o" "Debug/main.o" "Debug/delay.o" \
        -o Debug/CookerControlR3.elf

libraries: adc.c flashc.c gpio.c intc.c pm.c pwm.c spi.c tc.c usart.c delay.c


adc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/ADC/$@"

flashc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/FLASHC/$@"

gpio.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/GPIO/$@"

intc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/INTC/$@"

pm.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/PM/$@"

pwm.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/PWM/$@"

spi.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/SPI/$@"

tc.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/TC/$@"

usart.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" "$(DRIVER_PATH)/USART/$@"


delay.c: 
    $(CC) $(CFLAGS) $(COMP_INC) -o"Debug/$*.o" -I"FRAMEWORK/DRIVERS/CPU/CYCLE_COUNTER" "FRAMEWORK/SERVICES/DELAY/$@"

这将成功构建所有各种目标文件,然后在链接阶段失败,并显示以下内容:

C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:507: multiple definition of `gpio_local_clr_gpio_open_drain_pin'
Debug/gpio.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:507: first defined here
Debug/main.o: In function `gpio_local_tgl_gpio_open_drain_pin':
C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:525: multiple definition of `gpio_local_tgl_gpio_open_drain_pin'
Debug/gpio.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/GPIO/gpio.h:525: first defined here
Debug/main.o: In function `usart_reset_status':
C:\[snip - private]/./FRAMEWORK/DRIVERS/USART/usart.h:409: multiple definition of `usart_reset_status'
Debug/usart.o:C:\[snip - private]/./FRAMEWORK/DRIVERS/USART/usart.h:409: first defined here
Debug/main.o: In function `usart_parity_error':
[snip a hundred or so lines]

显然,我对多个定义有疑问。

在这一点上,我有点不知所措。 我没有太多的C开发经验,只是使makefile达到现在需要大量阅读的程度。

是什么导致我在这里遇到多个定义问题? 为了防止这种情况,我需要对makefile进行哪些更改?

我知道这个项目是过去成功构建的,因为我们有一个实际运行它的硬件设备。 但是,我需要进行一些更改,因此不再需要使用现有的编译版本。

现有版本是由不再可用的外部承包商构建的,因此我无法真正询问他们如何使它工作。

#1楼 票数:1

看起来您的头文件中实现了一个功能。 编译object1和object2(例如main.o和gpio.o)时,您的代码在两个对象中都重复了,并且无法将它们链接在一起。

在这种情况下,通常我将函数的声明保留在头文件中,并将其实现移至目标代码之一(无论哪种)中。

您可以确认在“ gpio.h:507”中您具有实现,而不仅是功能的签名吗?

#2楼 票数:0 已采纳

好吧,原来我使用的是最近的IDE。

我在正确的IDE(在本例中为基于eclipse的Atmel avr32 studio的较早版本)中打开了该项目,它以某种方式自动推断出结构,并将所有内容正确地组合在一起。

无论如何,虽然解决问题并不能避免,但是我将这个问题标记为已回答。 我已经花了太多时间试图弄清楚日食正在做什么。

  ask by Fake Name translate from so

未解决问题?本站智能推荐:

1回复

解决ld链接器问题以构建R源代码

在尝试从源代码安装R时,我遇到了链接器问题,特别是: undefined reference to 'u_getVersion_58 我发现有关此错误的信息有限(例如, 此帖子在RStudio论坛上 )。 尽管运行了apt-get build-dep ,但这些问题仍然存在。 从Dirk
1回复

MinGW32:使用-static标志链接ImageMagick

我目前正在尝试构建支持ImageMagick的Windows版本的emacs。 为此,我已经使用MinGW32 / MSys编译了ImageMagick,以获取兼容的库文件。 基本上链接也可以,但是我必须通过configure.bat的--lib选项将-llibMagickCore-6.Q
1回复

根据Windows下的iconv构建Haskell程序

我有一个取决于iconv的项目,因为我需要使用cp1251代码页。 这是问题项目的最小实施。 我从这里安装了iconv,并成功安装了haskell软件包“ iconv”,如下所示 软件包iconv已正确安装,但是取决于它的项目链接失败,这是怎么回事。 为什么安装并链接了iconv,但
3回复

需要澄清用于编译C文件的某些术语

我正在使用GCC编译器和Geany(Arch Linux,如果它有所作为)学习C. 但是,我看到在Geany和互联网上,可以互换地使用“编译和构建”这两个词。 我要求澄清我理解编译过程的方式是正确的,因为谷歌搜索它只会让我更加困惑。 假设我写了一个简单的helloworld.c文件:
1回复

如何以及何时在C程序中使用_POSIX_C_SOURCE?

我已经让自己不得不维护一些C项目,它也应该在旧平台上编译。 目前,对于某些平台,定义了宏_POSIX_C_SOURCE 。 我想知道 - 如果定义它是否可以接受,我不应该只在所有平台上定义它吗? 也许具有最高的相关价值? 为了概括,我想我要问:何时以及在什么条件下应该使用_POSIX_
1回复

AppleLLVM编译器4.0错误铿锵

对不起,我的英语不好,我是法国人。 我从C语言开始,在构建期间遇到错误 我试图在网上找到一些解决方案,但没有结果.. 谢谢帮帮我..
1回复

交叉编译poppler软件包时出错

在Ubuntu上交叉编译Poppler软件包时出现以下错误 配置完成后,我给出了命令make,然后出现以下错误 GlobalParams.cc:81:35:致命错误:fontconfig / fontconfig.h:没有此类文件或目录编译终止。 make [3]: * [libpop
1回复

ARM项目中的BoardSupportLibrary链接错误

我在Code Composer Studio ver5中有一个ARM项目(用于通用ARM9设备)(实际上是经过修改的日食)。 项目属性: 我得到链接错误 这些功能的所有定义都在evmomapl138_bsl.lib中。 100% PS另外,我尝试将“ evmomapl138_bs