Makefile multiple target patterns - makefile

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!

Related

Makefile include directive failing for long path Windows 10

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.

How to specify makefile dependencies when source and object suffixes are the same?

I'm using GNU Make 4.0 to compile objects on an IBM i. Most items are ok and conflict-free (.c compiles to a .module, .pf compiles to a .file), but a couple types of items use the same filename suffix for both source and object. For example, commands end in .cmd for the source code and also for the compiled command object. This results in a makefile definition like this:
C_CODE1.MODULE: C_CODE1.C # This is ok -- no conflict
COMMAND1.CMD: COMMAND1.CMD # Error! Make thinks it's a circular dependency.
What can be done to tell Make that the .cmd item on the left and the one on the right are actually two different items? The object suffixes are fixed by the operating system and cannot be changed. The source code suffixes could be changed, but then they wouldn't appear correctly in our code editors without customization. The source code does exist in a separate directory from the objects, but paths aren't really specified in the makefile, other than when setting up VPATH.
If the target name does not have to match the prerequisites, I would change the target name to something else, for example COMMAND1: COMMAND1.CMD.
If they have to be matched then I would write like the following to add the extension explicitly in the recipe.
COMMAND1 : COMMAND1.CMD
cat $< > ${#}.CMD
For the source, even if you are using traditional source files, it's not necessary to use the standard source member type. You could use say CMDSRC for the source member type of your command source.

Missing separator in Makefile

So here's the thing.
I'm trying to build pngwriter. In the makefile there's a line saying:
include make.include
The file make.include has the function to specify the platform used via a symlink, it has just one line:
make.include.linux
(there's a file in the same directory called make.include.linux which has some necessary settings. And by the way, I'm doing this on Windows with MinGW)
in the msys shell, when I do make, it says:
make.include:1: *** missing separator. Stop.
I've looked at other missing separator posts and they're about spaces/tabs, which I think it's not the case here. I've searched about makefiles, symlinks, separators and could solve it.
Please help!
EDIT! OK, so make.include.linux isn't a command, it's a file whose contents need to be included in the original makefile. The make.include should be, as I read, a symlink to make.include.linux.
What you have there isn't valid make syntax. Commands can only be run as part of a target recipe. In your case it seems like what you want is:
all:
make.include.linux
Assuming that make.include.linux is a command, and not something else. Make sure the indentation is a tab character.

gcc: passing list of preprocessor defines

I have a rather long list of preprocessor definitions that I want to make available to several C programs that are compiled with gcc.
Basically I could create a huge list of -DDEF1=1 -DDEF2=2 ... options to pass to gcc, but that would create a huge mess, is hard to use in a versioning-system and may at some time in the future break the command line length limit.
I would like to define my defines in a file.
Basically the -imacros would do what I want except that it only passes it to the first source file: (below from the gcc documentation):
-include file Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched
for file is the preprocessor's working directory instead of the
directory containing the main source file. If not found there, it is
searched for in the remainder of the #include "..." search chain as
normal. If multiple -include options are given, the files are included
in the order they appear on the command line.
-imacros file Exactly like -include, except that any output produced by scanning file is thrown away. Macros it defines remain defined.
This allows you to acquire all the macros from a header without also
processing its declarations. All files specified by -imacros are
processed before all files specified by -include.
I need to have the definitions available in all source files, not just the first one.
Look at the bottom of this reference.
What you might want is the #file option. This option tells GCC to use file for command-line options. This file can of course contain preprocessor defines.
Honestly - it sounds like you need to do a bit more in your build environment.
For example, one suggestion is that it sounds like you should create a header file that is included by all your source files and #define all your definitions.
You could also use -include, but specify an explicit path - which should be determined in your Makefile/build environment.
The -imacros would work, if your Makefile were building each source file independently, into its own object file (which is typical). Its sounds like you're just throwing all the sources into building a single object.

No rule to make target `/Makefile', needed by `Makefile'

I'm trying to 'make' using a pretty simple makefile. My makefile is named 'Makefile' so I'm simply using the command 'make'.
I get this strange error:
make: *** No rule to make target `/Makefile', needed by `Makefile'. Stop.
If, however, I use
make -f "full-path-to-makefile" it actually does run (with odd consequences...). I should say that I'm running all this from the directory where the Makefile lies, of course.
I'm working on Mac OSX, using tcsh.
Edit:
I'm working in the LLVM framework, trying to compile a pass function and this is the associated makefile:
LEVEL = ../../../
LIBRARYNAME = FunctionName
LOADABLE_MODULE = 1
include $(LEVEL)/Makefile.common
Any ideas will be appreciated :)
I had the same problem trying to write a new pass for LLVM i followed these instructions trying to make a HelloB (as Hello already exsited) http://llvm.org/docs/WritingAnLLVMPass.html#quickstart
What i has to do was do a ./configure again then make from the base directory.
I'll go out on a limb: you have an extra slash. Try omitting the final slash in $(LEVEL).
I found the answer, sort of:
The problem was with the installation process of LLVM. It seems that if you do the installation in one order instead of another it can lead to this error. It doesn't make any sense to me, but after I installed it properly everything compiles great (same code, same Makefile, same make program).
I don't really know why this happened, but I know how to fix it :)
What you want to do is ./configure again then make from the base directory (contrary to what is stated in the instructions on the web-site). That worked for me.
BTW - I got the same results running on Ubuntu (with the same fix).
Just to add some information here (since this is the first hit that comes up on Google when looking for the error) - I had the same problem which suddenly popped up on a (previously working) LLVM setup on OSX, and traced it back to the behavior of the realpath command in make.
Specifically, what was happening was that I had a directory called "LLVM/llvm-2.9-build", but for some reason the attempt to resolve PROJECT_OBJ_ROOT at the top of Makefile.config would decide that this directory was in fact called "llvm/llvm-2.9-build". Since OSX is case-insensitive by default, this doesn't cause an immediate problem, except that subsequently LLVM_SRC_ROOT would be set to "LLVM/llvm-2.9-build". This then meant that the creation of PROJ_SRC_DIR using patsubst to replace the object directory would result in a non-existent path (as the unmatched case means that no pattern replace occurs), which in turn would get resolved to / by realpath.
With PROJ_SRC_DIR set to /, this results in the makefile copy rule in Makefile.rules deciding that the source makefile is at $(PROJ_SRC_DIR)/Makefile (ie /Makefile), and the error message described.
It seems that it is only the built-in implementation of realpath in Make (GNU Make 3.81 in my case) that has this behaviour, as forcibly using the macro version of realpath from the top of Makefile.config fixes the problem. However, this isn't a good long-term fix, as you'd have to manually patch every one of the LLVM makefiles.
In the end, I couldn't see where realpath would be getting the lower-case "llvm" from, but figured it was probably an artifact somehow of some caching of the name from a point in time when I'd referenced the directory using its lower-case name. Hence I tried going to that directory and mv-ing it to a completely different name, and then back to "LLVM" before going in and building again, and that seems to have solved the problem.
I hope that's of some use to anyone else who comes across this particular weirdness!
It's not a complete answer, but what you are seeing is gmake not finding the Makefile it is told to include, and thus it is trying to remake it and failing because it can't find a recipe for it either.
However, the Makefile snippet you posted does not produce the error message you are seeing, so I think the problem is inside the Makefile.common file. Look for include statements which reference a $(some variable expansion)/Makefile and work backwards from there. You can also try to run gmake with the -d option and follow the processing based on the output.
Since your include line reads:
include $(LEVEL)/Makefile.common
it is puzzling that you are not getting an error about /Makefile.common. If you were, then I'd suggest that maybe you have a trailing blank after the definition of LEVEL.
Could there be a line in Makefile.common that itself includes $(SOMEMACRO)/Makefile and you have not set the value of SOMEMACRO?
here's my fixes for this issue: (https://github.com/rust-lang/rust/issues/24887#issuecomment-99391849)
update src/llvm/Makefile.config.in before running ./configure
or update x86_64-apple-darwin/llvm/Makefile.config before make
line 59:
PROJ_SRC_DIR := $(LLVM_SRC_ROOT)$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR))
update to
PROJ_SRC_DIR := $(patsubst $(PROJ_OBJ_ROOT)%,$(LLVM_SRC_ROOT)%,$(PROJ_OBJ_DIR))
line 86:
PROJ_SRC_DIR := $(call realpath, $(PROJ_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)))
update to
PROJ_SRC_DIR := $(call realpath, $(patsubst $(PROJ_OBJ_ROOT)%,$(PROJ_SRC_ROOT)%,$(PROJ_OBJ_DIR)))

Resources