编译C代码的脚本

时间:2017-04-26 07:57:03

标签: c linux shell terminal

通常如果我想编译一个名为number_input.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:错误:没有输入文件   number_input.c

我可以说正确输入了名称,但由于某些原因,cc命令没有考虑$1的值?我假设$1不是直接转换成字符串或类似的东西,但我不确定。

2 个答案:

答案 0 :(得分:5)

您的错误在第一行,因为您没有为a分配任何内容:

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

可以解决问题(对于行为良好的文件名,至少,因为你的脚本中缺少引号)。 a之后的空格表示您为其分配空字符串,然后运行管道中的命令。

而不是全力以赴地翻转两次,只需用${1%??}删除最后两个字符:

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

答案 1 :(得分:1)

执行此操作的最常用工具是make。它从运行目录中名为Makefile的文件中读取配方,并执行任何必要的任务。它足够聪明,可以检查文件时间戳,以检测是否需要重新编译项目的哪些部分或哪些部分。这是一个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 $@

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

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

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

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

作为all中的第一个食谱的Makefile食谱是您运行make时所遵循的默认食谱。这个告诉我应该构建PROGS中列出的所有程序。

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

最后的食谱很棘手。它表示PROGS中列出的所有文件都是根据具有相同名称和.c后缀的文件构建的。 $^引用.c文件名,$@引用文件名,不带后缀。

如果此Makefile用于通过电子邮件向教师返回练习,我还会添加新的.PHONY目标tarball

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 $@

如果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是如此有用。