脚本编译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
不是直接转换成字符串或类似的东西,但我不确定。
你的错误是在第一行,因为你并没有使用什么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
目标all
和clean
是“假的”,它们不生成该名称的文件。
作为Makefile
中的第一个配方,all
配方是在运行make
时遵循的默认配方。这说明应该建立PROGS
中列出的所有程序。
clean
配方(运行make clean
)从目录中删除所有临时文件和编译文件 - 基本上清除它。
最后的食谱是一个棘手的。它说PROGS
中列出的所有文件均由具有相同名称的文件加.c
后缀构建。 $^
指的是.c
的文件名,而[email protected]
指的是没有后缀的文件名。
如果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 [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
是如此有用。
你应该使用一个Makefile。 – piwi
你可以使用Makefile。你也可以使用CMake,或忍者,或bfg9000,或gyp,或... – You
...或者什么都不是,因为只有一个文件正在编译! –