CMake: Generate Unix Makefiles which ignore errors - makefile

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.

Related

Makefile generate by CMake contains 'cmake' command

I'm trying to use cmake for the first time and it seam to be good except one things.
In the generated makefile, there are some kind of 'cmake command'. Like :
$(CMAKE_COMMAND) -E cmake_progress_start ... etc ...
I really want to generate makefile without any $(CMAKE_COMMAND).
Is it possible ?
Thx.
I doubt you can achieve that, because cmake executable is used to regenerate Makefiles if any of CMakeLists.txt are changed.
I just want to generate Makefile and ensure me that I can build my source code without Cmake.
I found a solution by just do :
make -i
It will ignore error and a call to cmake append and that work. It's a huge workaround but that's work so...
Thx for your answer.

What is meaning of Path-like target in Make?

I don't have idea that what is meaning of path-like target specification.
I would like to see execute commands in Makefile that generated by cmake to know that build process of clang.
I saw it with make -n command, it seems like executed other make command like following.
make -f utils/hmaptool/CMakeFiles/hmaptool.dir/build.make utils/hmaptool/CMakeFiles/hmaptool.dir/build
I have no idea what above make command do it.
In this command, target specification is path-like.(utils/hmaptool/CMakeFiles/hmaptool.dir/build)
What is meaning of this?
I know non-path-like target, for example make install or make clean and so on.
But I have no idea path-like target.
What is this??
The above command will use the makefile utils/hmaptool/CMakeFiles/hmaptool.dir/build.make, and will attempt to build the target utils/hmaptool/CMakeFiles/hmaptool.dir/build.
You will have to check the makefile to know what exactly build is. Probably a PHONY target to build everything in that folder.

Conditional linking in Makefile

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)

How to Change the Default Command That make Executes?

By default, when running make to compile a C source code file named prog.c
make prog
the default command that executes is
cc prog.c -o prog
Sometimes I really need to include some additional flags. I know that when there are no Makefiles, make relies on some environment variables.
On Ubuntu 14.04, how to configure these variables to change the command that gets executed by default?
Step by step answers will be appreciated!
When no makefile is present (or no rule exists in that makefile) make relies on a default built-in database of rules. Run make -p to get make to spit out all the rules it knows about (in the no makefile case that will be the default ones).
When you look at that list you will find a pattern rule for building C source into object files or executables. Those rules have variables in them (like CFLAGS, LDFLAGS, etc.) that can be used to control exactly what you are trying to. That's why they are there (and are why that default command has such funny spacing, in case you ever wondered about that).

Getting GNU Make and NMake to use different makefiles by default

I want a project to be buildable with both GNU Make (on Linux) and NMake (on Windows). Obviously, I can have the makefiles called Makefile and Nmakefile and build by using make and nmake /F Nmakefile respectively. Is there a pair of names such that make and nmake without -f//F options work?
According to documentation, NMake looks for .mak files, so I've tried to use Makefile.mk and Nmakefile.mak, but it didn't work.
According to the man page of GNU make, it will first look for a file called GNUmakefile.
from man make:
Normally you should call your makefile
either makefile or Makefile. (We
recommend Makefile because it appears
prominently near the beginning of a
directory listing, right near other
important files such as README.) The
first name checked, GNUmakefile, is
not recommended for most makefiles.
You should use this name if you have a
makefile that is specific to GNU
make, and will not be understood by
other versions of make. If makefile
is `-', the standard input is read.
so call your gnu Makefile GNUmakefile

Resources