前阵子实现了一个CodeWarrior嵌入式开发环境的自动编译环境,用的基本上是Python。说起来,我觉得那个环境还是很实用的。虽说还有很多可以改进的地方,但是总觉得能用就好了,不想去做那么多的补丁。
虽说自己从事的是汽车电子嵌入式开发,但是很多时候各种代码正确或者错误的测试我都是借助于gcc,编译一下直接打印出执行结果。虽说方法很烂,但是通常这么简单的一个功能已经足以让我去定位绝大多数的问题。不过,有时候文件多的时候确实也需要自己写个简单的makefile,一来二去,厌烦了重复劳作的我有了写个简单小工具的想法。参考之前的CodeWarrior实现,只是这次改成了Perl,因为我接触的计算机环境中Perl更为普遍适用一些。
本次实现的功能很不完整,实用功能是最主要的指标,其他的功能能省则省。makefile的生成也只完成了文件的编译和链接功能,但是我觉得这已经足以覆盖90%以上的需求。make工具使用了gmake,从MATLAB的安装目录中找到的,gcc是安装草莓Perl时打包安装的。中间用到了一点点DOS
CMD命令,测试的平台为Windows10 HB。
我的最小工程demo如下:
一个main.c文件,两个以文件夹划分的模块。设计的时候把所有的object文件生成在同一个文件夹,名为objects,最终可执行程序的名称在Perl程序中指定。
原始工程目录树如下:
makefile构建功能在make.pl中实现,具体的代码如下(使用截图是为了有更好的格式与语法显示,路过感兴趣的可以自己抄一遍或者跟我联系索取,联系方式在文章开头已经提供):
为了能够让工程更完善一些,我把gmake加入到了环境变量,而make与clean则全都用Windows的批处理简单实现了一下。具体的测试结果如下:
1. 运行Perl程序,生成makefile
生成的makefile内容如下:
CC = gcc
test_project : main.o test1.o
test2.o
gcc -o
D:\workspace\Perl\maketools\test_project main.o test1.o
test2.o
main.o: D:\workspace\Perl\maketools\main.c
C:/Strawberry/c/i686-w64-mingw32/include/stdio.h
\
C:/Strawberry/c/i686-w64-mingw32/include/crtdefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_mac.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_secapi.h
\
C:/Strawberry/c/i686-w64-mingw32/include/vadefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_directx.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_ddk.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_push.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_off_t.h
\
C:/Strawberry/c/i686-w64-mingw32/include/swprintf.inl
\
C:/Strawberry/c/i686-w64-mingw32/include/sec_api/stdio_s.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_pop.h
\
D:\workspace\Perl\maketools\test1/test1.h
\
D:\workspace\Perl\maketools\test2/test2.h
$(CC) -c -o $@ $< -I
D:\workspace\Perl\maketools -I D:\workspace\Perl\maketools\objects
-I D:\workspace\Perl\maketools\test1 -I
D:\workspace\Perl\maketools\test2
test1.o:
D:\workspace\Perl\maketools/test1\test1.c
C:/Strawberry/c/i686-w64-mingw32/include/stdio.h
\
C:/Strawberry/c/i686-w64-mingw32/include/crtdefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_mac.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_secapi.h
\
C:/Strawberry/c/i686-w64-mingw32/include/vadefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_directx.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_ddk.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_push.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_off_t.h
\
C:/Strawberry/c/i686-w64-mingw32/include/swprintf.inl
\
C:/Strawberry/c/i686-w64-mingw32/include/sec_api/stdio_s.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_pop.h
$(CC) -c -o $@ $< -I
D:\workspace\Perl\maketools -I D:\workspace\Perl\maketools\objects
-I D:\workspace\Perl\maketools\test1 -I
D:\workspace\Perl\maketools\test2
test2.o:
D:\workspace\Perl\maketools/test2\test2.c
C:/Strawberry/c/i686-w64-mingw32/include/stdio.h
\
C:/Strawberry/c/i686-w64-mingw32/include/crtdefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_mac.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_secapi.h
\
C:/Strawberry/c/i686-w64-mingw32/include/vadefs.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_directx.h
\
C:/Strawberry/c/i686-w64-mingw32/include/sdks/_mingw_ddk.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_push.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_off_t.h
\
C:/Strawberry/c/i686-w64-mingw32/include/swprintf.inl
\
C:/Strawberry/c/i686-w64-mingw32/include/sec_api/stdio_s.h
\
C:/Strawberry/c/i686-w64-mingw32/include/_mingw_print_pop.h
$(CC) -c -o $@ $< -I
D:\workspace\Perl\maketools -I D:\workspace\Perl\maketools\objects
-I D:\workspace\Perl\maketools\test1 -I
D:\workspace\Perl\maketools\test2
虽说这种makefile比较冗长难维护,但是其实我们的工具本来就是解决这样的问题的,只要编译能够顺利执行,我们并不需要特别在意makefile的具体内容。
2. 进行编译功能的测试
这样,简单的编译功能已经实现。
3. 编译结果执行
到此,一个简单可以用于日常代码测试的工具已经实现。值得注意的是,中间固定死了主函数所在的文件名以及位置。至于目录层级,其实这个工具支持还算是良好。