我有一个变量中的文件路径列表。我想将此列表中的每个文件复制到新位置。问题是我对 makefile 非常陌生,而且我正在努力让任何东西正常工作。我的尝试最终达到了以下目的,尽管不起作用(而且可能完全错误),但我希望它能说明我正在尝试做的事情。
FILES = a/b/file c/d/file e/.../file etc...
copyfiles:
for file in $(FILES); do \
cp $$file newDir/$(notdir $$file); \
done
Run Code Online (Sandbox Code Playgroud) 过去,GNU make 两次毁掉了我的工作,因为它的一些内置规则以.c文件为目标。
如果您有一个名为 的文件foo.c,并且还有foo.lLex 扫描器或foo.yYacc 解析器,请注意!GNU make 假设该.c文件是由这些文件组成的目标(这显然是 POSIX 要求!),并且它将执行类似mv y.tab.c foo.c或 的操作lex -t foo.l > foo.c。
如何禁用所有这些隐藏的危险规则(无论已知或未知),同时保留有用的规则?
具体来说,我们如何向 GNU Make 提出此请求:“请保留与(例如).c 和 .o 文件相关的所有规则,并禁用涉及任何其他文件类型的所有规则”?
我正在使用 Makefile 来构建我的 C++ 项目。有点烦人,有时很难确定构建是成功还是失败。我希望在构建结束时看到一个明确的声明,就像在 gradle 中一样。
如果构建通过:
BUILD SUCCESSFUL
Run Code Online (Sandbox Code Playgroud)
如果构建失败:
BUILD FAILED
Run Code Online (Sandbox Code Playgroud)
对于积极的情况,我找到了这个解决方案:
all: dependencies #every job is done in dependencies
echo "BUILD SUCCESSFUL"
Run Code Online (Sandbox Code Playgroud)
做这个的最好方式是什么?
考虑以下人为的 Makefile:
.PHONY: all one two
SLEEP = 2
all: one two
one two:
@sleep $(SLEEP)
@echo $@
Run Code Online (Sandbox Code Playgroud)
运行make -j 2 all它可以在运行它们中的任何一个所需的时间内完成两个作业,因为它们都是并行运行的。如果您控制 make 的调用并记住每次都执行此操作,这将非常有效,但如果您控制的只是 Makefile,则效果不佳。
设置 MAKEFLAGS 环境变量也可以控制这个:
$ export MAKEFLAGS="-j 2"
$ make all
Run Code Online (Sandbox Code Playgroud)
但是,在 Makefile 中设置此值似乎不起作用:
MAKEFLAGS = -j 2
Run Code Online (Sandbox Code Playgroud)
失败。
export MAKEFLAGS="-j 2"
Run Code Online (Sandbox Code Playgroud)
失败。
同样设置 JOBS 似乎没有任何效果。有没有办法控制从 Makefile 内部运行的默认作业数量?
注意我知道我可以使用一个虚拟配方并从它内部调用一个递归 make,但这会带来大量的混乱,因为我需要为一大堆可能的目标设置它,我处理包含的 Makefile 不一定适合递归。
我试图对所有任务使用相同的值,但该变量正在为每个任务进行评估。如何避免?
版本:GNU Make 4.1
生成文件内容:
SHELL = /bin/bash -ex
BUILD_TIMESTAMP ?= $(shell date '+%Y%m%d%H%M%S')
VERSION ?= 1.2-${BUILD_TIMESTAMP}
t1:
echo ${VERSION}
sleep 1
t2:
echo ${VERSION}
sleep 1
Run Code Online (Sandbox Code Playgroud)
输出:
$ make t1 t2
date +%Y%m%d%H%M%S
echo 1.2-20170803143838
+ echo 1.2-20170803143838
1.2-20170803143838
sleep 1
+ sleep 1
+ date +%Y%m%d%H%M%S
echo 1.2-20170803143839
+ echo 1.2-20170803143839
1.2-20170803143839
sleep 1
+ sleep 1
Run Code Online (Sandbox Code Playgroud) 是否可以告诉SHELL,例如 bash,使用特定的 (bash)rc 文件.SHELLFLAGS?
您将在下面看到两个示例。第一个显示了我想要做什么,第二个说明了实现预期结果的一种方法。
我问的原因是我有一个 bashrc文件(来自 OpenFOAM)定义了一堆我想在各种配方中使用的变量和函数。
感谢您的时间。
示例(不工作)
文件bashrc::
export HELLOWORLD="Hello World"
Run Code Online (Sandbox Code Playgroud)文件Makefile::
SHELL=/bin/bash
.SHELLFLAGS=--rcfile bashrc --
test:
@\
echo "$${HELLOWORLD}"
Run Code Online (Sandbox Code Playgroud)示例(工作)
文件bashrc::
export HELLOWORLD="Hello World"
Run Code Online (Sandbox Code Playgroud)文件Makefile::
.ONESHELL:
SHELL=/bin/bash
test: ; source bashrc
@\
echo "$${HELLOWORLD}"
Run Code Online (Sandbox Code Playgroud)我有Makefile以下格式:
.PHONY: all
target1 := file1
target2 := $(target1).txt
all: $(target2)
$(target1): prerequisite1
recipe
$(target2): $(target1)
recipe
Run Code Online (Sandbox Code Playgroud)
target2取决于target1,make并将正确替换字符串以创建文件名。但是,在我的系统上,输入文件名和路径非常繁琐;我想知道是否有任何方法可以target1在引用其名称而不是文件路径,而是变量.
例如,我希望能够调用:
$ make $(target1)
Run Code Online (Sandbox Code Playgroud)
而不是
$ make path/to/file1
Run Code Online (Sandbox Code Playgroud)
我想这样做是因为我对变量进行了相当多的更改,并且我的结构Makefile有许多中间体,这些中间体有时很难追溯到它们的文字文件路径,但make根据我分配给它们的变量名很容易找到。
以上不起作用,我已经阅读了该man页面,并在此处和 Google 上进行了大量搜索。只是想知道是否有人以前遇到过这个问题并找到了解决方案。
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
Run Code Online (Sandbox Code Playgroud)
这是来自 GNU make 的示例 makefile。它说 make 将使用简单的规则生成具有匹配名称的 *.c 文件的 *.o 文件。
但是,在我的 mac 上,默认使用 clang,我希望它默认使用 gcc-7,以防某些项目在使用 clang 编译时出错。
我正在尝试在 Clear Linux 上构建 glibc 2.27,在此处获得:https : //www.gnu.org/software/libc/sources.html
根据帮助,我应该使用 prefix 命令构建到源文件夹之外的目录中。据我所知,我正在执行安装帮助中描述的操作:
配置和编译 GNU C 库
无法在源目录中编译 GNU C 库。您必须在单独的构建目录中构建它。例如,如果您在“/src/gnu/glibc-VERSION”中解压了 GNU C 库源代码,则创建一个目录“/src/gnu/glibc-build”来放置目标文件。这允许删除整个构建目录以防发生错误,这是重新开始的最安全方法,应该始终完成。
从您的对象目录中,运行位于源代码树顶层的 shell 脚本“configure”。在上面的场景中,你会输入
Run Code Online (Sandbox Code Playgroud)$ ../glibc-VERSION/configure ARGS...请注意,即使您在单独的构建目录中构建,编译也可能需要在源目录中创建或修改文件和目录。
'configure' 有很多选项,但唯一一个通常是强制性的是 '--prefix'。这个选项告诉'configure'你想安装GNU C 库的位置。这默认为“/usr/local”,但作为标准系统库安装的正常设置是 '--prefix=/usr' 对于 GNU/Linux 系统和 '--prefix='(空前缀)对于 GNU/赫德系统。
所以,我认为我这样做是正确的,但它仍然给我一个关于在不同目录中构建的错误:
james@clr ~/Downloads/glibc $ ./configure --prefix=/home/james/Downloads/glibc-build/
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for gcc... gcc
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether …Run Code Online (Sandbox Code Playgroud) 我有用 golang 实现的命令行工具,工作正常。我想执行一些应该提供字符串列表的命令
apps := $(shell fxt run apps)
apps:
@echo $(apps) is called
Run Code Online (Sandbox Code Playgroud)
在终端中,我在执行时看到以下内容make(完全没问题)
[app1 app2] is called
Run Code Online (Sandbox Code Playgroud)
由于命令fxt run apps返回字符串数组 ( var apps []string)
我的问题是我怎么能遍历的apps
变量?
命令返回的数据很好,但现在我需要获取这个列表(app1...appN)并循环它,我不清楚这个问题,我如何循环遍历字符串数组?
特殊情况是如果在循环列表中我app7应该如何在代码中做一个叉子,例如 if(app7) 打印mvn clean install
例子。
对于每个应用程序(在应用程序列表中)我需要运行命令
go test ./...
但是对于需要运行的app7
mvn clean install
和 app10
yarn