标签: gnu-make

带有许多目标目录的 GNU make

我必须在现有的 .html 文件中集成许多 HTML 文件的生成Makefile。问题是 HTML 文件需要驻留在许多不同的目录中。我的想法是写一个隐式规则,将源文件(*.st)转换成对应的html文件

%.html: %.st
    $(HPC) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

以及依赖于所有 html 文件的规则

all: $(html)
Run Code Online (Sandbox Code Playgroud)

如果 HTML 文件不在 builddir 中,则make找不到隐式规则:*** No rule to make target. 如果我像这样更改隐式规则

$(rootdir)/build/doc/2009/06/01/%.html: %.st  
    $(HPC) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

它找到了,但是我必须对项目中的几乎每个文件都有一个隐式规则。根据GNU手册中的隐式规则搜索算法make,规则搜索的工作方式如下:

  1. 将整个目标名称t拆分为目录部分,称为d,其余部分称为n。例如,如果tsrc/foo.o,则dsrc/,而nfoo.o
  2. 列出其中一个目标与tn匹配的所有模式规则。如果目标模式包含斜杠,则与t匹配;否则,针对n

为什么没有找到隐式规则,假设使用 GNU,最优雅的解决方案make是什么?

这是我的精简版Makefile: …

makefile gnu-make release-management build-management

4
推荐指数
1
解决办法
3764
查看次数

什么GNU makefile规则可以保证make的版本至少是v3.82?

我有一个 makefile,当使用旧版本的 gmake 时,它​​会出现不明显的故障。我想有一个规则来检查版本至少是 3.82 或更高版本。我已经得到了以下规则,但比较是脆弱的,我真的想要一个允许更高版本的比较:

GMAKE_VERSION :=  $(shell gmake --version | head -n 1 | sed 's/GNU Make //')

.PHONY: testMake
testMake:
    @if [ "$(GMAKE_VERSION)" != "3.82" ];               \
    then                                \
        echo >&2 "Unexpected gmakefile version "        \
            "$(GMAKE_VERSION), expecting 3.82 or later.";   \
        false;                          \
    fi
Run Code Online (Sandbox Code Playgroud)

什么GNU makefile规则可以保证make的版本至少是v3.82?

version gnu-make

4
推荐指数
1
解决办法
645
查看次数

gnuMake,如何强制假目标运行不止一次?

我的构建系统坚持在一次调用中对所有目标执行 make,所以我得到:

make clean test clean build

第二次清理只会说“没有为‘清理’做任何事情。” 即使它已添加到 .PHONY 目标。

有什么办法吗?

makefile build gnu-make

4
推荐指数
2
解决办法
2432
查看次数

Makefile:与子目录同名的规则被忽略

这是我的makefile:

all: first second

second:
    @echo "==Building second=="

first:
    @echo "==Building first=="
Run Code Online (Sandbox Code Playgroud)

如果存在名为的目录second,则makefile将完全忽略具有相同名称的规则.如果没有,一切正常.

请注意,无论second文件夹是否为Makefile,都会发生这种情况.

我在组织我的项目时遇到了这个问题:我考虑创建一个通用的Makefile,然后在每个目录中调用Makefile.所以对我来说,规则与文件夹的名称相同是很自然的.

解决方案很简单:更改Makefile中的规则名称...但这种行为似乎很奇怪:你对此有什么想法/见解,还有另一种可能的解决方案吗?

我在Ubuntu 12.04.2 LTS下使用Bash 4.2.25中的GNU Make 3.81.

makefile gnu-make

4
推荐指数
1
解决办法
1538
查看次数

在GNUMakefile路径中使用$ literal

我有 //here/is$/my/file(注意$)作为文件位置,并在GNUmakefile中指定

OutputFile = //here/is$/my/file
Run Code Online (Sandbox Code Playgroud)

问题是我需要以某种方式逃避$.我试过了\ $没有成功.

有谁知道如何做到这一点?

makefile gnu-make

4
推荐指数
1
解决办法
1550
查看次数

在 GNU 和 BSD Makefile 中运行命令并将结果存储到变量中

我想在 Makefile 中执行一个命令,将结果存储到一个变量中并稍后重用该结果。

在 BSD Makefile 中,我可以使用 != 运算符:

PASSWORD != openssl rand -base64 48
Run Code Online (Sandbox Code Playgroud)

在 GNU Makefile 中,我可以使用 shell 函数:

PASSWORD := $(shell openssl rand -base64 48)
Run Code Online (Sandbox Code Playgroud)

有没有办法以与两个 make 兼容的方式编写它?


预期输出

在这两种情况下,命令的结果都分配给 PASSWORD,因此我可以在 Makefile 中重用相同的 PASSWORD 值:

quux:
    @echo $(PASSWORD)
    @echo $(PASSWORD)
Run Code Online (Sandbox Code Playgroud)

如果我运行make quux,这将输出两次相同的密码。

例如:

$ gmake quux
Y0ZrQQqLF9JK98x9UiIwWwcCN2Cq1wNqzph3ShG1RK0NeqbxWn6p4XB5zgHvfnbY
Y0ZrQQqLF9JK98x9UiIwWwcCN2Cq1wNqzph3ShG1RK0NeqbxWn6p4XB5zgHvfnbY
Run Code Online (Sandbox Code Playgroud)

