我想跟进这个问题及其答案...现在我可以构建两个不同的可执行文件,我想根据变量在不同的目录中构建可执行文件。
我想从这样的事情开始:
EXEDIR = bin/release/
EXE = $(EXEDIR)AmiModRadio
SOURCES = $(wildcard *.c)
OBJECTSDIR = o/release/
OBJECTS = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))
CC = vbcc:bin/vc
LD = vbcc:bin/vc
release : $(EXE)
$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
$(CC) $(shell vbccprefs) -c $< -o $@
$(EXE) : $(OBJECTS)
$(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)
Run Code Online (Sandbox Code Playgroud)
像这样的东西:
EXE = $(EXEDIR)AmiModRadio
SOURCES = $(wildcard *.c)
OBJECTS = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))
CC = vbcc:bin/vc
LD = vbcc:bin/vc
release : EXEDIR = bin/release/
release : OBJECTSDIR = …Run Code Online (Sandbox Code Playgroud) 在 makefile(即子制作)中 使用makevs会产生什么效果?$(MAKE)
是否有一些makeflags被传播/未被传播?
假设我有一个文件,它不是基于文件系统中的其他文件生成的,而是基于某些外部命令生成的,其输出可能会或可能不会更改。我可以在 makefile 中表达这个概念,并且仅在内容实际更改时才运行依赖目标吗?
具体来说,我有一个date.h包含当前日期、小时和分钟(但不包括秒)的文件,该文件是由如下规则生成的:
echo "#define DATE" '"' $$(date '+%D-%H:%M') '"' > date.h
Run Code Online (Sandbox Code Playgroud)
默认的“app”目标取决于date.h,整个 Makefile 如下所示:
app: date.h
echo "Building app"
touch app
date.h: FORCE
echo "#define DATE" '"' $$(date '+%D-%H:%M') '"' > date.h
FORCE:
Run Code Online (Sandbox Code Playgroud)
现在FORCE目标date.h每次都会被重建,这会导致目标app总是过时并被重建。
另一方面,如果我不包含FORCE目标,则date.h只有在目标不存在时才会重建(例如,在清理后或最初克隆项目后),但此后不会再重建。
我想要的是 date.h 仅当其内容实际上被更改时才过时echo- 即,当分钟更改时,而不是其他情况。是否有某种方法告诉 make 仅考虑date.h磁盘上实际字节发生更改的情况,而不是按照时间戳进行更改,或者通过其他方式来实现此效果?
我想到了将日期回显到临时文件,然后date.h根据比较其内容进行有条件更新,但我不确定这是否是一个合理的方法。
我正在学习Linux,我的第一步是调整我的项目以在Linux上运行。这是简单的 makefile(主要用于教育目的),它生成文件:
#------------------------BUILD VARIABLES-----------------------------
# Directories, containing headers
INCLUDE_DIR = ../Include/
# Output directory which will contain output compiled file
OUTPUT_DIR = ../Bin/Debug/
SOURCES = EngineManager.cpp Geometry.cpp Main.cpp Model.cpp \
Shaders.cpp TGAImage.cpp
HEADERS = EngineManager.h Geometry.h Line.h Model.h Shaders.h \
TGAImage.h Triangle.h
#------------------------BUILD_RULES---------------------------------
TinyRenderBuilding : $(addprefix $(INCLUDE_DIR), $(HEADERS)) $(SOURCES)
mkdir -p $(OUTPUT_DIR)
g++ -std=c++14 -o $(OUTPUT_DIR)TinyRender.out -g -I$(INCLUDE_DIR) $(SOURCES)
Run Code Online (Sandbox Code Playgroud)
我不明白,为什么不g++生成调试符号?-g提出了选项
在 bash 脚本中,以下正则表达式似乎运行良好:
MY_STRING="FirstName-LastName-Gender-Age"
MY_REGEX="([^-]+)-([^-]+)$"
if [[ $MY_STRING =~ $MY_REGEX ]]; then
echo "Match: $BASH_REMATCH"
fi
Run Code Online (Sandbox Code Playgroud)
我有兴趣在 Makefile 中使用这个脚本。它似乎存在语法问题。例如:
my-target:
MY_STRING="FirstName-LastName-Gender-Age"
MY_REGEX="([^-]+)-([^-]+)$"
if [[ $MY_STRING =~ $MY_REGEX ]]; then
echo "Match: $BASH_REMATCH"
fi
Run Code Online (Sandbox Code Playgroud)
make 中正确的语法是什么?上面的代码似乎存在变量赋值问题、正则表达式中的“$”问题等。
假设我有几个名为foo.c、bar.c、baz.c、 ... 的文件,我想为每个运行构建任务的文件创建一个 Makefile 目标。
foo:
make foo.c
.PHONY: foo
foo.c:
run build foo
bar:
make bar.c
.PHONY: bar
bar.c:
run build bar
...
Run Code Online (Sandbox Code Playgroud)
我本质上只是想做make foo并且它构建了make foo.c。但我有 x 个文件,并且希望为每个文件创建任务。如何实现这一点。就像是:
FILES = $(foo bar baz ...)
$(FILES): $(FILES)
make $(FILE)
.PHONY: $(FILE)
$(FILES).c: $(FILES)
run build $(FILE)
Run Code Online (Sandbox Code Playgroud)
但所有文件都是相互独立的。
我是 CMake 的新手。add_definitions我对setCMake 文件感到非常困惑。
例如
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)和set(D_GLIBCXX_USE_CXX11_ABI,"0"),有什么区别吗?我看到了不同的结果,但我无法理解。
第二个问题:D_GLIBCXX_USE_CXX11_ABI这个有什么作用?
任何帮助表示赞赏。
多谢!
我在 GNU make 3.81 中遇到修改时间问题。
我的 Makefile 使用从远程服务器安装的数据,由于某种我不知道的原因,该服务器已将文件的修改时间设置为遥远的未来(进入下个世纪)。
Makefile 首先在本地目录中“从未来”创建到远程文件的符号链接,然后基于此文件运行多个脚本,这些脚本都会生成一些输出文件。
现在,当我想在中断后重新运行“make all”以获取所有输出文件时,它不会使用它生成的最新输出文件重新启动(假设从脚本编号 3 开始),而是重新生成所有内容从一开始,因为它注意到第一个文件(我“从未来”符号链接该文件的文件)是较新的。
是否有一个选项可以告诉 make 采用符号链接本身的修改时间,而不是符号链接目标的修改时间?
例子
这是一个重新生成问题的最小工作示例:
设置文件夹和文件:
mkdir symlinkmake
cd symlinkmake
echo $PWD > futurefile.txt
# set file modification time to the future
touch -t 212111111111 futurefile.txt
Run Code Online (Sandbox Code Playgroud)
生成文件的内容:
all: symlink.txt first_output.txt second_output.txt
symlink.txt:
ln -s futurefile.txt symlink.txt
first_output.txt: symlink.txt
cut -f1 -d"/" symlink.txt > first_output.txt
second_output.txt: first_output.txt
wc first_output.txt > second_output.txt
Run Code Online (Sandbox Code Playgroud)
现在运行make all并删除第二个输出文件。然后重新运行 make。由于第一个输出文件已经存在,因此只需要生成第二个文件。但由于futurefile.txt比任何其他文件都新,因此也会生成第一个输出文件:
make all
rm second_output.txt
make all
Run Code Online (Sandbox Code Playgroud)
在我的机器上,输出如下所示:
$ ls …Run Code Online (Sandbox Code Playgroud) 我make在 macOS High Sierra 版本 10.13.6 上的版本如下所示:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
Run Code Online (Sandbox Code Playgroud)
我当前的目录如下所示:
$ ls -1
Makefile
a.txt
b.txt
c.txt
Run Code Online (Sandbox Code Playgroud)
我的Makefile看起来像这样:
*.txt: FORCE
echo Target $@ invoked
FORCE:
Run Code Online (Sandbox Code Playgroud)
我可以Makefile这样使用它:
$ make a.txt
echo Target a.txt invoked
Target …Run Code Online (Sandbox Code Playgroud) make 文档说复杂条件的语法如下:
conditional-directive-one
text-if-one-is-true
else conditional-directive-two
text-if-two-is-true
else
text-if-one-and-two-are-false
endif
Run Code Online (Sandbox Code Playgroud)
但我见过的所有示例中的每个“条件指令 n”都在测试与第一个条件指令中相同的 $var 。实际上,它就像一个 case 语句,针对多个可能值测试一个变量。像这样:
ifeq ($(option), 1)
CC=gcc
else ifeq ($(option), 2)
CC=clang
else
CC=mipsel-linux-gcc
endif
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是一个要求吗?或者我可以有完全不同的条件指令,如下所示:
ifeq ($(option), 1)
CC=gcc
else ifeq ($(myhostname), "JohnsLaptop")
CC=johnsCompiler
else
CC=
endif
Run Code Online (Sandbox Code Playgroud)
那么它真的只是一个 case 语句的时髦语法,还是每个“else ifeq”都是独立的。
我知道我可以这样做:
ifeq ($(option), 1)
CC=gcc
else
ifeq ($(myhostname), "johnsLaptop")
CC=johnsCompiler
else
CC=mipsel-linux-gcc
endif
endif
Run Code Online (Sandbox Code Playgroud)
但那很丑。如果不需要的话,我宁愿不嵌套没有缩进的 if/else。