• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1013
  • Last Modified:

makefile and conditional compilation

I have an application with *many* source files that can be compiled "normally" or with a "debug" option.
The compilation is dependant on the -DDEBUG compiler switch.

How can I set up a makefile so that I can type in either:

make app_debug (to make the debug version)
or
make app (to make the non-debug version)

Basically the problem is this:
Once I make the debug version (using the -DDEBUG switch) the object files are timestamped as being younger than the source files. So when I try to make the non-debug version nothing gets "re-compiled".

Currently I link the source files to different names which causes differnet object file names to be created.

i.e.
I link source.c to source_d.c
so that
source.c compiles to source.o
source_d.c compiles to source_d.o

I think this is a clumsy way to do waht I need, can anyone suggest a more elegant approach?

Paul
0
zebada
Asked:
zebada
  • 9
  • 4
1 Solution
 
jkrCommented:
You could just specify a different output path for each target like e.g. VC++ does - this would keep the (equally named) object files n different directories, so that no time-stamp confusion would take place...
0
 
AxterCommented:
You can also change the name of the output targets.
For example, all the debug versions you can name foo.debug_o and release version foo.o
0
 
zebadaAuthor Commented:
The real question is how do I do that in the makefile?

I am currently using my own implicit .c.o: rule to compile my c source files.
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
AxterCommented:
Is this for Unix/Linux or Dos?
0
 
AxterCommented:
If you're doing Unix/Linux, you can create two script files.

One haveing the following:

#*********************************************************
# Set environmental variable
setenv REL_OR_DBUG debug_
# Launch make file with commandlines given to script file
make NameOfMyMakeFile %1 %2 %3 %4 %5
#*********************************************************

The other script file can be the following:
#*********************************************************
# Set environmental variable
setenv REL_OR_DBUG ""
# Launch make file with commandlines given to script file
make NameOfMyMakeFile %1 %2 %3 %4 %5
#*********************************************************


Then in your make file have the following:
PRGSUB = $(CSRCS:cpp=$(REL_OR_DBUG)o)
PRG  = $(PRGSUB:c=$(REL_OR_DBUG)o)
OBJS = $(PRG)
0
 
AxterCommented:
You can also just do one script file and make the first command line argument the environmental variable for REL_OR_DBUG.

Example:
#*********************************************************
# Set environmental variable
setenv REL_OR_DBUG %1
# Launch make file with commandlines given to script file
make %2 %3 %4 %5 %6 %7
#*********************************************************

You would call the above script file in the following manner.

MyScriptFileName debug_ NameOfMyMakeFile

If you have additonal command lines just added to the end.
Example:

MyScriptFileName release_ NameOfMyMakeFile buildme

Or

MyScriptFileName rel_ NameOfMyMakeFile clean

0
 
AxterCommented:
Correction on the makefile syntax:

PRGSUB = $(CSRCS:cpp=${REL_OR_DBUG}o)
PRG  = $(PRGSUB:c=${REL_OR_DBUG}o)
OBJS = $(PRG)

It may be hard to tell with the fonts on this web site, but the REL_OR_DBUG variable has "curly cue" {} wrapped around them.
Environmental variables get curly cues {}, and NOT the parenthesis "()" that normal make file variables get.
0
 
zebadaAuthor Commented:
Platforms:
SCO
HP-UX
Solaris
Tru64 (DEC Alpha OSF1)
Linux
AIX

If I have something like this in my makefile:

HDR=            a.h b.h c.h

SRC=            a.c b.c c.c

OBJ=            $(SRC:.c=.o)

prog:           $(OBJ)

$(OBJ):         $(HDR)

This is my .o.c: rule:
.c.o:           $<
                $(CC) $(ALL_CFLAGS) -c $<

How can I make the $(CC) command output to the different object file names (for debug and non-debug) based on the value of an env variable?

0
 
AxterCommented:
Here's a section of one of my old make files.
Just ignore what you don't need.
If you're interested, I can also show you how to make different targets, depending on your unix platform, by using `uname`


######################################################################
.SUFFIXES: .c .cpp .h .$(REL_OR_DBUG)o

.cpp.$(REL_OR_DBUG)o:; @echo "$(<:cpp=cpp):1: Creating: Object File from *.cpp" ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:cpp=$(REL_OR_DBUG)o)"..."
     $(CXX) $(CXXFLAGS) -c $< -o ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:cpp=$(REL_OR_DBUG)o)
     cp -fp -- ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:cpp=$(REL_OR_DBUG)o) ${XPLATFORMX}/${COMPILER_OBJECT_ID}/../..

.c.$(REL_OR_DBUG)o:; @echo "$(<:c=c):1: Creating: Object File from *.c" ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:c=$(REL_OR_DBUG)o)"..."
     $(CC) $(CFLAGS) -c $< -o ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:c=$(REL_OR_DBUG)o)    
     cp -fp -- ${XPLATFORMX}/${COMPILER_OBJECT_ID}/$(<:c=$(REL_OR_DBUG)o) ${XPLATFORMX}/${COMPILER_OBJECT_ID}/../..

)
0
 
AxterCommented:
zebada,
Did the above script code answer your question?
0
 
zebadaAuthor Commented:
I'll take a look at it later this week - been too busy.
0
 
AxterCommented:
OK
0
 
zebadaAuthor Commented:
Thanks Axter,
Sorry it took so long - the project finally got the go-ahead to redesign the make files.
The suffix substitution did the trick :)
0
 
AxterCommented:
Glad to be of help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 9
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now