Justin
Justin

Reputation: 742

Is it possible to define macros in makefiles conditionally?

I'm writing a makefile that has to be compatible with both LINUX and the HP-UX operating system. I'm aware that certain shell commands in LINUX are not compatible with HP-UX. Consequently, I was wondering if it was possible to have macros declared conditionally so that if it was determined that the OS was HP-UX, the macro would be defined a certain way and if the OS was LINUX, it would be defined differently?

OS       = `uname`
myOS     = Linux


ifeq ($(OS),$(myOS))
    message = "HELLO LINUX"
else
    message = "HELLO FOO" 
endif

all: install

install:
    echo $(message)

I've tried using the approach above; however, it seems that ifeq determines that OS and myOS are not the same. They should both be 'Linux', but it's outputting the else block instead.

Upvotes: 0

Views: 2050

Answers (3)

Levon
Levon

Reputation: 143122

Yes, you can define conditionals in makefiles.

This example taken from the above link

libs_for_gcc = -lgnu
normal_libs =

foo: $(objects)
ifeq ($(CC),gcc)
        $(CC) -o foo $(objects) $(libs_for_gcc)
else
        $(CC) -o foo $(objects) $(normal_libs)
endif

This shows the syntax for conditionals.

Given this defining anything specific should not be a problem. E.g., one could define/pass on marcos via the -D switch for a C program.

Update: To fix your problem with the OS variable not getting the output of the shell command uname you need to use shell function (as correctly pointed out by @AraundF): To quote from the link I posted:

"The shell function performs the same function that backquotes (``) perform in most shells ..."

so you were on the right track.

Upvotes: 2

Arnaud F.
Arnaud F.

Reputation: 8452

You shall use $(shell ...) in order to execute a SHELL command, this will work

OS       := $(shell uname)
myOS     := Linux


ifeq ($(OS),$(myOS))
    message := "HELLO LINUX"
else
    message := "HELLO FOO" 
endif

all: install

install:
    echo $(message)

Upvotes: 2

piokuc
piokuc

Reputation: 26204

What we used to do here is we define an environment variable ARCH on all systems we build stuff on, on a Linux system it will have value linux, on AIX aix, etc., in the Makefile we have:

include make.$(ARCH)

and for each platform we create a file called make.linux, make.aix, etc., with definitions specific for that platform, for example make.linux contains:

CC=g++

and make.aix contains

CC=xlC_r

This is quite a nice and clean approach, but nevertheless we are migrating to cmake ( http://www.cmake.org/ ) now.

Upvotes: 0

Related Questions