I have encountered errors on running the conditional assignment operator in a Makefile in Solaris 11.1. However I encounter no errors on running the same Makefile in Ubuntu.
version ?= 6.1
all:
echo $(version)
Note: Before the echo, there is a tab before the echo in the original code. Using four spaces here just for convenience of editing.
Error encountered in Solaris 11.1:
make: Fatal error in reader: Makefile, line 1: Badly formed macro assignment
However, there are no such errors on Ubuntu.
Better you use gmake because many Makefiles use Gnu-specific features. Solaris make might be using slightly different syntax. You can read the Solaris makefile manual; you will find that there is no ?= operator in it. Hence you are getting that error.
?= is a feature added by GNU make, which is the default version of make on Ubuntu, but on Solaris is installed as gmake or /usr/gnu/bin/make. ?= is not supported by the native make command on Solaris, which is installed as /usr/ccs/bin/make on older releases, /usr/bin/make on Solaris 11 and later.
If you need to use the GNU extensions in your makefiles, make sure you run the GNU make, not the Solaris make.
Related
Within a Makefile on linux, we can excute shell/bash commands with it to move directories or excute another files. However when porting the same Makefile over to macOS, all the commands are not readible (therefore path and execution are broken). Is there a universal command or workflow that can work on both?
Example of Makefile
.ONESHELL:
COMMAND ?= none
GIT_HASH ?= githash
alpine:
#cd images/alpine
#make ${COMMAND} GIT_HASH=${GIT_HASH} ALPINE_VERSION=3.6.5 TAG=3.6
so in a linux box both #CD and #MAKE are executed but not for macOS Catalina. I would like to make it universal so that both system will respect the appropriate command that follows.
Chances are that your MacOS box uses its default GNU make version (3.81). .ONESHELL was introduced with 3.82. Upgrade with Homebrew or MacPort. Anyway, better avoid make in recipes, prefer $(MAKE), and instead of cd; make you can use GNU make's -C option: $(MAKE) -C images/alpine ...
I get /bin/sh: -c: line 1: syntax error: unexpected end of file for the if statement in the makefile below — what's wrong? (My prompt is /tmp >.)
/tmp > make test
set -e
if [[ -f /tmp/device ]] ; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [test] Error 2
/tmp > cat Makefile
.ONESHELL:
test:
set -e
if [[ -f /tmp/device ]] ; then
echo 'Do something'
fi
I am using GNU Make 3.81.
Using GNU Make 3.81, the .ONESHELL feature is demonstrably not supported — you showed that, and I showed that. I tested on Mac OS X 10.11.5, with the supplied /usr/bin/make as GNU Make 3.81. I demonstrated to my satisfaction by adding strategically placed echo PID=$$$$ lines before set -e, after it, and so on, and observed different PID values. GNU Make version 3.81 is from 2006 (there was also version 3.82 from 2010, before version 4.x was released, starting with 4.0 in 2013).
The current version of GNU Make is 4.2.1 (June 2016). That version does support the feature; your script works as expected when using a sufficiently recent version of GNU Make. It is a feature that has been around for a while — you probably don't have to upgrade to the latest to get the support, but why would you go with a down-version if you're going to upgrade anyway.
If you wish to use the .ONSHELL: feature, you'll have to ensure you are using a new enough version of GNU Make (newer than version 3.81). If that's not feasible, don't use the feature.
Reading the NEWS file from 4.2.1, it is clear that ONESHELL was added to GNU Make version 3.82:
Version 3.82 (28 Jul 2010)
…
* New special target: .ONESHELL instructs make to invoke a single instance
of the shell and provide it with the entire recipe, regardless of how many
lines it contains. As a special feature to allow more straightforward
conversion of makefiles to use .ONESHELL, any recipe line control
characters ('#', '+', or '-') will be removed from the second and
subsequent recipe lines. This happens _only_ if the SHELL value is deemed
to be a standard POSIX-style shell. If not, then no interior line control
characters are removed (as they may be part of the scripting language used
with the alternate SHELL).
I'm running make on my project on WIN7 PC and getting the following error:
make: Interrupt/Exception caught (code = 0xc0000005, addr = 0x0040b0ac)
when removing some make parts it seems as the following line is the problematic:
$(shell if exist $(1) echo YES)
Any ideas what seems to be the issue? solutions?
Thanks!
Update:
I'm working with gnu make 3.81.1 mingw32 , same make and makefile used to work on my previous WIN XP (32 bit), problem appeared after upgrading to WIN7 .
OK, I think I've got it.
Apparantly it is something related to the PATH, if I replace the "shell" command with a predefined :
_SHELL=C:/Windows/System32/cmd.exe
the problem is fixed. might be because of severl c:\Program Files PATH instances .
Upgrading to 3.82 fixes the issue as well so I guess the've fixed that
Thanks!
There are a number of different ways GNU make can be built for windows, and the different ways will use different shells for the $(shell ...) command. I don't actually know if any of them will ever invoke Windows command.com or not.
But in any event, it doesn't seem like your version of GNU make works properly in that way. You should update your question with where you got your GNU make from (cygwin? mingw?) or how you built it, if you built it yourself.
Also you might ask on the make-w32#gnu.org mailing list, where Windows users of GNU make hang out.
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.
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