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

Simple Makefile issue

Hi,
I'm getting started with the arm/linux/gnu flow and I wish to have a makefile with multiple targets, as i'm cross compiling for a arm platform but i also want to check everything is running ok on my X86 laptop.  But with my makefile below it always seems to pick up the ARM rule, despite the fact i issue from the command line make as opposed to make ARM? Also as i'm new to makefile, if you've any suggestions how to make my makefile "better" that would be great too! thanks

EXE := prog
SRCS:= src/a.cpp src/b.cpp  
OBJS = $(SRCS:%.cpp=%.o)
INCDIR = -I. -I.. -Iincludes
#------------------------------------------------------------------------
CC        := g++
ARMCC     := arm-linux-g++
#Optimization and debug info options
OPT       := -O3
DEBUG     := -01 -g
PROFILE   := -pg
OTHER     := -Wall -Wno-deprecated -Wno-char-subscripts
OTHER_ARM := -barm-linux -Wa,-mcpu=arm9tdmi -Wall -Wno-deprecated -Wno-char-subscripts
CFLAGS    := $(OPT) $(OTHER)
#------------------------------------------------------------------------
# Default rule:
$(EXE) : $(OBJS)
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)
      /bin/rm -f $(OBJS) includes/*~ *~ src/*~
%.o : %.cpp
      $(CC) $(CFLAGS) $(INCDIR) -c -o $@ $<  
#------------------------------------------------------------------------
#Debug
debug : $(OBJS)
      $(CC) $(OPT) $(OTHER) $(DEBUG) -o $(EXE) $(OBJS)
%.o : %.cpp
      $(CC) $(OPT) $(OTHER) $(DEBUG) -c -o $@ $<        
#------------------------------------------------------------------------
#Profile
profile : $(OBJS)
      $(CC) $(OPT) $(OTHER) $(PROFILE) -o $(EXE) $(OBJS)
%.o : %.cpp
      $(CC) $(OPT) $(OTHER) $(PROFILE) -c -o $@ $<       
#------------------------------------------------------------------------
#Cross compile for ARM
ARM : $(OBJS)
      $(ARMCC) $(OTHER_LINK) $(OPT) $(INCDIR) -o $(EXE) $(OBJS)
%.o : %.cpp
      $(ARMCC) $(CFLAGS) $(INCDIR) -c -o $@ $<  

#------------------------------------------------------------------------
clean:
      /bin/rm -f $(EXE) $(OBJS) includes/*~ *~ src/*~

# Dependancies
b.o : a.h
a.o : a.h
0
pixitron
Asked:
pixitron
  • 8
  • 8
1 Solution
 
jkrCommented:
>># Default rule:
>>$(EXE) : $(OBJS)

That does not really specify the default rule - a default rule would be

.DEFAULT: $(EXE)
0
 
pixitronAuthor Commented:
right that makes more sense. So i made the change. However its still always picking up the arm cross compile rule (well it appears to pick up the arm cross compile rule for the src files and default rule for linking)?
0
 
pixitronAuthor Commented:
any more ideas?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
pixitronAuthor Commented:
tried wrapping the ARM crosscompile rules in an ifdef arm,, but if i type  make arm, make then compains there is no rule for arm
0
 
cupCommented:
You have multiple rules for

%.o : %.cpp

The last one defined wins.  If you have several different options, it is better to have several different makefiles and to have a master makefile invoking one of the others.
0
 
pixitronAuthor Commented:
Thanks cup,

thats exactly the behaviour i'm seeing all right (last rule winning). How would i go about having a master/slave makefiles? (any links would be great). Also would each of the "slave" makefiles then have their own dependancy listings as well (that seems like it would be a nightmare to maintain?).

Taking a step back is there a better way of doing what I'm trying to do?

I'm going to increase the points by 125 for this question.
0
 
cupCommented:
You have basically gotten it the wrong way round.  The assignments can change, the rules can't.  I've never seen := in makefiles before.  I assume it is the same as =

The top bit is the same until CFLAGS=

%.o: %.cpp
      $(CC) $(CFLAGS) $(INCDIR) -c -o $@ $<

vanilla: $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

debug:  $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER) $(DEBUG)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

profile:  $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER) $(PROFILE)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

ARM: $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER)
      CC=arm-linux-g++
      LFLAGS=whatever you have in OTHER_ARM
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

From clean: onwards it is the same.  You don't really need a master makefile for this case.  The master makefile idea is recursive normally use it for biggish projects which go over several directories.  The thing to remember is that the first colon and last rule wins.  In a makefile with several targets, if no parameters are provided, it makes the target in the first colon.

Make good use of whatever debugging flags your make provides.  Some provide more debugging information than others.  Some even use default makerules which they pick from somewhere else.  This isn't obvious until you switch on debugging.

Good luck.
0
 
pixitronAuthor Commented:
"You have basically gotten it the wrong way round..."

AHA! ok this is beginning to make more sense.  

For the ARM target though the compiler for the source code is not g++ its arm-linux-g++, won't the above rule compile the src files with g++ and try to link these files with arm-linux-g++ ?

Also I'm not sure what rule i should have for $(EXE) target - while i try to run the makefile, it compiles the src files but then says :  

make: *** No rule to make target `neuro', needed by `vanilla'.  Stop.

(exe= neuro btw)

Thanks a million for the help! Current Makefile is below

------------------------------------------------------------------------------------------------------------------------------
EXE := neuro
SRCS:= ***********
OBJS = $(SRCS:%.cpp=%.o)
INCDIR = -I. -I.. -Iincludes
#------------------------------------------------------------------------
#Optimization and debug info options
OPT       := -O3
DEBUG     :=  -g
PROFILE   := -pg
OTHER     := -Wall -Wno-deprecated -Wno-char-subscripts
#------------------------------------------------------------------------
%.o: %.cpp
      $(CC) $(CFLAGS) $(INCDIR) -c -o $@ $<

#------------------------------------------------------------------------
vanilla: $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)
#------------------------------------------------------------------------
debug:  $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER) $(DEBUG)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)
#------------------------------------------------------------------------
profile:  $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER) $(PROFILE)
      CC=g++
      LFLAGS=
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

#------------------------------------------------------------------------
#Cross compile for ARM Linux
#Surely compile of src files with g++ will cause a problem??
ARM: $(OBJS) $(EXE)
      CFLAGS=$(OPT) $(OTHER)
      CC=arm-linux-g++
      LFLAGS=-barm-linux -Wa,-mcpu=arm9tdmi -Wall -Wno-deprecated -Wno-char-subscripts
      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)

#------------------------------------------------------------------------
clean:
      /bin/rm -f $(EXE) $(OBJS) includes/*~ *~ src/*~

#------------------------------------------------------------------------
# Source Dependancies




0
 
cupCommented:
Oops - sorry $(EXE) should not be a dependency.   It should be

vanilla: $(OBJ)
   ...

0
 
pixitronAuthor Commented:
Ok, however I'm still getting a problem from...

vanilla: $(OBJS)
<TAB>      CFLAGS=$(OPT) $(OTHER)
<TAB>      CC=g++
<TAB>      LFLAGS=
<TAB>      $(CC) $(CFLAGS) $(INCDIR) -o $(EXE) $(OBJS)


CFLAGS=-O3 -Wall -Wno-deprecated -Wno-char-subscripts
/bin/sh: line 1: -Wall: command not found
make: *** [vanilla] Error 127
0
 
cupCommented:
It looks like the commands are being executed.  Try changing your = to :=
As I said earlier, I haven't used this version of make before.  It looks like  = is a shell assignment and := is a make assignment.
0
 
pixitronAuthor Commented:
I'm using (GNU) make under linux (RH9). Tried changing = to :=  but it didn't make any difference.


increasing points again
0
 
cupCommented:
If I can get my Linux box started (about 4 years since I've switched it on) I'll try out your make stuff.  At a guess, it doesn't like the assignments.  I'll try a few experiments to see if I can get it done in one makefile.  The alternative is to have 5 makefiles.
0
 
cupCommented:
Managed to ressurect my Linux box.   Anyway try this - it uses make recursively.  Not the best option but sometimes make is a pig and it is the easiest way around it

EXE := neuro
SRCS:= a.cpp b.cpp
OBJS = $(SRCS:%.cpp=%.o)
INCDIR = -I. -I.. -Iincludes
#------------------------------------------------------------------------
#Optimization and debug info options
OPT       := -O3
DEBUG     :=  -g
PROFILE   := -pg
OTHER     := -Wall -Wno-deprecated -Wno-char-subscripts
CFLAGS=$(OPT) $(OTHER)
# these may be overridden by the recursive make parameters
EXTRA=
CC=g++
LFLAGS=
#------------------------------------------------------------------------
%.o: %.cpp
      $(CC) $(CFLAGS) $(EXTRA) $(INCDIR) -c -o $@ $<

#------------------------------------------------------------------------
target:  $(OBJS)
      $(CC) $(CFLAGS) $(EXTRA) $(INCDIR) -o $(EXE) $(OBJS)
#------------------------------------------------------------------------
debug:
      make EXTRA="$(DEBUG)"
#------------------------------------------------------------------------
profile:
      make EXTRA="$(PROFILE)"
#------------------------------------------------------------------------
#Cross compile for ARM Linux
#Surely compile of src files with g++ will cause a problem??
ARM:
      make CC=arm-linux-g++ LFLAGS="-barm-linux -Wa,-mcpu=arm9tdmi -Wall -Wno-deprecated -Wno-char-subscripts"

#------------------------------------------------------------------------
clean:
      /bin/rm -f $(EXE) $(OBJS) includes/*~ *~ src/*~

0
 
cupCommented:
Forgot to say that the command line parameters override local settings.

Use "make -d" to see what is happening.
0
 
cupCommented:
Just realized that LFLAG isn't used anywhere.  The parameter should be CFLAG

EXE := neuro
SRCS:= a.cpp b.cpp
OBJS = $(SRCS:%.cpp=%.o)
INCDIR = -I. -I.. -Iincludes
#------------------------------------------------------------------------
#Optimization and debug info options
OPT       := -O3
DEBUG     :=  -g
PROFILE   := -pg
OTHER     := -Wall -Wno-deprecated -Wno-char-subscripts
CFLAGS=$(OPT) $(OTHER)
# these may be overridden by the recursive make parameters
EXTRA=
CC=g++
#------------------------------------------------------------------------
%.o: %.cpp
      $(CC) $(CFLAGS) $(EXTRA) $(INCDIR) -c -o $@ $<

#------------------------------------------------------------------------
target:  $(OBJS)
      $(CC) $(CFLAGS) $(EXTRA) $(INCDIR) -o $(EXE) $(OBJS)
#------------------------------------------------------------------------
debug:
      make EXTRA="$(DEBUG)"
#------------------------------------------------------------------------
profile:
      make EXTRA="$(PROFILE)"
#------------------------------------------------------------------------
#Cross compile for ARM Linux
#Surely compile of src files with g++ will cause a problem??
ARM:
      make CC=arm-linux-g++ CFLAGS="-barm-linux -Wa,-mcpu=arm9tdmi -Wall -Wno-deprecated -Wno-char-subscripts"

#------------------------------------------------------------------------
clean:
      /bin/rm -f $(EXE) $(OBJS) includes/*~ *~ src/*~

#------------------------------------------------------------------------
#------------------------------------------------------------------------
# Source Dependancies

0
 
pixitronAuthor Commented:
excellent! I don't know whether the recursive option is good or bad, but it certaily solves my problem! and I've learned alot about makefiles.

thanks again for the all the effort!
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

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