For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > February 2007 > Problem with a conditional part of Makefile









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Problem with a conditional part of Makefile
Andrew Falanga

2007-02-07, 7:06 pm

Hello,

In my Makefile, I have to check that the compiler is the correct one.
Currently, I have this:

# start of Makefile

GCC = $(shell which g++)

ifeq (${GCC},"/usr/bin/g++")
$(error Incorrect compiler, please use /path/to/compiler/g+
+)
endif

When I test to see if this works, by making sure that which g++
resolves to /usr/bin/g++, make just goes right through and starts
compiling. Am I not getting something right in syntax, or am I
misunderstanding the error function in gmake?

Andy

Jens Thoms Toerring

2007-02-07, 7:06 pm

Andrew Falanga <af300wsm@gmail.com> wrote:
> In my Makefile, I have to check that the compiler is the correct one.
> Currently, I have this:


> # start of Makefile


> GCC = $(shell which g++)


> ifeq (${GCC},"/usr/bin/g++")
> $(error Incorrect compiler, please use /path/to/compiler/g+
> +)
> endif


> When I test to see if this works, by making sure that which g++
> resolves to /usr/bin/g++, make just goes right through and starts
> compiling. Am I not getting something right in syntax, or am I
> misunderstanding the error function in gmake?


If I understand you correctly you want to enforce the use of
/usr/bin/g++ whenever just g++ is specified. Then you need to
use 'ifneq' instead of 'ifeq' in the condition and you also
need to leave out the double quotes. And the next line where
you stop the program will work only if you _don't indent it
wwith a tab - otherwise it's interpreted as a command, but
commands are only allowed ithin rules. So use instead

ifneq (${GCC},/usr/bin/g++)
$(error Incorrect compiler, please use /path/to/compiler/g++)
endif

But why don't you simple set the variable GCC to /usr/non/g++
and use tat variable whereever you invoke the compiler? BTW,
how is the user supposed to "use /path/to/compiler/g++" if
"which g++" is something else? The only simple method I can
see would be to change PATH in order to have /path/to/compiler
getting found first but is that something a user should be
forced to do?
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Giorgos Keramidas

2007-02-07, 7:06 pm

On 7 Feb 2007 11:23:21 -0800, "Andrew Falanga" <af300wsm@gmail.com> wrote:
> Hello,
>
> In my Makefile, I have to check that the compiler is the correct one.
> Currently, I have this:
>
> # start of Makefile
>
> GCC = $(shell which g++)
>
> ifeq (${GCC},"/usr/bin/g++")
> $(error Incorrect compiler, please use /path/to/compiler/g+
> +)
> endif


Two notes:

* Note #1

The $(shell command) construct only works with GNU make. With other
make implementations, you may have to resort to nested variable
expansion, like:

CFLAGS_sunos_gcc_common = -O2 -pipe -ansi -pedantic -W -Wall
CFLAGS_sunos_i386_gcc = -m32
CFLAGS_sunos_amd64_gcc = -m64
CFLAGS_sunos_sparc_gcc = -m32
CFLAGS_sunos_sparcv9_gcc = -m64

CFLAGS_sunos_suncc_common = -mt -xO5 -Xc -v -D__EXTENSIONS__
CFLAGS_sunos_i386_suncc = -xarch=386
CFLAGS_sunos_amd64_suncc = -xarch=amd64
CFLAGS_sunos_sparc_suncc = -xarch=v7
CFLAGS_sunos_sparcv9_suncc = -xarch=v9

CFLAGS = $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_common) \
$(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_$(TARGET_ARCH))

* Note #2

The g++ compiler is *not* a good compiler for standard, conforming ANSI
C programs. There are very subtle, but important differences between a
proper C compiler and a proper C++ compiler. So, use gcc for C
programs, and g++ for C++ programs.

Giorgos Keramidas

2007-02-07, 7:06 pm

On Wed, 07 Feb 2007 22:43:30 +0200, Giorgos Keramidas <keramida@ceid.upatras.gr> wrote:
> The $(shell command) construct only works with GNU make. With other
> make implementations, you may have to resort to nested variable
> expansion, like:
>
> CFLAGS_sunos_gcc_common = -O2 -pipe -ansi -pedantic -W -Wall
> CFLAGS_sunos_i386_gcc = -m32
> CFLAGS_sunos_amd64_gcc = -m64
> CFLAGS_sunos_sparc_gcc = -m32
> CFLAGS_sunos_sparcv9_gcc = -m64
>
> CFLAGS_sunos_suncc_common = -mt -xO5 -Xc -v -D__EXTENSIONS__
> CFLAGS_sunos_i386_suncc = -xarch=386
> CFLAGS_sunos_amd64_suncc = -xarch=amd64
> CFLAGS_sunos_sparc_suncc = -xarch=v7
> CFLAGS_sunos_sparcv9_suncc = -xarch=v9
>
> CFLAGS = $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_common) \
> $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_$(TARGET_ARCH))


