脚本编译C代码

问题描述:

通常如果我想编译称为number_input.c一个C程序,我会键入脚本编译C代码

cc -o number_input number_input.c 

我想用我的Mac终端做一个脚本,这样我就不必键入额外的词。最初我为了节省自己1秒的编程,但讽刺的是我花了2个多小时试图让这个工作。

a= echo "$1" | rev | cut -c3- | rev 
echo $a 
cc -o $a $1 
echo $1 

这是我的输出:

number_input

clang: error: no input files number_input.c

我可以告诉大家,名字都被正确输入,但由于某些原因,cc命令没有在$1价值服用?我假设$1不是直接转换成字符串或类似的东西,但我不确定。

+1

你应该使用一个Makefile。 – piwi

+1

你可以使用Makefile。你也可以使用CMake,或忍者,或bfg9000,或gyp,或... – You

+1

...或者什么都不是,因为只有一个文件正在编译! –

你的错误是在第一行,因为你并没有使用什么a

a=$(echo "$1" | rev | cut -c3- | rev) 

将解决该问题(乖巧的文件名,至少,因为你缺少进一步的报价在你的脚本中)。 a之后的空格表示您正在为其分配空字符串,然后在管道中运行命令,然后

而是要扭转两次的一切努力,只是${1%??}删除最后两个字符:

cc -o "${1%??}" "$1" 

最常用的工具,要做到这一点make。它从运行的目录中的名为Makefile的文件中读取配方,并执行必要的任何任务。它足够聪明地检查文件时间戳,以检测是否需要重新编译项目的哪些部分或哪些部分需要重新编译。下面是一个例子生成文件:

CC  := gcc 
CFLAGS := -Wall -O2 
LDFLAGS := -lm 

PROGS := number_input 

.PHONY: all clean 

all: $(PROGS) 

clean: 
    rm -f $(PROGS) 

$(PROGS): %: %.c 
    $(CC) $(CFLAGS) $^ $(LDFLAGS) -o [email protected] 

注意的是Makefile缩进必须使用制表符,而不是空格。如果您复制上述内容并粘贴到文件中,则需要运行sed -e 's|^ *|\t|' -i Makefile来修复缩进。

前三行命名使用的编译器,编译器选项和链接选项。您的特定用例不需要-lm链接选项;我只是将它包含在内,因为您迟早会想要使用<math.h>,然后您确实需要包含-lm链接选项。

PROGS行命名你的程序。您可以指定多个,只需用空格分隔即可。

.PHONY:行告诉make目标allclean是“假的”,它们不生成该名称的文件。

作为Makefile中的第一个配方,all配方是在运行make时遵循的默认配方。这说明应该建立PROGS中列出的所有程序。

clean配方(运行make clean)从目录中删除所有临时文件和编译文件 - 基本上清除它。

最后的食谱是一个棘手的。它说PROGS中列出的所有文件均由具有相同名称的文件加.c后缀构建。 $^指的是.c的文件名,而[email protected]指的是没有后缀的文件名。

如果Makefile被用于通过电子邮件返回练习,老师,我还添加了新的目标.PHONYtarball

CC  := gcc 
CFLAGS := -Wall -O2 
LDFLAGS := -lm 

PROGS := number_input 
TAR  := $(notdir $(CURDIR)).tar 

.PHONY: all clean tarball 

all: $(PROGS) 

clean: 
    rm -f $(PROGS) 

tarball: clean 
    rm -f ../$(TAR) 
    tar -cf ../$(TAR) $(notdir $(CURDIR))/ 

$(PROGS): %: %.c 
    $(CC) $(CFLAGS) $^ $(LDFLAGS) -o [email protected] 

运行make将编译number_input,如果number_input.c后已被修改最后一次编译number_input,或者number_input尚不存在。

运行make TAR=myname-ex01.tar tarball从当前目录中删除已编译的文件,然后创建当前目录(及其子目录,如果有的话)的tarball,作为myname-ex01.tar。如果只运行make tarball,则tar文件名将与当前目录的名称相同,但后缀为.tar

我希望你能明白为什么写Makefile是如此有用。