假设我需要在创建特定文件类型之前执行某些任务,但然后我想运行通用规则:
foo.bar:
# do something to prepare to make foo.bar
%.bar:
# generate the `.bar` filetype
我如何评估为某些特定准备工作foo.bar
定义的通配符配方来生成?foo.bar
假设我需要在创建特定文件类型之前执行某些任务,但然后我想运行通用规则:
foo.bar:
# do something to prepare to make foo.bar
%.bar:
# generate the `.bar` filetype
我如何评估为某些特定准备工作foo.bar
定义的通配符配方来生成?foo.bar
我有以下食谱:
ZS_FPATH := $(filter-out %.awk %.py %.sed, $(wildcard src/*))
compile: ${ZS_FPATH}
mkdir -p ${PACKAGE_NAME}/bin
zsh -c "zcompile -Uz ${PACKAGE_NAME}/bin/${PACKAGE_NAME} ${ZS_FPATH}"
mkdir -p ${PACKAGE_NAME}/etc
:> ${PACKAGE_NAME}/etc/zsfnames.lst
while IFS="" read -r zsfpath || [ -n "${zsfpath}" ]; do
basename $${zsfpath} >> ${PACKAGE_NAME}/etc/zsfnames.lst;
done < "${ZS_FPATH}"
.PHONY: compile
# ------------------------------------------------------------------------------
当我运行目标“compile”时,返回以下错误:
mkdir -p utk/bin
zsh -c "zcompile -Uz utk/bin/utk src/bckpfile src/echopath src/tievalue"
mkdir -p utk/etc
:> utk/etc/zsfnames.lst
while IFS="" read -r zsfpath || [ -n "" ]; do
/bin/sh: -c: line 2: syntax error: unexpected end of file
make: *** [Makefile:63: compile] Error 2
我在 neovim 中使用 tabstop=2 来进行间距。我也尝试过 vs code 但没有成功。有人能指出该片段的问题吗?
我试图make
通过生成如下所示的 Makefile 来并行运行一些作业:
test_all: test_1 test_2 test_3
test_1:
@echo "Starting test 1"
@run_some_job > test_1.log 2>&1
# if run_some_job passed, print "Test 1 passed", else print "Test 1 failed"
test_2:
@echo "Starting test 2"
@run_some_job > test_2.log 2>&1
# if run_some_job passed, print "Test 2 passed", else print "Test 2 failed"
test_3:
@echo "Starting test 3"
@run_some_job > test_3.log 2>&1
# if run_some_job passed, print "Test 3 passed", else print "Test 3 failed"
我将调用 usingmake -j10
以便所有这些并行运行,在各个日志文件中捕获它们的 stdout+stderr。
问题:我怎样才能在上面的评论中做我想做的事情?请注意,这里我只是进行打印,但实际上我可能想根据上一个命令是通过还是失败在下一个命令中执行自定义操作。
if run_some_job passed, print "Test N passed", else print "Test N failed"
我有一组目录中的源列表
SOURCES = $(wildcard src/**/*.cpp)
举例来说,我们有一个这样的目录
src
|- dir_one
| |- file_one.cpp
| `- file_two.cpp
|
|- dir_two
| |- file_three.cpp
| `- file_four.cpp
|
`- dir_three
`-file_five.cpp
那么$(SOURCES)
等于
src/dir_one/file_one.cpp
src/dir_one/file_two.cpp
src/dir_two/file_three.cpp
src/dir_two/file_four.cpp
src/dir_three/file_five.cpp
我想使用 Makefile 函数来获取仅包含文件名称的列表,但我不知道有哪些目录。例如我想得到
NAMES = <some makefile functions>
所以 $(NAMES) 等于
file_one file_two file_three file_four file_five
我的文件夹结构如下
/Myapp/main.c
/Myapp/f1.c
/Myapp/f1.h
/Myapp/Makefile
我的 Makefile 竞赛是
CC = gcc
main: main.o f1.o
$(CC) -o main main.o f1.o
main.o: main.c f1.h
f1.o: f1.c f1.h
我在目录 Myapp 中运行 makefile,它工作正常
但是......当我将 f1.h 移动到这样的包含文件夹时:
/Myapp/main.c
/Myapp/f1.c
/Myapp/Makefile
/Myapp/include/f1.h
并在Makefile中添加包含路径
CC = gcc
INCLUDE = ./include/
main: main.o f1.o
$(CC) -I$(INCLUDE) -o main main.o f1.o
main.o: main.c f1.h
f1.o: f1.c f1.h
它将显示: make: *** 没有规则可以生成“main.o”所需的目标“f1.h”。停止。
这让我困惑了一段时间。
搜索相关问题后仍然无法解决这个简单的问题
(我猜这可能是一个相对目录问题,对吧?)
感谢您的帮助。
我想知道在尝试“制作”我的程序时如何找出变量被覆盖的位置。这是编译器错误:
Loading /home/tyler/Software/Cpp/Cpp_Libraries/PelePhysics/Submodules/amrex/Tools/GNUMake/comps/gnu.mak...
Loading /home/tyler/Software/Cpp/Cpp_Libraries/PelePhysics/Submodules/amrex/Tools/GNUMake/sites/Make.unknown...
Loading /home/tyler/Software/Cpp/Cpp_Libraries/PelePhysics/Submodules/amrex/Tools/GNUMake/packages/Make.sundials...
make: /home/tyler/Software/Cpp/Cpp_Libraries/PelePhysics/Submodules/amrex/Tools/F_scripts/findparams.py: No such file or directory
make: Warning: File 'tmp_build_dir/o/2d.gnu.EXE/AMReX_buildInfo.d' has modification time 26084 s in the future
make: *** No rule to make target '/Users/tfara/amrex/Src/Extern/SUNDIALS/AMReX_NVector_MultiFab.cpp', needed by 'tmp_build_dir/o/2d.gnu.EXE/AMReX_NVector_MultiFab.o'. Stop.
我相信我可以准确地告诉你这个问题:我以前开发过这个软件,在那台机器上,一个名为 的变量AMREX_HOME
被设置为/Users/tfara/amrex/
。现在我在另一台机器上,AMREX_HOME
应该设置为/home/tyler/Software/Cpp/Cpp_Libraries/PelePhysics/Submodules/amrex/
. 问题是 PelePhysics 和 AMREX 程序是巨大的、专业开发的软件包,当它们被制作时,包含了一个巨大的中间 makefile 链,我无法完全理解它们。
所以你可以从编译器错误中看到前三个“加载”使用了正确的AMREX_HOME
变量。这是因为我在自己的 makefile 中设置了该变量。但在这个过程中的某个地方,AMREX_HOME
变量被覆盖了。我想让编译器告诉我谁正在尝试创建目标,/Users/tfara/amrex/Src/Extern/(etc)
以便我可以转到该 makefile 并适当地更新路径变量。
将以下 Makefile 视为 MWE:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
all: $(OBJECT1)
lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
all: $(OBJECT2)
lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
当我运行此脚本时,将执行以下命令:
ifort -traceback -c -o lnk/first.o sub/first.f90
ifort -traceback -c -o lnk/second.o sub/second.f90
换句话说,第一条和第二条规则都使用FORTRAN2=ifort -traceback -c
,而第一条规则应该使用FORTRAN1=ifort -c
。您能帮我看看是什么造成了这种奇怪的行为吗?我怎样才能实现$(FORTRAN1)$
第一条规则应该使用的目标?
编辑#1:
根据 MadScientist 的建议,我尝试了以下方法:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
$(OBJECT1): lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
$(OBJECT2): lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
但是,它只执行一个(即第一个)命令:
ifort -c -o lnk/first.o sub/first.f90
编辑#2:
问题是我删除了all:
目标。正确的文件内容应该是:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
all: $(OBJECT1)
$(OBJECT1): lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
all: $(OBJECT2)
$(OBJECT2): lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
考虑以下 Makefile 片段:
FORTRAN = ifort -c
PATH_MOD = mod/
FILE_MOD = mod_constant.f90 mod_rot.f mod_test.f90
SOURCE_MOD = $(FILE_MOD:%=$(PATH_MOD)%)
OBJECT_MOD = $(FILE_MOD:%.f*=%.o)
$(OBJECT_MOD): $(SOURCE_MOD)
$(FORTRAN) $(SOURCE_MOD)
clean:
rm -f *.o
该脚本执行命令ifort -c mod_constant.f90 mod_rot.f mod_test.f90
。
但是,我希望实现$(FILE_MOD)
[但目录中的其他文件] 中列出的所有文件都将在单独的行中$(PATH_MOD)$
编译,将目标文件放入目录中。在本例中,脚本应运行以下命令序列:lnk
ifort -c mod_constant.f90 -o lnk/mod_constant.o
ifort -c mod_rot.f -o lnk/mod_rot.o
ifort -c mod_test.f90 -o lnk/mod_test.o
有什么办法可以做到这一点吗?
我有一个 Makefile,它依赖于具有自己的 Makefile 的子项目中的一些内容。在子项目中,目标具有我希望我的主项目不必知道的依赖关系。因此,我尝试使用子项目的 Makefile 在必要时从中构建我需要的任何内容。这是我在构建之前在示例项目中的内容:
$ find . -type f | xargs head
==> ./subproject/Makefile <==
binary: source.txt
echo subproject source: > $@
date >> $@
cat $< >> $@
clean:
rm binary
==> ./subproject/source.txt <==
this is the subproject source code
==> ./Makefile <==
binary: source.txt subproject/binary
echo main source: > $@
date >> $@
cat $^ >> $@
subproject/%:
$(MAKE) -C $(@D) $(@F)
clean:
rm binary
$(MAKE) -C subproject clean
==> ./source.txt <==
this is the main source code
这就是我构建后得到的:
$ make
make -C subproject binary
make[1]: Entering directory '~/make-example/subproject'
echo subproject source: > binary
date >> binary
cat source.txt >> binary
make[1]: Leaving directory '~/make-example/subproject'
echo main source: > binary
date >> binary
cat source.txt subproject/binary >> binary
$ find . -type f | xargs head
==> ./subproject/Makefile <==
binary: source.txt
echo subproject source: > $@
date >> $@
cat $< >> $@
clean:
rm binary
==> ./subproject/binary <==
subproject source:
Di 10. Okt 14:01:03 CEST 2023
this is the subproject source code
==> ./subproject/source.txt <==
this is the subproject source code
==> ./Makefile <==
binary: source.txt subproject/binary
echo main source: > $@
date >> $@
cat $^ >> $@
subproject/%:
$(MAKE) -C $(@D) $(@F)
clean:
rm binary
$(MAKE) -C subproject clean
==> ./binary <==
main source:
Di 10. Okt 14:01:03 CEST 2023
this is the main source code
subproject source:
Di 10. Okt 14:01:03 CEST 2023
this is the subproject source code
==> ./source.txt <==
this is the main source code
alex@elephant:~/make-example$
当我更改subproject/source.txt
并make
在父项目中运行时,它仍然不会重新编译。
我几乎可以像这样解决这个问题:
subproject/%: always
$(MAKE) -C $(@D) $(@F)
always:
当make在子项目中运行时,subproject/binary
不会被重新编译。但是,binary
在父项目中仍然会重新编译,因为它的先决条件之一已运行,即使先决文件上的日期是旧的。
所以我认为答案可能是我不应该这样做。我真的希望父项目和子项目彼此了解得尽可能少。
有没有办法让父项目检查日期subproject/binary
并使用它来确定是否重建binary
,即使subproject/binary
公式已运行?
我希望能够键入make
并构建它,然后在主项目中再次更改subproject/source.txt
和键入,然后重新编译,然后重新编译结果,然后紧接着,不更改任何内容,然后再次键入,不重新编译任何内容make
subproject/binary
binary
make
我创建了一个具有以下目标的 makefile:
assets/css/%.css.br: assets/css/%.css
brotli $< $@
这对于压缩目录中的每个 css 文件并创建 .css.br 文件非常有效。
但是,我如何调用这个目标来压缩该目录中的每个css文件,我只能将这些目标一一调用。