That should have been:

CFLAGS = $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_common) \
$(CFLAGS_$(TARGET_SYSTEM)_$(TARGET_ARCH)
_$(BUILD_COMPILER))

of course :)
Andrew Falanga

2007-02-07, 7:06 pm

On Feb 7, 1:20 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Andrew Falanga <af300...@gmail.com> wrote:
>
> If I understand you correctly you want to enforce the use of
> /usr/bin/g++ whenever just g++ is specified. Then you need to
> use 'ifneq' instead of 'ifeq' in the condition and you also
> need to leave out the double quotes. And the next line where
> you stop the program will work only if you _don't indent it
> wwith a tab - otherwise it's interpreted as a command, but
> commands are only allowed ithin rules. So use instead


No. I want to ensure that /usr/bin/g++ isn't used. I'm testing to
see if which g++ returns a path other than /usr/bin/g++.

>
> ifneq (${GCC},/usr/bin/g++)
> $(error Incorrect compiler, please use /path/to/compiler/g++)
> endif
>
> But why don't you simple set the variable GCC to /usr/non/g++
> and use tat variable whereever you invoke the compiler? BTW,
> how is the user supposed to "use /path/to/compiler/g++" if
> "which g++" is something else? The only simple method I can
> see would be to change PATH in order to have /path/to/compiler
> getting found first but is that something a user should be
> forced to do?


Sorry about the example. I wanted only to show what I was trying to
do without giving extraneous information. Actually, to get the
correct compiler requires the users to execute a shell script to alter
the environment. It's more involved than simply setting a variable,
or altering only the PATH env variable. I don't actually maintain the
scripts or the build environment here, so I'm not sure how involved.

At any rate, I made a BASH build script that users *should* use to
build this code. But I know that someone will try to build simply by
typing "make" when they get to this directory. That why I wanted this
check in place. I'm still not able to get this to work. I noticed
above that you gave, in your example,

ifneq ($(GCC),/usr/bin/g++)

instead of

ifneq ($(GCC),"/usr/bin/g++")

I was using quotes. I changed to using no quotes and now I'm getting:

Makefile:6: *** commands commence before first target. Stop.

I moved the rule to being below the target "all" like an example I saw
in GNU manual for gmake, and again, the code just went through and
compiled. What is it I'm missing?

Andy

Andrew Falanga

2007-02-07, 7:06 pm

On Feb 7, 1:43 pm, Giorgos Keramidas <keram...@ceid.upatras.gr> wrote:
> On 7 Feb 2007 11:23:21 -0800, "Andrew Falanga" <af300...@gmail.com> wrote:
>
>
>
>
>
>
> Two notes:
>
> * Note #1
>
> The $(shell command) construct only works with GNU make. With other
> make implementations, you may have to resort to nested variable
> expansion, like:
>
> CFLAGS_sunos_gcc_common = -O2 -pipe -ansi -pedantic -W -Wall
> CFLAGS_sunos_i386_gcc = -m32
> CFLAGS_sunos_amd64_gcc = -m64
> CFLAGS_sunos_sparc_gcc = -m32
> CFLAGS_sunos_sparcv9_gcc = -m64
>
> CFLAGS_sunos_suncc_common = -mt -xO5 -Xc -v -D__EXTENSIONS__
> CFLAGS_sunos_i386_suncc = -xarch=386
> CFLAGS_sunos_amd64_suncc = -xarch=amd64
> CFLAGS_sunos_sparc_suncc = -xarch=v7
> CFLAGS_sunos_sparcv9_suncc = -xarch=v9
>
> CFLAGS = $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_common) \
> $(CFLAGS_$(TARGET_SYSTEM)_$(BUILD_COMPIL
ER)_$(TARGET_ARCH))
>


Being a make and make file novice, I didn't know this. Thanks.

> * Note #2
>
> The g++ compiler is *not* a good compiler for standard, conforming ANSI
> C programs. There are very subtle, but important differences between a
> proper C compiler and a proper C++ compiler. So, use gcc for C
> programs, and g++ for C++ programs.


I didn't even realize that one could compile a C++ program using gcc.
I'm trying to compile a C++ program with this make file, and that's
why I was using g++. I suspect I probably mislead you because of the
use of the variable name "GCC". Am I right? If so, sorry. Nearly
all, if not all, Makefiles I've ever looked through always use a
variable called CC or GCC, regardless of compiler being used. This
probably is bad form. I figured that gmake would not like the use of
the '+' character so I didn't try.

Andy

Jens Thoms Toerring

2007-02-07, 7:06 pm

