Makefile 中的 Heredoc?
这到底有可能吗?如何实现?
更新:我需要这个,因为我从动态和静态数据创建一个文件。
用例:我有一个测试目录。每个 C 文件都会生成一个测试可执行文件。 我可以根据
SRCS = $(wildcard [a-z]*.c)
需要添加新的测试,并且 make 会找到新的测试,编译、运行并 valgrind 它们。我也用git。我希望 .gitignore 包含可执行文件。
就这样。如何创建 .gitignore 并包含静态数据,即我想要忽略的文件(*.o
和 depend
)以及可执行文件动态地?
Is this possible at all and how?
Update: I need this because I create a file both from dynamic and static data.
Use case: I have a test directory. Each C file produces a test executable. With
SRCS = $(wildcard [a-z]*.c)
I can add new tests as needed and make will find the new tests, compile, run and valgrind them. I also use git. I would like .gitignore
to include the executables.
So there. How to create .gitignore
and include static data, i.e. the files I want to be ignored (*.o
and depend
) and also the executables dynamically?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
另一个 GNU Make 解决方案。
您可以使用
define
和export
命令来完成此操作,如下所示:您必须小心内部的 make 扩展(即
$(x)
)不过定义块。Another GNU Make solution.
You can do it using the
define
andexport
commands as follows:You have to be careful of make expansions (i.e.
$(x)
) inside the define block though.是的,你可以。正如其他人指出的那样,您可能不应该这样做,但您可以。 Ash 的答案有一种涉及定义命令的解决方案,但这很麻烦,并且可能会使将变量扩展到正确的值变得棘手。另一个技巧是使用
.ONESHELL :
特殊目标。警告几句:
-
或@
)仅适用于所有配方的第一行并对所有行生效下列的。排除了这一点,生成 Markdown 文件的方式如下:
请注意,另外一个问题是 Make 会跳过空行。如果你的定界文档内容中有一个空行很重要,你需要确保用适当的空白级别缩进该行以匹配定界文档,否则 Make 会吃掉它,甚至不会将它传递给 cat!
Yes, you can. As others note, you probably shouldn't, but you can. Ash's answer has one solution involving define commands, but that is combersome and can make it tricky to get variables expanded to the right values. Another trick is to use the
.ONESHELL:
special target.A couple words of warning:
-
or@
to suppress output or ignore errors only work on the first line of all recipes and take effect for all lines following.With that out of the way, here's how it might look to generate a markdown file:
Note one additional gotcha is that Make skips blank lines. If having a blank line in the content of your heredoc is important, you need to make sure to indent that line with the appropriate level of whitespace to match the heredoc or Make will eat it and not even pass it to cat!
GNU Makefile 可以执行以下操作。这很丑陋,我不会说你应该这样做,但在某些情况下我会这样做。
如果 .profile 文件不存在,
make .profile
将创建一个 .profile 文件。该解决方案用于应用程序仅在 POSIX shell 环境中使用 GNU Makefile 的情况。该项目不是一个开源项目,平台兼容性是一个问题。
目标是创建一个 Makefile,以方便特定类型工作区的设置和使用。 Makefile 带来了各种简单的资源,而不需要诸如另一个特殊存档等之类的东西。从某种意义上说,它是一个 shell 存档。然后,过程可以说诸如将此 Makefile 放入要工作的文件夹中之类的内容。设置工作空间,输入
makeworkspace
,然后要执行 blah,输入make blah
等。棘手的是弄清楚要引用什么内容。上面的代码完成了这项工作,并且接近在 Makefile 中指定此处文档的想法。对于一般用途来说这是否是一个好主意是另一个问题。
GNU Makefile can do things like the following. It is ugly, and I won't say you should do it, but I do in certain situations.
make .profile
creates a .profile file if one does not exist.This solution was used where the application will only use GNU Makefile in a POSIX shell environment. The project is not an open source project where platform compatibility is an issue.
The goal was to create a Makefile that facilitates both setup and use of a particular kind of workspace. The Makefile brings along with it various simple resources without requiring things like another special archive, etc. It is, in a sense, a shell archive. A procedure can then say things like drop this Makefile in the folder to work in. Set up your workspace enter
make workspace
, then to do blah, entermake blah
, etc.What can get tricky is figuring out what to shell quote. The above does the job and is close to the idea of specifying a here document in the Makefile. Whether it is a good idea for general use is a whole other issue.
这取决于你的决心有多大。最好假设它不会起作用。在 makefile 中编写要启动的 shell 脚本,而不是此处的文档。
失败 1
这会产生:
每行单独执行 - 哎呀。
失败 2
生成的:
可能有使用特定版本的 make 的方法(例如,我相信 GNU make 可以在单个子 shell 中执行操作的所有命令),但是您必须指定您的可移植性要求。对于常规(例如 POSIX 兼容)
make
,假设此处的文档不起作用。It depends on how determined you are. It is best to assume it won't work. Write a shell script to be launched instead of a here document in the makefile.
Fails 1
This produces:
Each line is executed separately - oops.
Fails 2
This generated:
There may be methods using a specific version of make (GNU make, for example, can execute all commands for an action in a single subshell, I believe), but then you have to specify your portability requirements. For regular (say POSIX-compliant)
make
, assume here docs do not work.如果您使用的是 Gnu Make,请使用“定义”创建多行文本变量,并使用规则将其回显到文件中。请参见 6.8 定义 https://www.gnu 的多行变量。 org/software/make/manual/make.html#Appending
像这样:
要创建这个,它有助于使用编辑器,创建您想要的文件,将“\n”附加到每行的末尾,然后将它们全部连接成一个字符串。将其粘贴到您的 makefile 中。
在 Linux 上使用 GNU Make 3.81 进行了测试。
If you're using Gnu Make, use a 'define' to create a multi-line text variable, and a rule to echo it into your file. See 6.8 Defining Multi-Line Variables of https://www.gnu.org/software/make/manual/make.html#Appending
Like this:
To create this, it helps to use an editor, create the file you want to have, append "\n" to the end of every line, and then join them all into a single string. Paste that into your makefile.
Tested with GNU Make 3.81 on linux.
尽可能接近我能得到的heredoc:
Makefile:
结果:
As close to a heredoc as I could get:
Makefile:
Result:
重要的是
GITIGNOREDS
行。我更喜欢像heredoc这样的东西,但我也对用空格分隔的文件列表和将空格转换为换行符的sed脚本感到满意。
编辑 根据 Ryan V. Bissell 的建议:使用添加到 gitignore 的单独测试子目录。一切都井然有序。这很简单。
Important is the
GITIGNOREDS
line. I would have preferred a heredoc likebut am also happy with a file list, separated by spaces, and a sed script to translate the space into newlines.
Edit As proposed by Ryan V. Bissell: Use a separate test subdirectory which you add to gitignore. And everything falls into place. It's simple.
看来没有办法在 Makefile 中创建此处文档。不过,有一个可能的解决方法。使用 echo 发送此处文档数据:
It appears there is no way to do a here-document in Makefile. However, there is a possible workaround. Use echo to send the here-document data: