makefile包含在下面.它只是一个很长的目标文件列表和两个目标.问题似乎是第一个目标忽略了$(INC).例如,输出以"g ++ -c -o main.o main.cpp"而不是"g ++ -I/usr/home/jrm/tmp/proteus_beta -c -o main.o main.cpp"开头.
TIA
PROG = proteus
# list of object files
OBJS = main.o \
dataset.o \
genetic_codes.o \
likelihood_engine.o \
options.o \
parsimony.o \
parsimony_engine.o \
seq.o \
site_collection.o \
site_pattern.o \
tools.o \
optare/crs.o \
optare/point.o \
optare/newton_1d.o \
optare/golden_section.o \
models/model.o \
models/DNA/DNA_model.o \
models/DNA/DNA_ssm.o \
models/CODON/CODON_model.o \
models/CODON/CODON_modelA.o \
models/CODON/CODON_modelB.o \
models/CODON/CODON_modelC.o \
models/CODON/CODON_modelD.o \
models/CODON/CODON_M0.o \
models/CODON/CODON_M1.o \
models/CODON/CODON_M2.o \
models/CODON/CODON_M3.o \
models/CODON/CODON_M0gtr.o \
models/CODON/CODON_FEBC1.o …Run Code Online (Sandbox Code Playgroud) 我想通过这个在Makefile中生成规则:
# $(call cc-defs, ccfiles)
define cc-defs
$1.files = $(patsubst %.cc,%.proto,$1)
$1: $1.files
endef
$(foreach ccfile,$(ccfiles), $(eval $(call cc-defs, $(ccfile))))
Run Code Online (Sandbox Code Playgroud)
但失败并显示错误消息:
Makefile:19: *** commands commence before first target. Stop.
Run Code Online (Sandbox Code Playgroud)
相反,我可以这样做:
# $(call cc-defs, ccfiles)
define cc-defs
$1.files = $(patsubst %.cc,%.proto,$1)
endef
$(foreach ccfile,$(ccfiles), $(eval $(call cc-defs, $(ccfile))))
$(foreach ccfile,$(ccfiles), $(eval $(ccfile):$($(ccfile).files)))
Run Code Online (Sandbox Code Playgroud)
如何使第一种方法有效?
这是我想要makefile做的一些伪代码:
if (A doesn't exist) or (B is newer than A):
rm -rf A
create an empty A
parallel_for X in (a large set of files):
if (X is newer than A):
update A using the contents of X
Run Code Online (Sandbox Code Playgroud)
在上面的伪代码中,A是一个SQLite数据库,B是一个C头文件,"大文件集"中的每个文件都是一个C源文件.
基本上,如果我只修改其中一个C源文件,我只希望快速更新数据库,而不是从头开始重建整个数据库.
这种类型的问题是否可以直接在GNU make中解决,还是我不得不求助于使用脚本?
提前致谢!
我试图弄清楚.mk文件中的以下两行是什么意思
包括$(ROOTDIRECT)/ target/$(MYSUBDIR)/defs.mk
包括$(ROOTDIRECT)/ target/$(dir $(patsubst%/,%,$(MYSUBDIR)))/ defs.mk
为了清晰起见,让ROOTDIRECT为"/ home/me",MYSUBDIR为"platform"
第一行,我猜是直接的,包括"/home/me/target/platform/defs.mk"
我不理解的第二行,我对我的环境的猜测是它包含"/home/me/target/defs.mk"
我是对还是错,有人可以帮我理解第二行
我正在尝试编写一个makefile,它应该从src /中选择来自inc /的头文件
〜/ Linuz/src:1.c,2.c,3.c ......
〜/ Linuz/inc:abc.h,dyz.h
请帮我创建一个应该可用的makefile
〜/ Linuz/some_other_dir /生成文件
PS:尝试为我的linux机器编译它.
谢谢你的建议.
我有以下命令行在Linux命令提示符下工作:
vi /tmp/test.txt -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
Run Code Online (Sandbox Code Playgroud)
它创建一个包含以下vim命令的临时文件(使用Process Substitution):
:1 s/^\/\/ VERSION: .*$/\/\/ VERSION: $(date)/g
Run Code Online (Sandbox Code Playgroud)
它打开文件/tmp/test.txt进行编辑,并从先前创建的临时文件中执行命令.它找到第1行并用当前时间戳替换该行.看起来有点像这样:
// VERSION: Fri Apr 12 21:20:03 CEST 2013
...
...
Run Code Online (Sandbox Code Playgroud)
接下来我可以进行任何所需的编辑,只有当我决定保存文件时,所有更改都将提交到磁盘.首先更改磁盘上的文件,然后启动编辑器不是一个选项,因为文件将具有不同的时间戳,而内容本身不会更改.
到目前为止,它按设计/预期工作.
现在我正在尝试将此vi命令行移动到make文件中,这就是我失败的地方.我尝试了一个$(shell .....)结构,但是make会给我带来错误.
edit:
$(shell vi $(src).cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
Run Code Online (Sandbox Code Playgroud)
我正在试图弄清楚Makefile中的行应如何阅读摆弄额外的引号和括号,但我还没有解决它.
我正在运行Ubuntu Linux 12.10和GNU Make 3.81
vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )Make似乎不喜欢"过程替代"结构<( command ).我不想使用额外的(真实)文件.
€ make edit
vi …Run Code Online (Sandbox Code Playgroud) 我想有类似的东西
BROKEN_THINGS = \
thing1 \ # thing1 is completely broken
thing2 \ # thing2 is broken too, see BUG-123
Run Code Online (Sandbox Code Playgroud)
看起来[g] make是不可能的.
我最终使用warning函数(这是有效的,因为$(warning X)总是返回空字符串):
BROKEN_THINGS = \
thing1 $(warning "thing1 is completely broken") \
thing2 $(warning "thing2 is broken too, see BUG-123") \
Run Code Online (Sandbox Code Playgroud)
最后一个并不理想,因为警告会使make的输出变得混乱(并且也是warning特定于gmake的).
有没有更好的解决方案来记录长长的多行列表?
我想读取文本文件的内容,并将其分配给我的makefile中的变量。我阅读了制作手册ch 8.6:file函数,并在我的makefile中编写了以下简单代码段:
# Snippet from my makefile
my_var = $(file < C:/full/path/to/my_file.txt)
all:
@echo $(my_var)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
*** Invalid file operation: < C:/full/path/to/my_file.txt. Stop.
Run Code Online (Sandbox Code Playgroud)
我特意选择$(file ..)而不是$(shell ..)函数来读取文件。那是因为我的makefile应该尽可能与平台无关。$(file ..)函数是纯makefile语法,而$(shell ..)函数则包含shell语法。
我究竟做错了什么?
我有这个Makefile:
node_modules: yarn.lock
yarn install --production=false
touch node_modules
yarn.lock: package.json
yarn install --production=false
touch yarn.lock
Run Code Online (Sandbox Code Playgroud)
基本上,如果node_modules目录丢失(或者有人通过添加/删除文件篡改了它),或者yarn.lock已经更新,那么它应该运行yarn install以重建/完整性检查node_modules目录.
但是,如果yarn.lock缺少,可以重建package.json,或者如果package.json更新,则应安装并重建锁文件.
问题是当两个node_modules 和 yarn.lock丢失,那么相同的命令运行两次.
我怎么能阻止这个?
我几乎把它通过包裹在有条件的指令来工作:
ifneq ("$(wildcard yarn.lock)","")
node_modules: yarn.lock
@yarn install --production=false
touch node_modules
yarn.lock: package.json
touch yarn.lock
else # yarn.lock does not exist
node_modules: yarn.lock
touch node_modules
yarn.lock: package.json
@yarn install --production=false
endif
Run Code Online (Sandbox Code Playgroud)
现在,如果你touch package.json再make node_modules和 …
我试图rm通过写入来抑制命令错误
Makefile文件:
...
clean: $(wildcard *.mod)
-rm $^ 2>/dev/null
...
Run Code Online (Sandbox Code Playgroud)
我跑了:
$ make clean
rm 2>/dev/null
make: [clean] Error 64 (ignored)
Run Code Online (Sandbox Code Playgroud)
我仍然遇到了错误.
无论如何,当我尝试
$ rm [some non-existent files] 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
在bash shell上,它运行正常.
如何2>/dev/null在makefile中使用?