Andrew Falanga <af300wsm@gmail.com> wrote:
> ifneq ($(GCC),"/usr/bin/g++")


> I was using quotes. I changed to using no quotes and now I'm getting:


> Makefile:6: *** commands commence before first target. Stop.


That's because you still have the tab character at the start of the
next line - if there's a tab it's taken to be a command and commands
can only be used in rules. If you instead have

($error stopped because of some error here)

at the very beginning of the line (or at least with only spaces in
front of it) that message will go away and it should work as expected
(hopefully;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Giorgos Keramidas

2007-02-07, 7:06 pm

On 7 Feb 2007 13:09:28 -0800, "Andrew Falanga" <af300wsm@gmail.com> wrote:
> On Feb 7, 1:43 pm, Giorgos Keramidas <keram...@ceid.upatras.gr> wrote:
>
> I didn't even realize that one could compile a C++ program using gcc.
> I'm trying to compile a C++ program with this make file, and that's
> why I was using g++. I suspect I probably mislead you because of the
> use of the variable name "GCC". Am I right? If so, sorry. Nearly
> all, if not all, Makefiles I've ever looked through always use a
> variable called CC or GCC, regardless of compiler being used. This
> probably is bad form. I figured that gmake would not like the use of
> the '+' character so I didn't try.


I was wrong, sorry. Now I see you are setting $(GCC), not $(CC)...

I apologize the the confusion.


Andrew Falanga

2007-02-07, 7:06 pm

On Feb 7, 2:17 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Andrew Falanga <af300...@gmail.com> wrote:
>
> That's because you still have the tab character at the start of the
> next line - if there's a tab it's taken to be a command and commands
> can only be used in rules. If you instead have
>
> ($error stopped because of some error here)
>
> at the very beginning of the line (or at least with only spaces in
> front of it) that message will go away and it should work as expected
> (hopefully;-)
> Regards, Jens
> --
> \ Jens Thoms Toerring ___ j...@toerring.de
> \__________________________ http://toerring.de


Thanks for your help on this one. Yes, this fixed it. WOW! That was
killing me. I thought the tab had to be there because of the display
of the make manual. Check it out:

http://www.gnu.org/software/make/ma...itional-Example

Thanks again.

Andy

Jens Thoms Toerring

2007-02-07, 7:06 pm

Andrew Falanga <af300wsm@gmail.com> wrote:
> On Feb 7, 2:17 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
[color=darkred]
> Thanks for your help on this one. Yes, this fixed it. WOW! That was
> killing me. I thought the tab had to be there because of the display
> of the make manual. Check it out:


> http://www.gnu.org/software/make/ma...itional-Example


Yes, but that example is for the use of a conditional in the command
part of a rule. But when you're not within the comman of a rule you
can't use commands (that all start with a tab). If you look at the end
of that page there's also an example of using a conditional before the
start of the rules and if you look very carefully you'll see that
the indentation is much less there than in the other examples (only 2
instead of 8 spaces are used), which probably is meant to indicate that
simple spaces instead of a tab are to be used...

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Andrew Falanga

2007-02-08, 7:07 pm

On Feb 7, 2:57 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Andrew Falanga <af300...@gmail.com> wrote:
>
>
>
>
> Yes, but that example is for the use of a conditional in the command
> part of a rule. But when you're not within the comman of a rule you
> can't use commands (that all start with a tab). If you look at the end
> of that page there's also an example of using a conditional before the
> start of the rules and if you look very carefully you'll see that
> the indentation is much less there than in the other examples (only 2
> instead of 8 spaces are used), which probably is meant to indicate that
> simple spaces instead of a tab are to be used...
>
> Regards, Jens
> --
> \ Jens Thoms Toerring ___ j...@toerring.de
> \__________________________ http://toerring.de


Ah, ok thanks again. This whole make program is quite involved I'm
finding.

Andy

Billy Patton

2007-02-08, 7:07 pm

Here's what I got to work

GCC := $(shell which g++)

ifneq "${GCC}" "/usr/XXXbin/g++"
$(error Incorrect compiler, please use /path/to/compiler/g++)
endif

all :
@echo ${GCC}


"Andrew Falanga" <af300wsm@gmail.com> wrote in message
news:1170876201.015959.174710@h3g2000cwc.googlegroups.com...
> Hello,
>
> In my Makefile, I have to check that the compiler is the correct one.
> Currently, I have this:
>
> # start of Makefile
>
> GCC = $(shell which g++)
>
> ifeq (${GCC},"/usr/bin/g++")
> $(error Incorrect compiler, please use /path/to/compiler/g+
> +)
> endif
>
> When I test to see if this works, by making sure that which g++
> resolves to /usr/bin/g++, make just goes right through and starts
> compiling. Am I not getting something right in syntax, or am I
> misunderstanding the error function in gmake?
>
> Andy
>



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com