Change Between GNU Make and Clearmake Compilers During a Build - makefile

Is it possible to switch from Clearmake to GNU make at a certain point in a build and then switch back? If so, how so?

Note, neither GNU make nor clearmake are compilers.
All make versions are just tools for running other commands, so you can just write a rule that will run a different make as a command:
run-make:
gmake do-something
Now when the run-make rule is invoked it will call GNU make (here called gmake, but it might be called make or whatever) to build a target do-something. Once that's done it'll return back to the current make version (presumably clearmake).
With the minimal information you provided, that's the best we can do.

Related

How to use make install or uninstall inside a makefile?

I am writing a recipe to configure and install some software in Ubuntu using makefiles, and I know you need $(MAKE) instead of make inside the makefile, but is it possible to install a given package just by typing $(MAKE) install package?
Thanks
Make is not a shell, and makefiles are not shell scripts. You really need to remember that - don't try to write a shell script and put it in a makefile. Make is a "declarative" language and not a "procedural" like a script.
You need to understand what files you expect to have after the installation, and what files you have before the installation, and what commands are used to go from the latter to the former. Then make rules where the former depend on the latter, with those commands in the recipes.
If that sounds like too much work, and it may very well be, then, you need to not use a Makefile, but write yourself a shell script instead, and call it in addition (probably after) using Make.
install and package are not files you expect to have after the installation, so they should not have recipes written for them. They may be considered "phony" Make targets, but then, you still need to depend them on "real" files, and write detailed recipes for those.

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).

What's the difference between MinGW, GNU and Cywin makefiles?

Are there any? I'd like to have one makefile handle all the build targets across platforms.
MinGW and GNU are the same. Both use GNU Make (go figure!). There are options for Cygwin, including GNU make, cmake and possibly others. If you go with the same make, then you have a starting point for portable Makefiles. However ...
Makefile recipes often include OS-specific commands as each line in a recipe is handed off to the OS command shell for execution.
The tools available under a specific OS may vary.
Paths are always a bit of a challenge.
Cygwin and MinGW each provide environments that attempt to mimic UNIX and make the issues above easier to deal with.

Convert gmake Makefile to make Makefile?

Does a utility exist to convert a GNU Makefile for gmake to a Makefile that can be used for make (FreeBSD-make)?
That utility is called a developer (programmer, make guru, ...) :-)
Seriously, the AI required for this task is complex enough and the demand for automatic conversion sufficiently close to epsilon that nobody would seriously consider programming one.
If you have a GNU makefile it is best to use GNU make.
As already noted there are no such converter and I very doubt there could exist such. As I understand you have two options:
Use GNU make port to FreeBSD. For example this.
Patch makefiles to make them compatible with FreeBSD make. Actually there are not too much of them in LuaJIT (main Makefile and src/Makefile). This should be rather easy. Just make sure you have all tools (check what is called in shell), and fix "error"s step by step.
For example, error on line 29 (export PREFIX= /usr/local) is due to GNU make directive export which has no similar in FreeBSD make. The manual says "Environment variables are set outside the Makefile in the shell that is running make" and thus you have to comply with this requirement.
Also you'll need to fix all make conditionals and etc, the whole bunch of differences is collected in BSD make vs. GNU make
It is unlikely that there is one because there are things you can do in GNU make that you can't do in other versions of make. Amongst others, the function macros for manipulating strings and the conditionals in the makefile are generally not available.

Resources