Annoying "nothing to be done for 'install'" message - makefile

I cannot figure out why make is giving me this. I run "make clean; make" then "make install" and I get a "make: Nothing to be done for `install'." message. Here is my install target:
$(phony install): $(OBJFILES)
#$(shell cp $(OBJFILES) ../../)
I changed it from using a ".PHONY: install" to "$(phony install)" because I saw someone online who said that was also a way to do phony targets, and I was stumped. To be honest, I'm rather new to writing my own Makefiles, but it seems simple enough. I'm sure I'm missing something obvious and I will feel dumb here in a second. :P
Okay, weird thing. It seems that make is executing the install target, but is still saying "nothing to be done" this is weird. Also, if I do "make clean; make install" it installs just fine and doesn't give me any messages like that. So, it is only when the object files need rebuilt that "install" is seeing that it needs to be run. That doesn't make sense. I should be able to run "make; make install"!

You don't need to use $(shell ...) inside a recipe, instead write command as it is. Also, I've never heard about $(phony ...), and I guess that it is not valid (try to run Make with --warn-undefined-variables option).
.PHONY: install
install: $(OBJFILES)
#cp $^ ../../

Related

ocamlbuild: Nothing to be done for `all'

I'm using ocamlbuild in makefile to build my code and want to recompile when there is any code change. But make returns with error message: make: Nothing to be done for `all'.
My makefile code:
all: test1 test2
test1:
ocamlbuild $(INCLUDES) $(FLAGS) $(TEST1_BYTE)
mv $(TEST1_BYTE) test1.out
test2:
ocamlbuild $(INCLUDES) $(FLAGS) $(TEST2_BYTE)
mv $(TEST2_BYTE) test2.out
clean:
rm -f test1.out test2.out
rm -rf _build
I expect make will do the recompilation instead of make clean; make. It only works with make clean; make now.
Make your targets phony then the make utility will always rebuild them. And ocamlbuild will track the dependencies with all the knowledge of the OCaml infrastructure, and will never rebuild anything unnecessary. Here's how to declare your targets phony, add this to your Makefile
.PHONY: test1 test2
Also, it looks like that you're still learning both make and ocamlbuild utilities, and given that you're going to invest your time in learning the tools it is better to focus on something that is not that legacy. While getting accustomed to make could be considered as useful, the ocamlbuild tool is more or less deprecated with the newer, dune and much better documented. It is very easy, just create a new file named dune and put the following contents there,
(executable
(name test1))
(executable
(name test2))
Now you can build your targets with dune build test1.exe. You can still create a Makefile as a courtesy to those who don't know how to invoke dune. And as usual, don't forget to make your targets phony in the makefile.
This Makefile specifically says that test1 and test2 depend on nothing. As long as they both exist, make will say there's nothing to do.
I don't know anything about ocamlbuild, but I suspect you should be using it by itself rather than combining it with make, which is a separate (very flexible, but very old) build system.
For what it's worth, it seems to me that many current OCaml developers are switching to dune for a build system.

What is the reason for fatal error: *** No rule to make target 'install'. Stop

The error occurs when I tried to run the command make install under Ubuntu 16.04 that
*** No rule to make target 'install'. Stop.
I have already run make command with several errors fatal: bad revision 'HEAD', which didn't lead to halting the command. I have no idea whether these errors matter.
My makefile is:
SUBDIRS := $(wildcard */.)
all: $(SUBDIRS)
$(SUBDIRS):
make -C $#
install:
for dir in $(SUBDIRS); do \
make -C $$dir install; \
done
.PHONY: all $(SUBDIRS)
Specifically, I want to know how the makefile works after install:.
The project should install an APP on the connected phone Nexus 5. But actually, there's no such APP on my phone.
I suppose your Makefile is properly formatted, with tabs where they should be, etc.
Then, when you run make install in the top level directory, your Makefile does have a rule to make the target install: it says to loop on your subdirectories, enter each one of them, and run make install there (this is what the -C option does). One of those sub-makes fails, most probably because, in its respective subdirectory, it doesn’t find a Makefile with an install recipe in it. When the sub-make fails, the loop goes on with the remaining sub-makes (unless the shell was instructed otherwise by means of the -e switch), and the final return code of the whole recipe will be the return code of the last sub-make.
There are some points worth discussing in your Makefile (for example, install should be listed as a .PHONY target), but you don’t provide enough information to clarify them: for example, is it really necessary to have the shell loop through the subdirectories in a particular order? Usually, a better policy is to have make parallelize the sub-makes whenever possible (and, as a side effect, have make stop when the first submake fails...)

Nothing to be done for dev makefile

I have a simple Makefil here:
.PHONY: dev
dev:
php -S localhost:8000
And this error comme out: Nothing to be done for dev
The only way this could be happening is if make can't find your makefile. Are you in the same directory as this makefile when you run make? Did you name your makefile makefile or Makefile, or did you call it something else? In your question you say you have a simple Makefil but I don't know if that was a typo or if you really tried to call your makefile "Makefil" (missing final "e").
See the GNU make manual for information on how make locates makefiles.

