EtherCAT学习笔记——修改Makefile

系列文章目录

第一章 LinuxCNC与EtherCAT

第二章 安装LinuxCNC

第三章 基于Preempt -RT的IgH EtherCAT Master安装

第四章 基于Xenomai3.1的IgH EtherCAT Master安装

第五章 基于RTAI的IgH EtherCAT Master安装

第六章 修改MakeFile

杂记: Linux配置杂记


目录

系列文章目录

前言

一、Makefile解析

二、Makefile修改

三、编译结果

总结

参考链接


前言

        修改Igh EtherCAT主站的Makefile,实现基于例子的多文件编译


一、Makefile解析

        在还没进行Makefile的修改时,在main函数中添加在test.c中的函数test(),即使已经做好头文件的包含和声明,由于Makefile的编译并没有链接,所以会产生未定义的错误,如图1

图1 编译错误——函数未定义引用

         对Makefile的规则进行了解后(1),找到问题的关键在“目标:依赖”这一项中。

        对原来的例程进行一次清理和重新生成后,我们可以知道目标的名字是什么,代码如下。

sudo make clean
sudo make

        本文的路径为/ethercat_test/examples/dc_user (test),生成的目标名为ec_dc_user_example,因此以此为关键词在Makefile中搜索,可得结果如图2

图2 目标:依赖
ec_dc_user_example$(EXEEXT): $(ec_dc_user_example_OBJECTS) $(ec_dc_user_example_DEPENDENCIES) $(EXTRA_ec_dc_user_example_DEPENDENCIES) 
	@rm -f ec_dc_user_example$(EXEEXT)
    $(AM_V_CCLD)$(ec_dc_user_example_LINK) $(ec_dc_user_example_OBJECTS) $(ec_dc_user_example_LDADD) $(LIBS)

        对第一行的代码进行解析,第一行代码顶格,从Makefile规则可知此行代码为编译规则,其中

        ec_dc_user_example_OBJECTSec_dc_user_example-main.o;

        ec_dc_user_example_DEPENDENCIES为空;

        EXTRA_ec_dc_user_example_DEPENDENCIES为空。

        因此该指令为ec_dc_user_examples: ec_dc_user_example-main.o,其中ec_dc_user_example-main.o依赖main.c

        第二行代码前方有tab,因此为指令:@rm -f ec_dc_user_example$(EXEEXT),作用是删除已经存在的目标文件

        第三行代码前也有tab,因此为指令:$(AM_V_CCLD)$(ec_dc_user_example_LINK) $(ec_dc_user_example_OBJECTS) $(ec_dc_user_example_LDADD) $(LIBS),其中

$(AM_V_CCLD):@echo " CC " $@;

$(ec_dc_user_example_LINK)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@,再对其中的各个变量进行解析。

        $(LIBTOOL) $(AM_V_lt):/bin.bash ../../libtool -silent;

        $(AM_LIBTOOLFLAGS)、$(LIBTOOLFLAGS):未定义;

        $(CCLD):gcc;

        $(AM_CFLAGS):未定义

        $(CFLAGS):-g -O2

        $(AM_LDFLAGS)、$(LDFLAGS) :未定义

$(ec_dc_user_example_OBJECTS)ec_dc_user_example-main.o

$(ec_dc_user_example_LDADD) $(LIBS):未定义

         因此该指令实际为:@echo " CC " $@/bin.bash ../../libtool -silent --mode=link gcc -g -O2 -o @ec_dc_user_example-main.o

小结: ec_dc_user_examples: ec_dc_user_example-main.o可知,当前的目标的依赖文件只有main.o,而main.o依赖main.c,但实际上,经过修改的main()调用了在test.c中的test(),因此目标的依赖文件应该为main.o和test.o,因为缺少依赖,所以会出现如图1的错误。

二、Makefile修改

        从上面的解析可知,编译失败的原因是缺少依赖文件,因此,只需要在保证头文件路径正确的前提下,在头文件文件夹中加入test.h,并在ec_dc_user_examples: ec_dc_user_example-main.o命令中添加目标的test.o依赖。

        上面的目标生成指令中,有ec_dc_user_example_DEPENDENCIES和EXTRA_ec_dc_user_example_DEPENDENCIES两个变量并未使用,因此我选择了EXTRA_ec_dc_user_example_DEPENDENCIES变量作为我的外部文件的依赖定义,如图3

图3 外部文件依赖定义

         对目标文件的指令进行修改,将ec_dc_user_example_DEPENDENCIES和EXTRA_ec_dc_user_example_DEPENDENCIES加入到指令中,修改结果如下

ec_dc_user_example$(EXEEXT): $(ec_dc_user_example_OBJECTS) $(ec_dc_user_example_DEPENDENCIES) $(EXTRA_ec_dc_user_example_DEPENDENCIES) 
	@rm -f ec_dc_user_example$(EXEEXT)
	$(AM_V_CCLD)$(ec_dc_user_example_LINK) $(ec_dc_user_example_OBJECTS) $(ec_dc_user_example_DEPENDENCIES) $(EXTRA_ec_dc_user_example_DEPENDENCIES) $(ec_dc_user_example_LDADD) $(LIBS)

        然后再添加对test.o的生成规则,可以仿照已有的进行修改,如下代码

test.o: test.c
	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_dc_user_example_CFLAGS) $(CFLAGS) -MT test.o -MD -MP -MF $(DEPDIR)/test.Tpo -c -o test.o `test -f 'main.c' || echo '$(srcdir)/'`test.c
	$(AM_V_at)$(am__mv) $(DEPDIR)/test.Tpo $(DEPDIR)/test.Po

        其中,生成指令中的ec_dc_user_example_CFLAGS已经指定了头文件目录,在头文件目录中加入test.h头文件,即可编译。

三、编译结果

        test()函数功能如下:

#include "test.h"

void test()
{
	printf("**********************\n");
	printf("yes:%d",1+1);
}

        编译结果如图4、图5,生成了ec_dc_user_example、ec_dc_user_example.o、test.o三个文件。

图4 编译结果

       

图5 编译生成的文件

运行结果如图6,可以看见test()函数已调用并成功打印。

图6 ec_dc_user_example运行结果

四、Makefile和源文件在不同文件夹内的编译

        当我建立了一个src文件夹用来放置.c文件,同时makefile在src的上级目录,此时我需要告诉makefile去哪里找.c文件,需要用到这句指令。

vpath %.c ./src

        同时修改规则中的指令,在main.c前增加路径。

	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_dc_user_example_CFLAGS) $(CFLAGS) -MT ec_dc_user_example-main.o -MD -MP -MF $(DEPDIR)/ec_dc_user_example-main.Tpo -c -o ec_dc_user_example-main.o `test -f 'main.c' || echo '$(srcdir)/'`$(SRCDIR)/main.c

总结

        对于如何修改Makefile文件使之可以进行多文件编译,实现模块化编程的关键就在于对目标的生成规则进行完善,并将头文件放置在正确的位置。


参考链接

  1. Makefile入门(超详细一文读懂)_晨曦艾米的博客-CSDN博客
  2. makefile与源文件不一目录解决办法
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值