Convert gmake Makefile to make Makefile? - 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.

Related

Change Between GNU Make and Clearmake Compilers During a Build

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.

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)

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.

Why don't developers use the `install` command?

While looking at my friend's Makefile, I noticed that he used the install shell command. From what I can tell, the command allows you to install and chmod files with one fell swoop. The command came up in a subsequent conversation of ours, and he said he had heard that the command is considered somewhat archaic, and that developers should use cp, mv, chmod etc. for modern projects.
Strangely, this has been my only encounter with the command. This leads me to believe that the command has indeed been rejected and hence forgotten. Is this true? Is there some sort of security flaw with the program? From my possibly naive point of view, using a single command is always better than using many commands
I suspect the answer is that the install command is pretty much only used in scripts and makefiles (such as the automake makefiles that #Jack Kelly describes), and almost never interactively. Thus people rarely see it 'over someone's shoulder', and it doesn't lodge in their consciousness.
It is however, as you say, pretty much exactly the right tool for this job. The problem is that it's not a POSIX command, so it's wise not to use any terribly exotic options. The version of it used in automake makefiles is supplemented by a distributed shell script if the configure script hasn't convinced itself that the local version is sufficiently compatible.
See the autoconf manual's discussion of portable shell scripting, for some useful tips on this general topic.
Makefiles generated by automake still use it, as evidenced by the line (or similar):
checking for a BSD-compatible install... /usr/bin/install -c
in the output of configure.

Resources