Make include in makefiles be relative to the current file's location
Asked Answered
H

4

23

PREAMBLE: the question is wildly obsolete. The NDK build/native debugging system doesn't work like this anymore.


Directly related to this question. How can I make the include directive in makefiles behave relatively to the location of the currently executing makefile.

Assume that the current path is arbitrary and you have no control over it. Only the makefile location is known. Your makefile is not the root one from the make invokation - it's included. That's exactly how it is in Android NDK.

Is there a builtin variable with the current makefile's name or path (as opposed to the root level makefile)? Can I strip filename away from it, leaving just the path? Using make 3.81 on Cygwin.

Hotshot answered 10/11, 2011 at 2:39 Comment(6)
The question is unclear: you're saying the makefile location is known. Then, you've got no question anymore!Isotonic
Include looks in the current folder, and in the folder where the initial makefile is. My makefile is included from the initial makefile; include doesn't work as expected. That said, I've found a workaround years ago - I made an env variable with the project location.Hotshot
So, you didn't even use the answers. Sigh. BTW, the folder of the initial makefile is not in the include path.Isotonic
None of them worked for both ndk-build and ndk-gdb :( And now the NDK build architecture is completely different anyway.Hotshot
Would it be an option to cd to the directory of the makefile, before running make?Cystotomy
It's been a while, but IIRC some part of the build chain would override that.Hotshot
P
31

You can get the name of the makefile being currently processed from MAKEFILE_LIST builtin variable.

Given that the current makefile is the last one that has been included (in other words you didn't use another include directive since the beginning of the current script), the path to the script itself would be:

SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))

Now you are able to include a script in the same directory as such (note an absence of slash, it has already been added by $(dir ...)):

include $(SELF_DIR)another.mk

Note: In GNU Make 3.80 there was no lastword builtin function. In that case you may implement it as follows replacing $(lastword ...) with $(call lastword,...):

lastword = $(if $(firstword $1),$(word $(words $1),$1))
Princessprinceton answered 10/11, 2011 at 13:52 Comment(7)
In my case, MAKEFILE_LIST returns something unrelated.Hotshot
It seems strange, I just tried the solution on Cygwin too, everything works as expected... What's the value of MAKEFILE_LIST in your case?Princessprinceton
Dunno, but the path that came out /cygdrive/c/android-ndk-r6b/buil d/core/ . This is Android NDK, and my makefile is but a tiny fragment in a sizable build framework.Hotshot
The only left idea is to check that you assign SELF_DIR as the first statement of your makefile, before including anything else. Also the assignment must be simple (:=), not recursive (=).Princessprinceton
As the name implies, MAKEFILE_LIST is a list and may contain more than just the current makefile. You can't rely it on to always point to the current Makefile.Hyacinthia
@Hyacinthia that is exactly what lastword is for.Princessprinceton
Beware that using MAKEFILE_LIST will break your Makefile if you include any other Makefiles and you expect to support paths with spaces in them.Baryon
M
5

Is there a builtin variable with the current makefile's name?

Yes, there is, use ${CURDIR}. This is the directory where top-level Makefile is located, so you don't need to strip anything from it.

http://www.gnu.org/software/make/manual/make.html#Recursion

Mouth answered 10/11, 2011 at 4:28 Comment(5)
Good one, but there's catch. CURDIR, it seems, is sometimes terminated with / (when invoking ndk-gdb) and sometimes (ndk-build) is not. Any way around that?Hotshot
That shouldn't matter, as foo//bar is a legal path and it equals foo/bar. So you may just use ${CURDIR}/...Mouth
Funny... Now ndk-build works and ndk-gdb behaves as if CURDIR is one level up above my project location. Now I'm utterly puzzled.Hotshot
I dont think the op asked what you answered. From the manual "[...] in particular note that if you include files from other directories the value of CURDIR does not change". So you cannot use it to figure an included makefile directory.Filefish
So wrong. $(CURDIR) is not at all related to any Makefile location. It's just the dir the initial make command was launched from (and doesn't change when recursively calling make).Isotonic
G
2

I find that relative paths work (GNUMake 3.81), but if they don't for you, try this:

include $(abspath ../whatever)
Gongorism answered 10/11, 2011 at 4:37 Comment(3)
Good one, but on ndk-gdb builds it resolves wrongly, goes one level up too many. I guess the assumtion is that the relative path is relative to the current directory (as opposed to the file's directory) is still there.Hotshot
Repeated error: this does not work for out-of-tree builds.Isotonic
Not sure it answers the OP question, but man did it help me !! ...so ThanksUrbane
H
1

Although this is a very old thread, but now we can use -I DIRECTORY, --include-dir=DIRECTORY when calling make. For example, if the root Makefile needs to include ./sub/a.mk and a.mk uses other make files relative to its own directory, you could call make like this:

make -I ./sub <your Makefile target>
Histaminase answered 6/6, 2024 at 21:4 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.