make究竟如何知道文件是否被修改,以运行某些规则?这些信息必须在某个地方,那么是否有一个文件存储在某个地方并且带有文件的时间戳?
有很多make程序,因此我不确定依赖性检查背后的原理是否对所有程序都相同。如果它们差异很大,我最感兴趣的是 GNU Make;不过了解其中的差异会很好。
我正在使用 GNU make,并且正在尝试根据目标创建先决条件。我希望先决条件是目标的基本名称。所以,当我运行这个时:
make a/b/foo.txt
Run Code Online (Sandbox Code Playgroud)
它应该运行这个:
cp foo.txt a/b/foo.txt
Run Code Online (Sandbox Code Playgroud)
这些都不起作用:
a/%.txt: $(basename $@)
cp $< $@
a/%.txt: $(@F)
cp $< $@
a/%.txt: $(shell basename $@)
cp $< $@
a/%.txt: $(basename %)
cp $< $@
a/%.txt: $(shell basename %)
cp $< $@
Run Code Online (Sandbox Code Playgroud)
我已经看到 % 在目标和先决条件中使用,所以我知道将先决条件基于目标是正常的。我也在先决条件中看到了变量,所以这也是正常的。但似乎特殊变量 $@ 和 $(@F) 在先决条件中不可用,以及诸如 basename 和 shell 之类的函数。有什么方法可以解决这个限制吗?
我正在搜索一个命令,该命令用特定的分隔符分隔所有给定的参数,并输出它们引用。
示例(分隔符设置为冒号:):
somecommand "this is" "a" test
Run Code Online (Sandbox Code Playgroud)
应该输出
"this is":"a":"test"
Run Code Online (Sandbox Code Playgroud)
我知道 shell 在将参数传递给命令之前会解释“”引号。因此,该命令实际上应该做的是打印出引号中的每个给定参数,并用冒号分隔所有这些参数。
我也不是在寻找仅 bash 的解决方案,而是在寻找最优雅的解决方案。
循环遍历这些元素的数组并执行此操作非常容易,但问题是我必须在 a 中使用它,gnu makefile它只允许单行 shell 命令并使用sh而不是bash.
所以越简单越好。
这很容易与这个问题重复,但据我所知,它还没有得到回答。
这是我的目标:能够将先决条件打印到目标。
我有某种解决方案,但对我来说感觉就像是黑客。
假设目标是all,并且它只有先决条件,位于名为 的文件中makefile-1:
all: foo
all: bar baz
Run Code Online (Sandbox Code Playgroud)
我可以使用另一个名为的 makefile makefile-2:
all:
ifeq ($(SHOW),yes)
echo $^
else
cat $^
endif
Run Code Online (Sandbox Code Playgroud)
当正确调用时,这会给我所需要的东西:
$ make -f makefile-1 -f makefile-2
cat foo bar baz
$ make -s SHOW=yes -f makefile-1 -f makefile-2
foo bar baz
Run Code Online (Sandbox Code Playgroud)
但我不确定如果先决条件实际上在原始 makefile 中有一个配方,或者是否有更好/更干净的方法,该怎么办。
每当我想要一个 make 命令来显示一个文件时,我就会遇到这个问题,该文件是使用操作系统的默认应用程序打开该类型文件并遵循特定配方而产生的。
例如...我主要在 Linux 中工作。我可以生成并查看代码文档,并将make docs以下内容放入 Makefile 中:
docs:
cd ${DIR_WORKING}/doc/; doxygen Doxyfile
xdg-open ${DIR_WORKING}/doc/html/index.html &
Run Code Online (Sandbox Code Playgroud)
我想在Windows中使用make docs并具有相同的效果。我也可以使用用户分配的变量,例如 a$(OPEN)代替xdg-open。有没有一种方法可以使用 Windows 和 Linux 中的默认程序打开文件,而不需要用户修改 Makefile?我从未在我的代码中使用过 Autoconf,并希望有一个不依赖于这个方向的解决方案。
我在创建依赖于其他文件内容的 Makefile 构建时遇到问题。
我知道我可以在 makefile 中编写类似的内容来动态生成先决条件:
result/nuclease.stat : $(shell cat config/nuclease.sample.list)
#bash
make result/nuclease.stat
Run Code Online (Sandbox Code Playgroud)
但问题是文件config/nuclease.sample.list可能不存在,而我有一个目标。
如果我可以在$(shell cat config/nuclease.sample.list)评估之前强制 make 要求config/ nuclease.sample.list - 问题就解决了。
我应该建立什么样的依赖?
另一件事,我想保留所有 gnu make 的优良品质:仅下载一次文件,仅处理一次等等。
我正在开发 Solaris 11,已打完补丁。我试图通过在 ISA 下转储预处理器宏来确定编译器是否支持 ISA。
Make 由于Missing Separator. Missing Separator当与 GNU make 的shell 函数一起使用时,我无法找到有关错误的信息。
这是简化的情况。没有空格,因此它不是像“ Make error:缺少分隔符和朋友”中那样的空格/制表符问题。
$ cat -n GNUmakefile-test
1 EGREP ?= egrep
2 SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: (Sun|Studio)")
3
4 # Begin SunCC
5 ifeq ($(SUN_COMPILER),1)
6 $(info "Sun compiler")
7 $(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>/dev/null)
8 ifeq ($(.SHELLSTATUS),0)
9 $(info "SSSE3")
10 SSSE3_FLAG = -xarch=ssse3 -D__SSSE3__=1
11 endif
12 …Run Code Online (Sandbox Code Playgroud) 我目前正在从事一个需要我了解 CMake 和 GMake 的项目。我读过他们,但仍然没有得到他们的申请。
有人可以提供一些关于如何在软件开发中使用 CMake 和 GMake 的例子吗?
谢谢你。
假设我有一个 C++ 源文件,如下所示:
int main() {
...
#ifdef flag
// do something
#endif
...
#ifndef flag
// do something different
#endif
...
}
Run Code Online (Sandbox Code Playgroud)
我知道对于 gcc,我可以用作-D'flag'预处理器的指令来定义flag,从而确定上面代码的哪一部分实际被编译,并且这可以在 Makefile 中使用。
但是我如何编写一个 Makefile,以便根据我是否想要flag定义来重新构建源文件(不对任何文件进行其他更改,包括 Makefile 本身)?
例如,我知道我可以(如果有更好的方法,解决方案不需要遵循这个!),当我运行 make eg with 时定义一个变量make flag=1 all,但是如果文件包含main(与上面的源代码示例一致)此后一直没有更改。
即从一个干净的目录开始并运行make all将运行构建,但是如果我立即运行,make flag=1 all我希望包含main(例如main.cpp)的文件能够正确重建,而不必touch main.cpp首先。
我正在开发一个 SDL 项目,我使用 makefile 来构建它。我正在使用 MinGW w64 编译器和 make 在 Windows 上执行此操作。
我的项目结构看起来像这样
proj
------>bin #stores the executable
------>include #stroes the external library include files
------>lib #stores the lib files of the libraries
------>obj #stores the .o files
------>src #source files
makefile
Run Code Online (Sandbox Code Playgroud)
我的 makefile 看起来像这样
CC = g++
OUT = main
ODIR = ./obj
SDIR = ./src
OUTDIR = ./bin
IDIR = ./include
LDIR = ./lib
libs = -lmingw32 -lSDL2main -lSDL2
OBJS = $(patsubst $(SDIR)/%.cpp,$(ODIR)/%.o,$(wildcard $(SDIR)/*.cpp))
$(ODIR)/%.o : $(SDIR)/%.cpp
$(CC) …Run Code Online (Sandbox Code Playgroud)