蛋疼程序员:make用batch在Windows上的伪实现

DeathKing posted @ 2011年8月20日 09:49 in Geek with tags geek make makefile windows batch , 6349 阅读

  一个真正的好工具,你会爱不释手。当然,make就是这样的工具。

  我是一个不喜欢使用IDE的人(里面有太多我用不上的功能),我喜欢UNIX的哲学,喜欢用众多小工具来完成工作。并且,我也是个自由软件爱好者,因此,我在电脑里安装有各种自由软件的Windows版本:gccvimcurl等。
 

故事的起因


  今年的214日,我去成都参加了CD7,经过熟人的介绍,加入了一个游戏开发团队。但是由于他们已经开工,我便被分到了资源打包程序这一块上(生产力环境是Windows)。考虑到我是使用gccNotepad++,我便意识到,我需要一种高效的管理这些源文件的方法。这中方法应该满足下面的特性:

  • 简便,没有复杂的使用方法;
  • 轻巧,不会使用太大体积的工具;
  • 灵活,可以轻松的被扩展;

  因此,考虑到只是需要利用较短的命令去执行较长的命令,我打算使用一个批处理脚本来完成这个工作,而没有选择make for Windows,因为这就引入了新的工具,而且,我将会花一段时间去学习它。
 

设计规划


  这个工具将被命名为make.bat,并将接受至多一个参数,改参数指定了make所需要执行的目标(Target),如果没有指定该参数则会自动执行all目标。如果没有与指定参数相符合的目标,将会执行error目标,显示出错误信息后,程序会自动退出(跳转到endp标签)。

  可以使用变量代替LinuxMakefile中的“宏(Macro)”,但是make.bat不能处理诸如make install INSTDIR='D:\Program Files\'一类的替换宏定义。make.bat不负责检查依赖,make.bat也不用实现make中的字符处理函数等,因为这些都将加剧脚本的复杂程度。
 

工具实现


  首先,我们要在脚本开始处设置好“宏”,我们是用Batch的“环境变量”来实现的,使用@符号,是为了避免将回显显示在屏幕上:

@echo off
@set CC=gcc
@set CFLAGS=
@set CINCLU=
@set INSDIR=D:\code\myBin\

  开始处理,根据参数决定动作:

:start	
	if {%1}=={}               goto all
	if {%1}=={help}           goto help
	if {%1}=={test}           goto test
	if {%1}=={clean}          goto clean
	if {%1}=={debug}          goto debug
	if {%1}=={install}        goto install
	if {%1}=={uninstall}      goto uninstall
	goto error

  我们已经强调过意图,如果第一个参数为空,那么跳转到all标签,如果不为空,则跳转到对应标签,否则跳转到error标签。或许每个工程对应的目标不一样,根据不同的需求调整就行了,因为这个工具是灵活的。

  然后编辑all标签,处理编译文件的命令:

:all
	echo Compiling....
	%CC% %CFLAGS% %CINCLU% -o cDzip.exe d_main.c
	echo Done
	goto endp

  我是用我的工程为大家做示范,不同的工程会不一样。make.bat会首先使用一个回显提示用户正在编译文件(编译完成后回向屏幕输出一个Done来标识完成编译),然后执行命令来编译文件。分别使用%CC%%CFLAGS%%CINCLU%来对变量求值,这样会具有可移植性(或许有些编译器压根就不支持-o选项,笑),或许? 

:test
	echo Compiling....
	%CC% %CFLAGS% %CINCLU% -o test.exe d_main.c
	echo Test the -r Options with README.dpk
	test.exe -r README.dpk
	echo Test the -l Options with out.dpk
	test.exe -l out.dpk
	goto endp

  test命令用于检查编译出来的程序是否能够正常工作,这一步在Release前对程序进行测试很有用。而debug目标,则是为编译的文件加上-g选项,以支持gdb调试。

:debug
	%CC% %CFLAGS% %CINCLU% -g -o debug.exe d_test.c
	goto endp

  clean目标清除编译好的程序,因为我们没产生什么目标文件。并且你完全可以只写del target_program.exe,因为即使target_program.exe,程序也只会在屏幕上输出找不到文件,而不会停止:

:clean
	if exist cDzip.exe del cDzip.exe
	if exist debug.exe del debug.exe
	if exist test.exe  del test.exe
	goto endp

  installunistall目标,安装或卸载程序:

:install
	if exist cDzip.exe (
		copy cDzip.exe %INSDIR%cDzip.exe
	) else (
		echo Error: File not exists, please run make first.
	)
	goto endp
	
:uninstall
	if exist %INSDIR%cDzip.exe del %INSDIR%cDzip.exe
	goto endp

  errorhelp目标,error目标无法由外部调用:

:error
	echo Bad command!
	echo Use make help to know more.
	goto endp

:help
	echo.
	echo You can use follows commands
	echo   make             /* to make the program */
	echo   make install     /* to install the program */
	echo   make uninstall   /* to uninstall the program */
	echo   make test        /* to make the program and test */
	echo   make debug       /* to make the debug program */
	echo   make clean       /* clean the cDzip.exe and debug.exe */
	echo   make help        /* show help version */
	goto endp

  这样,一个伪的Windows下的Makefile就实现了,是集makeMakefile的一齐实现,并和他们有点不一样。
 

后序


  现在比以前少打了不少命令,而且还可以实现一些有趣的效果,不过,我至始至终感觉到……一丝蛋疼。

Avatar_small
λ 说:
2011年8月21日 20:26

我是来观察你的版面的……这页的右上角没有显示后一篇(还是前一篇?)文章,我用的 Chromium 。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter