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.
Related
In Unix Makefile I can prefix a recipe line with - to ignore any error that will occur (as describe in Errors in Recipes).
hello_world: hello_world.cxx
-$(CXX) $(CXXFLAGS) $^ -o $#
I converted my Makefile to CMake:
cmake_minimum_required(VERSION 3.0)
project(HelloWorld)
add_executable(hello_world hello_world.cxx)
and run cmake and the generated Makefile looking fine, except the missing -.
Is it possible to generate Unix Makefile with CMake that will ignore errors (prefix the recipe line with -)?
The best would be to specify it per target level. I know I can run make -i to have the same behaviour but it isn't that convenient.
You cannot.
make is designed to give the user a fine control over commands it runs. CMake's under-the-hood commands are supposed to always succeed.
As a hack, you can generate makefiles and run make --ignore-errors.
But I advice making each of your examples that would fail a separate project, and run them from an external script.
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...)
In my Makefile, I want to link to a library only if it is installed on the machine. So, for example if the library is hwloc, I want to do the following:
xfoo : foo.o
if (hwloc installed)
gcc foo.o -o $# -lhwloc
else
gcc foo.o -o $#
Is there anyway to do something like this? i.e. Is it possible to check if a specific library is installed and use that as a condition in a Makefile?
Here's the wrong answer:
xfoo : foo.o
if (hwloc installed); then gcc foo.o -o $# -lhwloc; else gcc foo.o -o $#; fi
Commands executed from a Makefile do not have to be just simple, single commands. Anything that a shell can execute, can be invoked from a Makefile. Including an entire script, sandwiched into one line.
Here's the right answer:
However, the above approach is the wrong one. You will find that many free software packages do this kind of thing all the time: conditionally link in a library, if it's available.
But the way that it's done is by running a separate configure script, before running make. Go grab the source tarball to a random free software package, of your choosing, and read the installation instructions. They will all tell you to run the configure script first, before running make.
A crushing majority of free software packages use the GNU toolchain to create their build system -- the configure script, and the Makefile. The GNU toolchain consists of autoconf and automake tools (also libtool in many cases). Go Google these, for more information.
There are also a few other, less popular toolchains, but the GNU toolchain is the most frequently one used, for this sort of a thing. So, to do something along the lines of what you're trying to do, the way this gets typically done is:
In the configure.ac file:
AC_CHECK_LIB(hwloc,some_function_in_the_hwloc_library,[LINK_HWLOC=-lhwloc])
AC_SUBST(LINK_HWLOC)
In the Makefile.am file:
hwloc_LDADD=#LINK_HWLOC#
That's it. That's the way this is done the countless number of times most free software packages need to do this exact same thing. autoconf and automake will take care of writing the shell script and the makefile, that implements this.
I don't have access to a Linux machine at the moment so pardon me my answer will be untested.
I will respectfully disagree with both of my predecessors.
First, using autotools to amend an existing Makefile is a bad idea. Autotools are made to avoid worrying about creating a good Makefile in a simple use case. It's as if OP asked "How to change + to - in my Python script" and the answer was "write a shell script to modify the script, save it in temporary file and execute the file"
Second answer, why do something manually when it can be painlessly done automatically?
So, IMHO the correct answer is, this is the exact use case for $(wildcard):
xfoo: foo.o $(wildcard libhwloc.a)
gcc $(patsubst lib%.a, -l%, $^) -o $#
Note: the library is installed or not ahead of time but not to be made during the build.
If you don't want to get involved with the autotools/etc. for this (which while a reasonable solution is also reasonable to want to avoid for something this simple) and you don't want to have to play guessing games about where people may or may not have this hwloc library installed then the best you can do is to let people turn the feature on manually.
Use three (or four) make variables. USE_HWLOC, HWLOC_LDLIBS, HWLOC_CFLAGS and possibly HWLOC_LDFLAGS.
Then when USE_HWLOC is defined you link against the library and use the other three variables in case they have also been set.
ifdef USE_HWLOC
HWLOC:=-lhwloc
else
HWLOC:=
HWLOC_LDLIBS:=
HWLOC_LDFLAGS:=
HWLOC_CFLAGS:=
endif
xfoo : foo.o
gcc foo.o -o $# $(HWLOC_LDLIBS) $(HWLOC)
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 $^ ../../
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