tags:

views:

152

answers:

4

Hello,

i need to build the same source tree twice,

1 - with normal cflags to build the project binary
2 - with cflags plus -fPIC to build a static library that would be some sort of SDK to develop project dynamic modules.

Using only one Makefile, what is the best approach to accomplish this?

It would be nice to do some sort of :

all: $(OBJECTS)

lib_rule: $(OBJECTS)
   CFLAGS += -fPIC

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

But obviously it can't be done.

Thanks

+4  A: 

One thing I've used in the past is a different extension:

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

.cpp.lo:
    $(CC) -c $< -o $@ $(CFLAGS) $(EXTRA_CFLAGS)

You then build your static library from the .lo files and you binary from the .o files:

prog: a.o b.o

libsdk.a: a.lo b.lo

Assuming you are using GNU Make, you can use some built in functions to only have to maintain the list of objects one time:

OBJS = a.o b.o
LOBJS = $(patsubst %.o, %.lo, $(OBJS))
R Samuel Klatchko
+1, this is what is commonly done in autotools/libtool-based projects.
greyfade
gonna try it now, let's see ...
Simone Margaritelli
yep it works, and i'm already using those kind of macros to obtain OBJECTS from SOURCES variable, so it's the same i guess ^^Thank you sooo much.
Simone Margaritelli
A: 

In a different make tool such as CMake, you can express something like that much more easily.

For instance, you could well do

set(sources ABC.cpp DEF.cpp XYZ.cpp)
ADD_LIBRARY(mylib STATIC ${sources})
add_executable(myExecutable  ${sources} main.cpp)

Or, you could repeatedly build the same directory with different flags by including it several times from the directory's logical parent, i.e.

set(MyTweakFlag 2)
add_subdirectory("libDir" "libDir2")
set(MyTweakFlag 3)
add_subdirectory("libDir" "libDir3")

...and then use if() or whatnot in the child directory to set the right flags.

Particularly if you have many such configurations, using make becomes quite fragile; make won't correctly find the transitive closure of recursive make dependancies (and certainly won't correctly find the dependancy on the makefile itself - if you change flags, say) so if you're going to do complicated makefile magic: do it with a better tool!

(CMake simply happens to be what I replaced make with, but there are various other replacements possible, of course)

Eamon Nerbonne
+1  A: 

Instead of placing the compiled .o files in the same directory as the source, I create them in labeled sub-directories. In your case, you can have the static library files created as source_dir/lib/*.o and your normal files as source_dir/bin/*.o. In your different build targets after you set up your unique CFLAGS, simply generate a DIR_NAME value holding the name of the appropriate sub-folder. You can use this variable when you create the paths for the compiler to use when building and when linking.

bta
i prefer not to modify the source tree structure, so the first answer was the most appropriate to my case.
Simone Margaritelli
You don't have to change your source tree structure in any way. The creation/deletion of the folders for the binary objects will be handled automagically by `make` or your compiler. The only change you would have to make would be inside your Makefile.
bta
+1  A: 

GNU make offers also "Target-specific Variable Values". Consider the following Makefile:

# Makefile  
CFLAGS := My Cflags

all: $(OBJECTS)  
        @echo "$@ CFLAGS is: " $(CFLAGS)  

lib_rule: CFLAGS += extended by -fPIC  
lib_rule: $(OBJECTS)  
        @echo "$@ CFLAGS is: " $(CFLAGS)  

# Makefile - end.

$ make all
all CFLAGS is: My Cflags
$ make lib_rule
lib_rule CFLAGS is: My Cflags extended by -fPIC
$
(Please note: if you copy and paste the example, remember to re-add the tabstops in front of the command lines. I always get caught by that.)

gh57.at