标签: gnu-make

我需要帮助减少 makefile 中的依赖项

我为生成一个简单的网页创建了一个 makefile。makefile 背后的想法是这样的:

  • 我们正在编译一个网页,index.html
  • index.html 需要main.sty必须编译的手写笔 css
  • 页面中使用了许多示例
    • 例如,代码one位于lib/examples/one
    • 每个示例包含三个部分
      • 标记(.jade模板文件)
      • 一些代码(一个.coffee脚本文件)
      • 描述(.md降价文件)
  • 构建脚本必须将每个示例呈现为单个 html 文件
    • Jade、Pygments、Markdown 生成三个html文件
    • 一个example.jade模板用于这些组合成一个示例文件
      • example.jade必须复制到正确的构建示例目录,因为模板语言只能做相对导入。因此,为了导入example/one/code.html,我们必须将模板复制到example/one并包含它code.html
    • 完成后,每个示例x都将编译为tbuild/examples/x.html
  • lib/index.jade模板被移动到build(以便它可以包括示例文件)
  • 然后使用 Jade 将index.jade模板编译为 html

这有点简化,但这样更容易理解。简化是每个例子中实际上有两个标记文件(left.html和right.html),并且代码文件都是通过pygments运行作为脚本使用的,所以code.html和code.coffee都需要使其成为构建。

现在,makefile 看起来像这样:

