标签: gnu-make

这个 Makefile 如何在不指定编译器的情况下制作 C 程序?

我使用的是“ Advanced Linux Programming (2001)” [code]一书中的 Makefile 。我很奇怪看到GNU make确实正确编译了代码,甚至没有在 Makefile 中指定编译器。这就像没有任何食谱烘焙!

这是代码的最小版本:

测试.c

int main(){}
Run Code Online (Sandbox Code Playgroud)

生成文件

all:            test
Run Code Online (Sandbox Code Playgroud)

并真正起作用!这是它执行的命令:

cc     test.c   -o test
Run Code Online (Sandbox Code Playgroud)

我在文档中找不到任何有用的东西。这怎么可能?


PS 额外说明:连语言都没有指定;因为test.c可用,GNUmake使用cc. 如果存在test.cpptest.cc(当没有时test.c),它使用g++(而不是c++)。

linux make gcc gnu-make

42
推荐指数
1
解决办法
4326
查看次数

在哪里可以找到“make”错误代码列表?

我正在尝试编译一个用 Fortran 编写的程序make(我有一个Makefile,在包含Makefile的目录中,我输入命令$ make target,其中“目标”是我的Makefile 中存在的系统特定的目标规范。正如我对我的目标规范的各种修订进行试验,我在尝试调用 时经常收到各种错误消息make。举几个例子:

make[1]: Entering directory
/bin/sh: line 0: test: too many arguments
./dpp   angfrc.f > angfrc.tmp.f
/bin/sh: ./dpp: Permission denied
make[1]: *** [angfrc.o] Error 126
make[1]: Leaving directory
make: *** [cmu60] Error 2
Run Code Online (Sandbox Code Playgroud)

make[1]: Entering directory
/bin/sh: line 0: test: too many arguments
./dpp -DSTRESS -DMPI -P -D'pointer=integer'-I/opt/mpich_intel/include  angfrc.f > angfrc.tmp.f
/bin/sh: ./dpp: Permission denied
make[1]: *** [angfrc.o] Error 126
make[1]: Leaving …
Run Code Online (Sandbox Code Playgroud)

make error-handling gnu-make

28
推荐指数
2
解决办法
16万
查看次数

如果命令失败,不要停止 make'ing,但检查退出状态

我试图指示 GNU Make 3.81 在命令失败时不要停止(所以我在命令前加上-),但我还想检查下一个命令的退出状态并打印一条信息更丰富的消息。但是我下面的 Makefile 失败了:

$ cat Makefile 
all:
    -/bin/false
    ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!
Run Code Online (Sandbox Code Playgroud)

为什么上面的 Makefile 回显“成功!” 而不是“失败!” ?

更新:

遵循并扩展已接受的答案,以下是它的书写方式:

failure:                                                                                                                                                                                                                                      
    @-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"                                                                                                                                                                 
success:                                                                                                                                                                                                                                      
    @-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo …
Run Code Online (Sandbox Code Playgroud)

make gnu-make

28
推荐指数
3
解决办法
7万
查看次数

如何将makefile中给出的依赖项显示为树?

问题

我想查看一个 makefile 的一个或多个目标的依赖关系。所以我正在寻找一个程序,它可以解析生成文件,然后以某种树状格式(缩进,ascii-art,...)或图形(点,...)表示依赖关系。

相似的

有些程序可以针对其他情况执行此操作:

  • pactreeDebree可以以树状(如 ascii 格式或dot图形)的形式显示软件包的依赖关系,
  • gcc -M source_file.c 将 C 源文件的依赖项显示为 make 规则,
  • pstree显示进程树的 ascii 表示。

进步

在网上搜索我发现几乎没有帮助。这让我尝试

make --always-make --silent --dry-run some_target | \
  grep --extended-regexp 'Considering target file|Trying rule prerequisite'
Run Code Online (Sandbox Code Playgroud)

但看起来我必须在 perl 或 python 中编写更多解析代码才能将其表示为一个漂亮的树/图。而且我还不知道我是否真的会以这种方式获得完整和正确的图表。

要求

以某种方式限制图形会很好(没有内置规则,只有给定的目标,只有一定的深度),但在大多数情况下,我只是在寻找一种工具,它会给我一些“合理”的依赖关系,人类- 可视格式(就像“类似”下的程序一样)。

问题

  • 有没有可以做到这一点的程序?
  • 我会从 获得完整和正确的信息make -dnq ...吗?
  • 有没有更好的方法来获取这些信息?
  • 解析此信息的脚本/尝试是否已经存在?

make text-processing gnu-make

26
推荐指数
2
解决办法
2万
查看次数

为什么 echo -e 在 Makefile 中表现得很奇怪?

我正在编写一个 Makefile(在 Ubuntu 20.04 上,如果相关的话),并注意到echo. 以这个简单的 Makefile 为例:

test.txt:
        @echo -e 'hello\nworld'
        @echo -e 'hello\nworld' > test.txt
Run Code Online (Sandbox Code Playgroud)

当我运行时make,我希望在 stdout 上看到与 test.txt 中相同的内容,但事实上我没有。我在标准输出上得到这个:

hello
world
Run Code Online (Sandbox Code Playgroud)

但这在 test.txt 中:

-e hello
world
Run Code Online (Sandbox Code Playgroud)

同时,如果我-e从 Makefile 中的两行中删除,我会在标准输出上得到:

hello\nworld
Run Code Online (Sandbox Code Playgroud)

在 test.txt 中:

hello
world
Run Code Online (Sandbox Code Playgroud)

这让我想知道是否echo检测到重定向并表现出不同的行为,但当我在 shell 中手动运行它时却没有(如我通常期望的那样,/bin/echo -e 'hello\nworld' > test.txt它会在单独的行上产生hello和)。world我什至通过添加一行来确认 Makefile 使用的是 /bin/echo 而不是内置的 shell @echo --version

这里发生了什么?

echo gnu-make

17
推荐指数
1
解决办法
6767
查看次数

Makefile中的%符号是什么意思

我在玩makefile,遇到了%.o%.c。据我了解,它指定了所有co文件。但为什么这项工作:

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

这不起作用

SOURCE := $(wildcard *.c)

$(SOURCE:.c=.o): SOURCE
        $(CC) -c $^  -o $@
Run Code Online (Sandbox Code Playgroud)

这两个表达式都指定了所有文件。那么%.o: make 文件中的符号有什么作用呢?

make gnu-make

16
推荐指数
2
解决办法
3万
查看次数

限制 GNU?Make 到 POSIX Make 行为

有没有已知的方法可以让 Linuxmake拒绝意外使用 GNU?在 Linux 中编辑或使用其他人的 Makefile 时,在 Makefile 中进行特定扩展?我的意思是,限制 GNU?Makemake按照 POSIX 中指定的方式运行并拒绝任何 GNU?Make 特定扩展?

.POSIX专项的目标是不够的,按照“ 4.9特别内置目标名(gnu.org) ”。手册页没有提到这个命令行选项。

使用其他make实用程序可能是一种选择。

— 更新 2018-10-19 —

我仍然没有找到我的问题的直接答案,但这里至少有一个关于这个问题的文档,这个文档在我提出这个问题时并不存在:  A Tutorial on Portable Makefiles (nullprogram.com)

make gnu-make

15
推荐指数
1
解决办法
2806
查看次数

Makefile:已设置但具有空值的变量的默认值

我有一个 Makefile,它有一个变量,如果变量未设置或设置但具有空值,则该变量需要具有默认值。

我怎样才能做到这一点?

我需要这个,因为我在 shell 脚本中调用 make 并且 makefile 所需的值可以作为 $1 从 shell 传递。并将其传递给 makefile,我必须将其设置在 bash-script 中。


想法:(不优雅)在 bash 脚本内部,可以检查变量是否已设置但具有空值,在这种情况下可以取消设置。


片段

注意:如果变量未在终端中定义,以下将不起作用,因为它们是在 bash 脚本中设置的。

生成文件

dSourceP?=$(shell pwd)
Source?=$(notdir $(wildcard $(dSourceP)/*.md))
Run Code Online (Sandbox Code Playgroud)

Bash 脚本

make all dSourceP="${1}" Source="${2}"
Run Code Online (Sandbox Code Playgroud)

终端

bash ./MyScript.sh
bash ./MyScript.sh /home/nikhil/MyDocs
bash ./MyScript.sh /home/nikhil/MyDocs index.md
Run Code Online (Sandbox Code Playgroud)

bash make shell-script gnu-make variable

13
推荐指数
1
解决办法
2万
查看次数

gnuMake,如何覆盖环境变量

目前我正在使用具有如下定义的 Makefile

MYLIB=/.../mylib-1.2.34
Run Code Online (Sandbox Code Playgroud)

问题是这些对于不同的开发人员来说是不同的,每次结帐后都必须重新编辑文件是一种痛苦。

所以我尝试导出一个特定的环境变量,然后做

MYLIBX:=$(MYLIB_ENV)
MYLIBX?=MYLIB
Run Code Online (Sandbox Code Playgroud)

问题是如果 MYLIB_ENV 没有定义,它仍然会创建一个空的 MYLIBX,所以 ?= 不起作用。有没有一种干净的方法来做这个非常基本的事情?

我正在使用多年来开发的一组“丰富”的 make 文件,这些文件可以执行各种操作,例如 make 和相互调用,因此无法深入更改内容。

解决方案

双洗牌。MYLIB 已经定义。

MYLIB_ENV?=MYLIB
MYLIB:=MYLIB_ENV
Run Code Online (Sandbox Code Playgroud)

gnu-make

11
推荐指数
1
解决办法
6857
查看次数

如何在 GNU make 中使用来自 HTTP 的文件作为先决条件?

我想在我的 makefile 中使用来自万维网的文件作为先决条件:

local.dat: http://example.org/example.gz
    curl -s $< | gzip -d | transmogrify >$@
Run Code Online (Sandbox Code Playgroud)

如果远程文件比本地文件新,我只想“transmogrify”,就像make正常操作一样。

希望保留的高速缓存副本example.gz -文件都很大,而且我不需要原始数据。最好我想完全避免下载文件。目标是使用-jmake 标志并行处理其中的一些。

什么是解决这个问题的干净方法?我可以想到几种方法:

  • 保留一个空的虚拟文件,每次重新创建目标时都会更新
  • 一些使用 GNU make 的新插件系统插件(我对此一无所知)
  • 在本地文件系统中挂载 HTTP 服务器的 make-agnostic 方式

在进一步挖掘之前,我需要一些建议,最好是具体的例子!

remote timestamps http gnu-make

11
推荐指数
1
解决办法
2025
查看次数