I have a Makefile that includes another makefile with the include makefile directive and the included Makefile exists on a deep path (200 characters). The Makefile doesn't produce any error on reading the long path Makefile however it's contents are not included in the main Makefile.
include <long-path>/my.mk
I have tried using UNC path post script as well but that also seems to have no effect. Any help how to handle long paths inclusions in Makefiles?
There can be different ways on how you handle this:
Provide Relative Path: A relative path refers to a location that is relative to a current directory, so you dont require to give a full path
Keep your files/sandbox at very short location if possible: Eg: C:
You can use mount/ shortpath option to use short paths.
Related
I have a Makefile with only project-level definitions: which source files to use, what binary or library to make, etc..
It includes ../../Make.Arch for architecture-specific definitions (such as compiler command).
In turn, Make.Arch is meant to include ../etc/Makefile.Standard for all the boilerplate of actually allowing the make system to work .
But include requires a path relative to where the makefile is actually being run (or maybe where the first Makefile is), not relative to the second... What to do?
Make interprets relative paths from the working directory, the directory in which Make is being run. You haven't specified how you're running Make, so I'll assume your running it in the directory with Makefile.
If you are allowed to modify the makefiles, you can change the paths.
You could change Make.Arch from this:
include ../etc/Makefile.Standard
to this:
include ../../../etc/Makefile.Standard
but that would require that any makefile that uses Make.Arch be two directories down from it. That's clearly not a good idea. But we can use a variable:
include $(ARCH_DIR)/../etc/Makefile.Standard
which is provided by Makefile (or any other makefile that uses Make.Arch):
ARCH_DIR := ../..
include $(ARCH_DIR)/Make.Arch
If you are not allowed to modify the makefiles, then you must cheat. One way is to create a symbolic link to Makefile.Standard.
mkdir ../etc
ln -s ../../../etc/Makefile.Standard ../etc
Now Makefile will work. (It ought to be possible to make a link to etc/, but for some reason I can't get that to work right now.)
When trying to run my makefile (https://pastebin.com/CYqsYtj9), I run into an error:
C:/STM32_Projects/blink_project/test/cpputest/build/MakefileWorker.mk:485: *** multiple target patterns. Stop.
I'm going to link the MakefileWorker.mk as well (https://pastebin.com/5JSy3HsB), even tho I'm pretty sure it's written properly since it's from https://github.com/cpputest/
So, question: why am I getting this error?
EDIT:
When I'm trying to make the makefile from Cygwin CLI, the error I get is the following:
C://STM32_Projects/blink_project//test/cpputest/build/MakefileWorker.mk:485: *** target pattern contains no '%'. Stop.
EDIT 2(Minimal, verifiable example):
// test/main.cpp
#include "CppUTest/CommandLineTestRunner.h"
int main (int ac, char ** av){
return CommandLineTestRunner::RunAllTests(ac,av);
}
so this is a simple main.cpp that my makefile should compile, other than that, you need a full repo from https://github.com/cpputest/cpputest compiled as shown in README in that repo.
Well, as mentioned I'm no expert when it comes to Windows and I know even less about cygwin.
But, my suspicion is that the environment you're trying to use is not well-supported or well-tested on Windows. Here's what I see:
You set:
PROJECT_DIR=C:/STM32_Projects/blink_project
TEST_DIR=$(PROJECT_DIR)/test
TEST_SRC_DIRS=$(TEST_DIR)
which means TEST_SRC_DIRS is set to C:/STM32_Projects/blink_project/test.
Next in MakefileWorker.mk you get an error because TEST_DEPS is set to objs/C:/STM32_Projects/blink_project/test/main.o ... which, I hope we can all easily see, is a totally bogus path.
So how did we get this path? Let's look backwards and see:
At line 484 we see how TEST_DEPS is set:
TEST_DEPS = $(TEST_OBJS) $(MOCKS_OBJS) ...
So, it's likely the bogus path is in TEST_OBJS. That is set at line 380:
TEST_OBJS = $(call src_to_o,$(TEST_SRC))
First, what's TEST_SRC? It's set on line 379 as the result of the user-defined macro get_src_from_dir_list with TEST_SRC_DIRS (which you set above). That macro will locate all the source files, so files that match *.cpp, *.cc, and *.c in each directory in TEST_SRC_DIRS. So based on the info output we can infer that this returns:
C:/STM32_Projects/blink_project/test/main.cpp
which is to be expected. Then we pass that to src_to_o which is a user-defined macro on line 363, which uses another user-defined macro src_to defined on line 362:
src_to = $(addprefix $(CPPUTEST_OBJS_DIR)/,$(call __src_to,$1,$2))
Oho!! Well, CPPUTEST_OBJS_DIR is set to obj at line 226, so this is very likely the start of our problem.
In a POSIX filesystem where there is no such abomination as a "drive letter", paths are fully constructable: if you have a fully-qualified path you can create another path by adding a new path as a prefix. That can't work on Windows, where the drive letter must always come first.
But let's keep going. So we see where the obj/ prefix comes from, now where does the rest of the path come from? That's the expansion of a user-defined macro __src_to defined at line 361 that starts with our source path above. What does this do? It wants to replace the .cpp extension with .o. But note this bit here:
$(if $(CPPUTEST_USE_VPATH),$(notdir $2),$2)
If CPPUTEST_USE_VPATH is true then we return notdir of the path; this would strip out all the drive and directory info and return just main.cpp which would turn into main.o and then the result would be obj/main.o, which would work fine.
But if CPPUTEST_USE_VPATH is false (which it is by default), we don't strip off the path and obj is added to the full path with the drivespec and you get a syntax error.
So. Basically, the cpputest makefiles have issues on Windows. It looks like you have one of these choices:
Either set the CPPUTEST_USE_VPATH option to Y to enable it (and read about what that option means and how to use it in the cpputest docs),
Or, remove the drive specs from your paths in your makefile and just use:
PROJECT_DIR = /STM32_Projects/blink_project
which means you need to be careful that your current drive is C: before you invoke this else it won't be able to find things.
HTH!
A Makefile contains
include ../../common/common.mk
at the end of the file. I want to see the full path during the invocation. How can I do that?
$(info full path to common.mk: $(abspath ../../common/common.mk))
include ../../common/common.mk
Usually, make does not change working directory during execution. Most likely, you can check for ../../common/common.mk from command line just before running **make*. But if you use make -C some/directory then the working directory will be whatever you specify after -C (relative to your current directory).
My include file references many other make files using something like:
include Enablers/MSRP/Android.mk
the problem is that the make file that references all other makefiles is deep in sub-folders, or, in other words the correct path would be something like:
include ../../../../../Enablers/MSRP/Android.mk
In order for me to build my makefile I have to add ../../../../.. to make search path:
ndk-build -I../../../../.. -j8 other params...
(ndk-build is a wrapper for gnu make on android buildsystem, it's equivalent to make build-local.mk other params)
So, what can i do to to avoid adding the ../../../../.. to make search path? I could go the makefile and update all makefile include statements, but I'm looking for the way to add that extra include path at the top of my makefile. Something like:
makeincludepaht += include Enablers/MSRP/Android.mk
include Enablers/MSRP/Android.mk
...
Append the new include path to the standard search path:
.INCLUDE_DIRS += ../../..
Look at the end of the Special Variables section for the .INCLUDE_DIRS special variable.
I'm not familiar with ndk-build, but I have similar setup. I just set a variable in make that contains this path and then use that variable in all my includes.
makefile:
INCLUDE_TOP=../../../../..
include $(INCLUDE_TOP)/someDir/includes.mk
You can also then use INCLUDE_TOP inside includes.mk for all your paths. It is usually better to make it default to some value by conditionally setting in there.
includes.mk:
# will only set if not already set
INCLUDE_TOP ?= ./
HEADERS=$(INCLUDE_TOP)/headers
I would like to tell (g)make to include some common initializations from a separate file knowing the relative location of the included file with respect to the main Makefile.
However in the manuals I cannot find any built-in variable that would, for example, give you the name of the current Makefile.
For example if I want to include the content of a file in the same directory as the current make file, instead of hard-wiring the location of the include:
# MAIN Makefile : ./scripts/make/TaskA.mk
include ./scripts/make/Common.inc
...
I would like to write something like the following assuming that _MAKEFILE_ contains the TaskA.mk location:
# MAIN Makefile : ./scripts/make/TaskA.mk
MAKEFILE_DIR=$(dirname $(_MAKE_FILE_))
include $(MAKEFILE_DIR)/Common.inc
Doesn't the manual give a recipe based on MAKEFILE_LIST?
Basically
this_makefile := $(lastword $(MAKEFILE_LIST))
before any include directives should do the trick.
Look at GNU make - Other Special Variables. MAKEFILE_LIST includes all Makefiles read. So, if you take the first one and extract the directory, you're done.
MAKEFILE_DIR=$(dir $(firstword $(MAKEFILE_LIST)))
include $(MAKEFILE_DIR)Common.inc