【问题标题】:Script to compile C code用于编译 C 代码的脚本
【发布时间】:2017-04-26 07:57:03
【问题描述】:

通常如果我想编译一个名为 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

这是我的输出:

数字输入

clang:错误:没有输入文件 number_input.c

我可以看出名称输入正确,但由于某种原因cc 命令没有接受$1 的值?我假设$1 不会以某种方式直接转换为字符串或类似的东西,但我不确定。

【问题讨论】:

  • 你应该使用 Makefile。
  • 可以使用 Makefile。你也可以使用 CMake,或者 Ninja,或者 bfg9000,或者 gyp,或者......
  • ...或者什么都没有,因为只编译了一个文件!

标签: c linux shell terminal


【解决方案1】:

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

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

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

与其竭尽全力反转两次,只需删除带有${1%??}的最后两个字符:

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

【讨论】:

    【解决方案2】:

    最常用的工具是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 $@
    

    如果在上次编译 number_input 之后修改了 number_input.c,或者如果 number_input 尚不存在,则运行 make 将编译 number_input

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多