cmake and parallel building with "make -jN"

I'm trying to setup a parallel CMake-based build for my source tree, but when I issue
$ cmake .
$ make -j2
I get:
jobserver unavailable: using -j1. Add '+' to parent make rule
as a warning. Does anyone have an idea if it is possible to fix it somehow?
In the generated Makefile, when calling into a sub-make it needs to either use $(MAKE) (not just 'make') or else precede the line with a +. That is, a rule should look like this:
mysubdir:
$(MAKE) -C mysubdir
or like this:
mysubdir:
+make -C mysubdir
If you don't do it one of those two ways, make will give you that warning.
I don't know anything about cmake, so maybe it's generating Makefiles that aren't correct. Or maybe you did something incorrectly on your end.
In my case (with CMake 3.5.2) the trivial cd build && cmake .. && make -j5 works just fine.
But, I do get the jobserver unavailable error when building custom targets (as dependencies of other targets) via the cmake --build . --target foo idiom.
Like this:
add_custom_target(buildroot
COMMAND ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
— so that the user can make deb and it Just Works. CMake will regenerate makefiles if needed, run the compilation, install everything exactly as with make install, and then run my custom scripts to package up the populated buildroot into whatever shape or form I need.
Sure enough, I'd like to make -j15 deb — but that fails.
Now, as explained on the mailing list by CMake devs, the root cause lies, surprisingly (or not), within GNU Make; there is a workaround.
The root cause is that make will not pass its jobserver environment to child processes it thinks aren't make.
To illustrate, here's a process tree (ps -A f) branch:
…
\_ bash
\_ make -j15 deb
\_ make -f CMakeFiles/Makefile2 deb
\_ make -f CMakeFiles/buildroot.dir/build.make CMakeFiles/buildroot.dir/build
\_ /usr/bin/cmake --build . --target install ⦿
\_ /usr/bin/gmake install
…
At ⦿ point, make drops jobserver environment, ultimately causing single-threaded compilation.
The workaround which worked great for me, as given away in the linked email, is to prefix all custom commands with +env. Like this:
add_custom_target(buildroot
#-- this ↓↓↓ here -- https://stackoverflow.com/a/41268443/531179
COMMAND +env ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
In the end, this appears in the rule for buildroot in the appropriate makefile (CMake generates a bunch of them), and causes GNU Make to behave properly and respect -j.
Hope this helps.
As pointed out by #Carlo Wood in his comment to this answer, trying to convince cmake to add + to the beginning of the command in the cmake-generated makefile is not possible.
A work-around I found is to shield underlying make command from the make flags coming from cmake. This can be done by setting environment variable MAKEFLAGS to empty string for the custom command:
COMMAND ${CMAKE_COMMAND} -E env
MAKEFLAGS=
make <your target and make options>
Hope this helps.

Make: $(wildcard) holding a directory open

So there seems to be this problem with GNU Make's $(wildcard) function keeping a directory open on Windows. See (unasnwered) post "make is holding a directory open". Google does not provide much information on the topic.
In short: the Makefile uses the $(wildcard) function at some point, and keeps a directory open, which typically prevents the "make clean" rule to do its work correctly. Re-running "make clean" a second time usually solves it.
I'm using GNU Make version 3.81 under a standard DOS-Box. The author of the post linked to above is using Cygwin.
Has anyone found a fix for this?
Sounds like a file descriptor leak, all right -- harmless for very-short-lived processes (like make) on UNIX, but a right PITA on Windows.
As this is allegedly a bug in make, as opposed to a problem with its usage, it should be addressed first by validating that it still exists when built from source on the newest upstream version, and then by filing a bug report with the GNU make project (or with any distributor with whom you have an appropriate support contract), or diving into the source and attempting to fix it yourself.
It wouldn't hurt to try to reproduce on Linux -- checking for file descriptor leaks are much easier here, as one can just look at /proc/self/fd (or, for a child of make, /proc/$PPID/fd) for things that don't belong.
I did find a workaround for the problem, which at least lets me work in peace.
The problem was that the $(wildcard) function was used to collect the sources files. My clean rule, however, only deletes a directory - no need for the collecting to take please. So I basically put the part of the Makefile that needs to collect the sources files in a conditional statement:
# The clean rule is always parsed
clean:
rm -rf $(OUTPUT_DIRECTORY)
# The compile rule is only interpreted if we did not invoke 'make clean'. We
# can test the value of $(MAKECMDGOALS) for that:
ifeq ($(filter $(MAKECMDGOALS),clean),)
SOURCE_FILES := $(wildcard ...)
compile:
g++ $(SOURCE_FILES) ...
endif

Resources