Difficulties with a Makefile - makefile

So I'm trying to install the Homotopy Type Theory library for Coq from github following these instructions. Running the command etc/install_coq.sh sets it off messing with a bunch of files before it hits an error as so:
$ make clean
make: *** No rule to make target `clean'. Stop.
Apparently there's one or more bugs present within Makefile.am, and according to what I've read while googling the issue it's likely related to improper whitespace. Running make clean myself yields the same thing:
make: *** No rule to make target `clean'. Stop.
Meanwhile running make -f Makefile.am clean yields:
Makefile.am:4: *** missing separator. Stop.
Lines 4-6 in the file are simply:
if make_hoqide
bin_SCRIPTS += hoqide
endif
What's wrong with that that's causing the problem?

Makefile.am is generally paired with Makefile.in; these need to be processed with automake or configure before you get a usable real Makefile.
If you've got a script "autogen.sh" in your top-level source directory, run that
first, then configure:
$ ./autogen.sh
$ ./configure
$ make
This is, in fact, step 3 of the instructions that you linked to. Perhaps the install_coq.sh script isn't finding all of the dependencies that you need?

Related

How to let Makefile see target from another file

I have such Makefile with a content for creating a script:
.PHONY cluster-run
cluster-run:
make $(TARGET) --just-print >> tmp_script.sh;
And another one nn.mk:
.PHONY nn-model
include Makefile
nn-model:
python run-nn.py
I have two separate Makefiles for readability, because their content is big and I have another '*.mk' files, like nn-lstm.mk, nn-conv.mk, etc.
I launch as follows:
make -f nn.mk cluster-run TARGET=nn-model
But make gives an error:
make nn-model --just-print >> tmp_script.sh;
make[1]: *** No rule to make target `nn-model'. Stop.
make: *** [cluster-run] Error 2
For me such behaviour is strange because target nn-model actually exists. How can I fix this problem?
First you should never use raw make in recipes. Always use the $(MAKE) variable.
Second, the problem is because when you run the sub-make you don't provide the -f option:
make nn-model --just-print >> tmp_script.sh;
Because of that, it reads Makefile but not nn.mk, and so there's no rule to build the target nn-model.
Remember if you run a sub-make like this it's starting an entirely new make process with a clean slate: none of the targets defined in the parent make process are known to the sub-make when it starts.
I don't know what you mean by target nn_model actually exists but there's definitely no file named nn_model or you wouldn't get that error.
So what's happening is that when you build cluster-run it invokes a recursive make, which reads Makefile, and asks it to build $(TARGET) (which will include nn-model).
Notice that the recursive make is a new make and does not inherit variables or rules from the parent make, so this make instance has no clue how to build nn-model If you want the child make to see this, then the child make must include the parent one...

make: *** No rule to make target 'php', needed by 'test-newsletter-only'. Stop

I have a Makefile (being read by GNU Make 4.1) containing the following line:
test-newsletter-only: php bin/phpunit src/AppBundle/Tests/Service/NewsletterFromPageServiceTest.php
... and when I run make test-newsletter-only in my shell, I get the following:
make: *** No rule to make target 'php', needed by
'test-newsletter-only'. Stop.
I have verfified with php -v that a valid copy of PHP is installed in the environment where I'm running this. What am I doing wrong here?
Please look through make docs.
You can find rule syntax here
php is interpreted as a prerequisite, while I assume you intended it to be part of the recipe. Take it to the new line.

How to use synchronization in makefile?

From the docs:
To avoid this you can use the --output-sync (-O) option. This
option instructs make to save the output from the commands it invokes
and print it all once the commands are completed. Additionally, if
there are multiple recursive make invocations running in parallel,
they will communicate so that only one of them is generating output at a
time.
So, given a makefile:
# A "recipe" that will always fail.
all::
#foo bar baz
And running, we get:
# A "non-synchronized" run
$ make
make: foo: Command not found
makefile:3: recipe for target 'all' failed
make: *** [all] Error 127
# Synchronize!
$ make --output-sync
makefile:3: recipe for target 'all' failed
make: *** [all] Error 127
Can you see a difference between the 2 runs?
Well, they both fail!
But, in the first run, Make let's us know why it failed, as it "let-through" the failing error(s) from the recipe:
make: foo: Command not found
But, for the second run, all we get, is:
makefile:3: recipe for target 'all' failed
make: *** [all] Error 127
But why? Why did it fail..Were there any debugging errors - from the recipe - that it failed? Sure there were! As evident by the 1st run! So, Why is Make so quick to hide them?
Now - that Make is hiding the error message - all we can do here, is: to guess!
We are very lucky here, because we know that "foo..." is an invalid command, so probably, somewhere, behind the curtains, this command was not acceptable, for this very reason.
But, consider this:
Imagine, when you have some typo in a command?
Now, imagine a typo in complex makefile!
Now, imagine the typo in a complex makefile run recursively!
Now, imagine all that in a makefile that runs for long period of times, outputting considerable amount of output!
How, then, could it be still justified for Make to "hide" some debugging errors, and show others?
(Versions note: All versions supporting synchronization, hence: 4.0 and up).
I had opened a bug report on this the other day here https://savannah.gnu.org/bugs/index.php?47365
It should be fixed now http://git.savannah.gnu.org/cgit/make.git/commit/?id=14b2d7effb0afd75dfd1ed2534e331784f7d2977
I guess you can build the latest version from source or wait until they make another official release. I'll be building from source as I need this fix ASAP :)

Is there a way to tell my makefile to output a custom error message if a certain an include file is not found?

I have a configure script that generates a config.inc file containing some variable definitions and a makefile that imports those configurations using
include config.inc
The thing that bothers me is that if the user tries to run the makefile directly without first running configure they get an unhelpful error message:
makefile:2: config.inc: No such file or directory
make: *** No rule to make target 'config.inc'. Stop.
Is there a way for me to produce a better error message, instructing the user to first run the configure script, without resorting to the autoconf strategy of generating the full makefile from inside configure?
Sure, no problem; just do something like this:
atarget:
echo here is a target
ifeq ($(wildcard config.inc),)
$(error Please run configure first!)
endif
another:
echo here is another target
include config.inc
final:
echo here is a final target
Note this is definitely specific to GNU make; there's no portable way to do this.
EDIT: the above example will work fine. If the file config.inc exists, then it will be included. If the file config.inc does not exist, then make will exit as it reads the makefile (as a result of the error function) and never get to the include line so there will be no obscure error about missing include files. That's what the original poster asked for.
EDIT2: Here's an example run:
$ cat Makefile
all:
#echo hello world
ifeq ($(wildcard config.inc),)
$(error Please run configure first!)
endif
include config.inc
$ touch config.inc
$ make
hello world
$ rm config.inc
$ make
Makefile:5: *** Please run configure first!. Stop.
I gave up and decided to use autoconf and automake to handle my makefile-generation needs.

Specifying different GNUmakefile for GNU make command

I have two GNUmakefiles in my directory as follows,
GNUmakefile &
GNUmakefile2
Could someone please let me know the command I have to use, if I have to let the "make" command to process "GNUmakefile2" instead of "GNUmakefile".
I used the below command,
make -f GNUmakefile2
but in that case, I am getting the following errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: ** No rule to make target `internal-master-tool-all'. Stop.*
make: ** [internal-all] Error 2*
I think it is considering GNUmakefile as makefile (when I use make with -f command), so it is checking for rules in GNUmakefile.
At present what I am doing is I am renaming the required file (which I want, make command to execute) to "GNUmakefile". And I am not getting any errors while executing "make" command, but I don't think this is the correct solution.
Please let me know which command I need to use for this scenario. Thanks for your help.
After checking Beta's solution (i.e.,but that makefile is invoking Make a second time, and the second Make process is probably reading GNUmakefile) what I have done is I renamed existing "GNUmakefile" to "GNUmakefile3".
So at present in my directory the following makefiles are present:- "GNUmakefile2" & "GNUmakefile3".
And then I executed the following command:- $ make -f GNUmakefile2
I recieved the below errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: GNUmakefile: No such file or directory
make[1]: * No rule to make target `GNUmakefile'. Stop.
make: * [internal-all] Error 2
Please let me know what is the problem here
Your makefile includes two huge makefiles from the FSF. The second, library.make, contains this rule:
ifeq ($(GNUSTEP_MAKE_PARALLEL_BUILDING), no)
# Standard building
...
else
# Parallel building. ...
internal-library-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) $(OBJ_DIRS_TO_CREATE)
$(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) ...
endif
and the first, common.make contains this assignment:
# The default name of the makefile to be used in recursive invocations of make
ifeq ($(MAKEFILE_NAME),)
MAKEFILE_NAME = GNUmakefile
endif
So try either make -f GNUmakefile2 GNUSTEP_MAKE_PARALLEL_BUILDING=no or make -f GNUmakefile2 MAKEFILE_NAME=GNUmakefile2, and see if that solves the problem.

Resources