LIB = lib
BUILD = build
LIBEX = $(LIB)/examples
BUILDEX = $(BUILD)/examples
EXAMPLES = $(addsuffix .html,$(addprefix $(BUILDEX)/,$(shell ls …
Run Code Online (Sandbox Code Playgroud)

makefile gnu-make

5
推荐指数
1
解决办法
325
查看次数

GNU make:定时构建,是否可能有一个目标,其配方在所有目标完成后执行

我的问题类似于this onethis one

从本质上讲,类似以下内容是我正在寻找的东西——或者是一个相当干净的技巧来实现它:

GET_TIMESTAMP  = $(shell perl -e 'print time()')
START_TIME    := ${GET_TIMESTAMP}

all: T1 T2 ... TN

T1:
T2:
...:
TN:

#...

timer:
  @perl -e 'printf( "Loaded makefiles in %ds, build completed in %ds\n", $ARGV[1] - $ARGV[0], $ARGV[2] - $ARGV[1] );' ${START_TIME} ${LOAD_COMPLETE} ${GET_TIMESTAMP}

.ATEND: timer

LOAD_COMPLETE := ${GET_TIMESTAMP}
Run Code Online (Sandbox Code Playgroud)

...可以通过多种方式启动:

~ gmake all
(...)
  Loaded makefiles in 8s, build completed in 93s
~ gmake T2 T3 T4
(...)
  Loaded makefiles in 8s, build completed …
Run Code Online (Sandbox Code Playgroud)

gnu-make

5
推荐指数
1
解决办法
4186
查看次数

具有多个依赖项的 Makefile 目标

我有一个小脚本,可将 Markdown 文件编译为 html,并将其与一些样式表和 javascript 一起插入到模板的主体中。我有一个 GNU makefile 来完成这个:

output.html: content.md compile.py style.css script.js
    python compile.py < $< > $@
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我收到错误:

make: *无规则生成目标style.css', needed byoutput.html'。停止。

如果我删除compile.pystyle.cssscript.js,目标将运行,但它不再依赖于文件,因此我可以在 中进行更改style.css,并且不会重新运行目标。

所有这些文件都在同一目录中:

my_project_directory/
    content.md
    compile.py
    style.css
    script.js
Run Code Online (Sandbox Code Playgroud)

如何在不导致错误的情况下将所有这些文件声明为依赖项?

makefile gnu-make

5
推荐指数
1
解决办法
8670
查看次数

当 PHONY 依赖项更新时,为什么 make 不考虑没有配方过时的目标?

.PHONY: b
c: a
    @touch c
    @echo "Changed"
a: b
b:
    @date +%s > a
Run Code Online (Sandbox Code Playgroud)

使用示例 make 文件运行 make 会导致在第一次运行时打印“Changed”;但是“已更改”仅在第 3 次、第 5 次等执行时打印。这是因为 make 似乎没有意识到执行目标“b”的配方会更新 a。

将“a”作为目标的规则更改为空配方会导致每次 make 运行时打印“Changed”(正如您所期望的 - 虚假目标始终被视为“过时”)。例如

a: b ;
Run Code Online (Sandbox Code Playgroud)

Make 应该跳过对 PHONY 目标的隐式规则搜索,但“a”不是 PHONY。如果没有找到“a”的隐含规则,是否正确地不考虑“a”可能已被其 PHONY 依赖“b”改变?

makefile gnu-make

5
推荐指数
1
解决办法
1038
查看次数

使用 nmake.exe windows 在 makefile 中无法识别 addprefix 命令

all: prd.exe

CC=cl
CFLAGS=-O2 -I../src -I. /W4
LDFLAGS = /Zi
LIBSRC = $(addprefix ../lib/, \
        open.c malloc.c \
     ) \
     $(addprefix ../src/, \
        main.c \
      ) \
      helper.c

LIBOBJS = $(LIBSRC:.c=.o)

prd.exe: ../src/main.obj
$(CC) $(LDFLAGS) -Fe$@ *.o

../src/main.obj: ../src/main.c
$(CC) $(CFLAGS) $(LIBOBJS) -c $< -Fo $@ 

.c.o:
$(CC) $(CFLAGS) $(LIBOBJS) -c $< -Fo $@ 

.c.i:
$(CC) $(CFLAGS) $(LIBOBJS) -C -E $< > $@

clean:
del /s /f /q ..\lib\*.o ..\src\*.o *.o *.exe *.pdb

distclean: clean
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

致命错误 U1000:语法错误 : ')' …

windows nmake makefile gnu-make

5
推荐指数
1
解决办法
1362
查看次数

在 makefile 中使用“空目标”

最近我一直在尝试了解 GNU Make 的概念。在阅读时,我遇到了一个名为Empty Target的话题。从GNU Make 手册我了解到的是

空目标是虚假目标的变体;它用于保存您不时明确请求的操作的配方。与虚假目标不同,该目标文件可以真正存在;但文件的内容无关紧要,通常是空的。

空目标文件的目的是用它的最后修改时间记录规则的配方最后一次执行的时间。这样做是因为配方中的命令之一是更新目标文件的触摸命令。

另一个来源,我读到这样的东西

空目标类似于虚假目标,因为目标本身被用作利用 make 功能的设备。虚假目标总是过时的,所以它们总是执行并且它们总是导致它们的依赖(与先决条件相关联的目标)被重新制作。但是假设我们有一些命令,没有输出文件,只需要偶尔执行,我们不希望我们的依赖项更新?为此,我们可以制定一个规则,其目标是一个空文件(有时称为 cookie):

prog: size prog.o
$(CC) $(LDFLAGS) -o $@ $^

size: prog.o
size $^
touch size
Run Code Online (Sandbox Code Playgroud)

请注意,大小规则在完成后使用 touch 创建一个名为 size 的空文件。这个空文件用于它的时间戳,因此只有当 prog.o 被更新时,make 才会执行大小规则。此外,prog 的大小先决条件不会强制更新 prog,除非它的目标文件也更新。

从阅读他们我明白的是

  • 空目标用于维护时间戳
  • 空目标的内容没有兴趣,只有更新时间。

为了进行一些实践,我编写了两个示例 makefile

生成文件 1

空目标使用

prog: size prog.o
    gcc -o $@ prog.o

size: prog.o
    size $<
    touch size

prog.o: prog.c
    gcc -c $<
Run Code Online (Sandbox Code Playgroud)

输出

[sourav@localhost Practice]# make
gcc -c prog.c
size prog.o
   text …
Run Code Online (Sandbox Code Playgroud)

c makefile gnu-make

5
推荐指数
1
解决办法
5715
查看次数

如何将宏定义作为参数传递?

我希望通过将它作为参数传递来定义一个C宏make,这是从命令行调用的.

背景:#define ENABLE_OPT 1当选择某个构建选项时,我希望该指令包含在我的C源代码中.因此,我希望通过make命令行完成此操作,而不是修改源代码 makefile.

怎么能实现这一目标?我发现make -DENABLE_OPT=1 -f Makefile抛出错误"E","N"等是无效的参数.

c macros makefile gnu-make

5
推荐指数
1
解决办法
193
查看次数

Makefile中的词典/地图/查找表

我需要在Makefile中创建一个查找表/字典/映射来查找键值信息.

我一直在尝试使用ifeq语句来做同样的事情,但我的陈述似乎失败了:

# this gets the account id from the current user's ARN, you must have the AWS CLI and jq installed
AWS_ACCOUNT_ID:=$(shell aws iam get-user | jq -r '.User.Arn' | awk -F ':' '{print $$5;}')

# define a friendly account name for output
ifeq ($(AWS_ACCOUNT_ID), 123456)
AWS_ACCOUNT_FRIENDLY:=staging
endif

ifeq ($(AWS_ACCOUNT_ID), 789012)
AWS_ACCOUNT_FRIENDLY:=preprod
endif

ifeq ($(AWS_ACCOUNT_ID), 345678)
AWS_ACCOUNT_FRIENDLY:=production
endif
Run Code Online (Sandbox Code Playgroud)

它似乎只适用于第一个值123456而不适用于其他值.

有没有办法在Make中定义字典/地图,只需通过帐户ID的密钥查找帐户友好名称?

makefile gnu-make

5
推荐指数
1
解决办法
2922
查看次数

非常基本:为什么我的makefile不能使用普通后缀

objects = hello.o name.o printing.o
exename = himake

$(exename): $(objects)
    $(CC) -o $(exename) $(objects)

%.o: %.cpp
    $(CC) -c  $^
Run Code Online (Sandbox Code Playgroud)

我试图使用常见的后缀,所以我不需要先将3个文件编译成.o.这应该是使用%通配符完成所有三个.

我做的很长,但不是这样.

运行上面的makefile给出了以下错误:

[alex@pcc Dir]$ make
cc -o himake hello.o name.o printing.o
hello.o: In function `__static_initialization_and_destruction_0(int, int)':
hello.cpp:(.text+0x23): undefined reference to `std::ios_base::Init::Init()'
hello.o: In function `__tcf_0':
hello.cpp:(.text+0x66): undefined reference to `std::ios_base::Init::~Init()'
Run Code Online (Sandbox Code Playgroud)

还有更多,我没有包括

文件:hello.cpp:

// hello.cpp

// standard library
#include <iostream>
#include <string>
using namespace std;

// user defined header files
#include "name.h"
#include "printing.h"

int main ()
{
    string name;

    name …
Run Code Online (Sandbox Code Playgroud)

c++ makefile gnu-make

5
推荐指数
1
解决办法
66
查看次数

软件基础 - 自动评分

为了学习Coq,我从这里下载了Benjamin Pierce的电子书软件基础,并提取了内容.我现在开始通过直接在Vim中编辑文件来完成练习.Basics.v

我想自动评分我的答案(例如跟踪我的得分与时间的关系).

为此做准备,我按照中给出的顺序coqc对每个.v文件进行了运行Makefile.因此,我现在可以调用,例如coqtop -batch -l BasicsTest.v.

但是,虽然这会报告该章的可用分数,但它不会报告我的分数.(我在本章的中途,我相信到目前为止我的答案是正确的,因为coqtop -batch -l Basics.v执行没有错误.)

我怀疑我忽略了Make或Coq的调用,这将为我的答案产生一个得分.如果是这样,它是什么?

makefile gnu-make coq

5
推荐指数
2
解决办法
319
查看次数

标签 统计

gnu-make ×10

makefile ×9

c ×2

c++ ×1

coq ×1

macros ×1

nmake ×1

windows ×1