获取makefile目录

发布于 2024-08-16 19:20:50 字数 368 浏览 3 评论 0原文

我正在将我的 cpp 文件与 makefile 一起分发。现在 makefile 与 cpp 文件位于同一目录中。

makefile 中允许我检索 makefile 所在的当前目录的变量(如果有)是什么?这样我就可以使用该变量来指定我的 cpp 编译路径。

我的 makefile 如下:

all:
    g++ ($makeFileDir)/main.cpp ($makeFileDir)/hello.cpp ($makeFileDir)/factorial.cpp -o ($makeFileDir)/hello.exe

编辑:我在 Windows 上运行我的 makefile

I am distributing my cpp files along with a makefile. Now the makefile is located in the same directory as the cpp file.

What is the variable (if any) in makefile that allows me to retrieve the current directory where the makefile is located? In this way I can use that variable to specify my cpp path for compilation.

My makefile is as follows:

all:
    g++ ($makeFileDir)/main.cpp ($makeFileDir)/hello.cpp ($makeFileDir)/factorial.cpp -o ($makeFileDir)/hello.exe

Edit: I am running my makefiles on Windows

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烏雲後面有陽光 2024-08-23 19:20:50

我记得我也遇到过同样的问题。据我记忆,这是不可能的。
最好的选择是将其作为变量传递。这既是跨平台的,又保证可以工作,因为您在调用时知道 makefile 目录(否则您无法调用它)。

或者,你可以做一个非常肮脏的把戏,这意味着你尝试将当前路径(你可以在 gnu make 中使用 $(CURDIR) 获得)与调用 makefile 的路径(这可能很棘手,并且取决于你的品牌)

I remember I had the exact same problem. It's not possible, as far as I remember.
The best bet you can have is to pass it as a variable. That is both cross platform and guaranteed to work, as you know the makefile dir at invoke time (otherwise you can't invoke it).

In alternative, you can do a very dirty trick, meaning you try to combine your current path (you can obtain with $(CURDIR) in gnu make) with the path of the invocation of the makefile (which can be tricky, and depends on your make)

浊酒尽余欢 2024-08-23 19:20:50

这是获取 Makefile 目录的跨平台方法,它应该完全与 shell 无关。

makeFileDir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

请注意,这将为您提供当前正在解释的 Makefile 的目录。如果您使用其他人的此语句包含一个 Malefile,您可能会遇到不好的(或好的!)惊喜。

如果您使用 Windows 上最新的 make 实现,即 Chocolatey's,这应该足够了。

Windows 旧版 make 的问题

根据您在 Windows 上使用的 make 版本,反斜杠的处理可能会不一致。您可能需要以下变体之一。例如,GnuWin 的 make 3.81 二进制文件就是这种情况。

  • 使路径分隔符保持一致。下面的语句仅使用正斜杠,只需交换 \/ 即可获得相反的行为。根据我的经验(使用 GnuWin 的 make),您可能必须使用正斜杠才能将此类变量用于 make include 语句或在 VPATH 中使用它。
    但是您当然需要在 DOS shell 中使用反斜杠,因此在配方中...您可能需要该变量的两个版本,但至少替换可以确保路径分隔符是一致的!
makeFileDir := $(subst \,/,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
  • GnuWin make 3.81 的 abspath 功能已损坏,无法处理包含驱动器号的路径。这里还有一个处理 Windows 绝对路径(带驱动器号)的解决方法。然后,您可以使用它来获取 Makefile 的目录(此处也包含路径分隔符替换)。
    我不会解释细节,但解决方法只是返回参数,如果它已经是 Windows 绝对路径,即路径根目录中有 : ,并使用内置 abspath否则。
define fixabspath
$(if $(findstring :,$(firstword $(subst /, ,$(subst \,/,$(1))))),$\$
$(1),$\
$(abspath $(1)))

makeFileDir := $(subst \,/,$(dir $(call fixabspath,$(lastword $(MAKEFILE_LIST)))))

备注

  • 我在这里可能省略了一些来源,对此我深表歉意。已经是很久以前的事了。
  • fixabspath 定义中,$\ 只是为了分割行以提高可读性。
  • MAKEFILE_LIST 变量包含正在解释的 Makefile 列表,最后一个是当前的。请参阅相应的手册页
  • 如果我没记错的话,这也适用于 macOS 的原生 make。

Here is a cross-platform way to get the directory of the Makefile, which should be fully shell-agnostic.

makeFileDir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

Note that this will give you the directory of the Makefile being currently interpreted. You might have bad (or good!) surprises if you include a Malefile using this statement from another.

That should be enough if you use a recent implementation of make for windows, i.e. Chocolatey's.

Issues with older make for Windows

Depending on the version of make you're using on Windows, there can be inconsistencies in the handling of backslashes. You might need one of the following variant. That's the case for GnuWin's make 3.81 binary for example.

  • Make the path separator consistent. The statement below uses forward slashes only, just swap \ and / to get the opposite behavior. From my experience (with GnuWin's make), you might have to use forward slashes to use such a variable for make include statements or to use it in VPATH.
    But you would of course need backslashes in the DOS shell, and therefore in recipes... You might need two versions of the variable, but at least the substitution makes sure that the path separator is consistent!
makeFileDir := $(subst \,/,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
  • The abspath function of GnuWin make 3.81 is broken and doesn't handle paths with drive letters in it. Here is a workaround to handle Windows absolute paths (with drive letter) as well. You can then use it to get the directory of the Makefile (here with the path separator substitution as well).
    I won't explain the details, but the workaround simply returns the argument if that's already a Windows absolute path, i.e. if there is : in the root of the path, and uses the builtin abspath otherwise.
define fixabspath
$(if $(findstring :,$(firstword $(subst /, ,$(subst \,/,$(1))))),$\$
$(1),$\
$(abspath $(1)))

makeFileDir := $(subst \,/,$(dir $(call fixabspath,$(lastword $(MAKEFILE_LIST)))))

Remarks

  • There might be sources I'm omitting here and I'm sorry for that. It's been a long time ago.
  • In the fixabspath definition, $\ are just here to split the line for readability.
  • The MAKEFILE_LIST variable contains a list of the Makefiles being interpreted, the last one being the current one. See the corresponding manual page.
  • If I remember correctly, this also works with macOS' native make.
药祭#氼 2024-08-23 19:20:50

对于“cygwin”和“linux”的使用,我通过直接从 makefile 中的规则调用 pwd 解决了这个问题:

do.%: %.cpp
  echo "Running command in " `pwd`
  somecommand $^

For 'cygwin' and 'linux' use I've solves this by calling pwd directly from the rule in the makefile:

do.%: %.cpp
  echo "Running command in " `pwd`
  somecommand $^
风吹雪碎 2024-08-23 19:20:50

你可以使用 $(srcdir)

然后 ./configure --srcdir="/your/path/to/the/source/directory"

you can use $(srcdir)

then ./configure --srcdir="/your/path/to/the/source/directory"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文