这与使用反引号运算符不同。在这种情况下,兼容两个make,每次都会运行命令。

makefile gnu-make

4
推荐指数
1
解决办法
1015
查看次数

"如何读取文件"的示例

在GNU-Make手册中,如何制作读取制作文件 https://www.gnu.org/software/make/manual/make.html#Reading-Makefiles部分说

GNU make在两个不同的阶段完成它的工作.在第一阶段,它读取所有makefile,包括makefile等,并内化所有变量及其值,隐式和显式规则,并构建所有目标及其先决条件的依赖关系图.在第二阶段,make使用这些内部结构来确定需要重建的目标,并调用执行此操作所需的规则.

我无法清楚地了解这两个阶段的差异.可能正在寻找一个有助于理解的例子.是否有任何链接或教程阐明了第一阶段和第二阶段到底发生了什么.

makefile gnu-make

4
推荐指数
1
解决办法
653
查看次数

如何在 GNU Make 中以编程方式定义目标?

我不知道有什么方法可以在 GNU Make 中以编程方式定义目标。这怎么可能?

有时可以使用替代方法离开。然而,在 Makefile 中以编程方式定义目标的能力对于使用make. 在 FreeBSD 的构建系统或诸如BSD Owl 之类的Makefile 库中可以找到复杂生成规则的示例

shell 脚本和 Makefile 之间的主要区别是:

  • 在 Makefile 中,程序的状态由命令行和文件系统给出,因此可以在作业中断后恢复作业。当然,这需要正确地编写 Makefile,但即使这相当困难,也比使用 shell 脚本实现类似的效果要容易得多。

  • 在 Makefile 中,用建议或钩子装饰一个过程是非常容易的,而这在 shell 脚本中基本上是不可能的。

例如,一个非常简单且有用的模式如下:

build: pre-build
build: do-build
build: post-build
Run Code Online (Sandbox Code Playgroud)

这将build目标呈现为三个目标的组合,一个包含实际指令do-build,另外两个是钩子,在 之前和之后执行do-build。许多为 BSD Make 编写的构建系统都使用这种模式,顺便说一下,它允许以编程方式定义目标,以便可以批量编写:

.for _target in configure build test install
.if !target(${_target})
${_target}: pre-${_target}
${_target}: do-${_target}
${_target}: post-${_target}
.endif
.endfor
Run Code Online (Sandbox Code Playgroud)

.if/.endif块引入的条件使用户能够使用自己对 any 的定义${_target}

GNU Make 的那个片段的翻译是什么?

makefile gnu-make bsdmake

4
推荐指数
1
解决办法
1674
查看次数

入侵qmake的Makefile的其他变量

在qmake的Makefile中,定义了一系列变量。我想再添加一个,由.pro文件定义。Makefile中的此部分如下所示:

DEL_DIR       = rmdir
MOVE          = mv -f
CHK_DIR_EXISTS= test -d
MKDIR         = mkdir -p
Run Code Online (Sandbox Code Playgroud)

我想补充:

TESTARGS     = -xunitxml -o xunitresults.xml
Run Code Online (Sandbox Code Playgroud)

关于原因的一些背景知识:当qmake使用“测试用例”创建Makefile时,它还会使“检查”目标看起来像这样:

check: first
         $(TESTRUNNER) ./$(QMAKE_TARGET) $(TESTARGS)
Run Code Online (Sandbox Code Playgroud)

在这里完整记录。

这对于自动单元测试确实非常强大!但是,我想在make文件的其他位置设置“ TESTARGS”。我怎样才能做到这一点?

qt qmake gnu-make

4
推荐指数
1
解决办法
399
查看次数

为什么make.exe尝试在Windows上运行/ usr / bin / sh?

我最近从Window 7迁移到Windows 10,无法继续使用我的makefile。

我一直在使用WindowsGNU Make

我注意到的第一件事是它已开始将Windows文件夹分隔符(反斜杠字符“ \”)视为行继续字符,因此我修改了“ clean”部分,如下所示,改为使用正斜杠“ /”字符:

clean:
    del $(ObjDir)/*.o
Run Code Online (Sandbox Code Playgroud)

当我打电话时make -ftest.mak clean,出现以下错误,这表明它现在正试图在MinGw / Cygwin环境中运行:

c:\Test\Source>make -ftest.mak clean
del obj/*.o
/usr/bin/sh: del: command not found
make: *** [clean] Error 127
Run Code Online (Sandbox Code Playgroud)

我的PC上确实有MinGw文件夹(已重命名以停止寻找它),并且在Cmd.exe环境或PATH中看不到任何与“ MingGw”相关的环境变量

我如何才能make工作,这样它就不会尝试sh在Windows下执行?

是否有一些配置参数可以调用它sh而不是cmd.exe

更新:刚刚尝试运行make -d来记录调试输出。好像它使用我的Git文件夹作为某种根文件夹:

Must remake target `clean'.
del obj/*.o
CreateProcess(NULL,C:/Program Files/Git/usr/bin/sh.exe -c "del obj/*.o",...)
Putting child 0x006e7fc0 (clean) PID 7234712 on the chain.
Run Code Online (Sandbox Code Playgroud)

mingw gnu-make windows-10

4
推荐指数
2
解决办法
4246
查看次数