What is the best approach to using different CFLAGS for the same source files?

I need to build the same source tree twice,

1 - with normal flags for creating a binary project 2 - with cflags plus -fPIC for creating a static library, which will be a kind of SDK for developing dynamic project modules.

Using only one Makefile, what's the best approach for this?

It would be nice to do something like:

all: $(OBJECTS) lib_rule: $(OBJECTS) CFLAGS += -fPIC .cpp.o: $(CC) -c $< -o $@ $(CFLAGS) 

But obviously this is not possible.

thanks

+7
makefile
source share
4 answers

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

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

Then you create your static library from .lo files, and you create binary files from .o files:

 prog: ao bo libsdk.a: a.lo b.lo 

Assuming you are using GNU Make, you can use some of the built-in functions only to maintain a list of objects once:

 OBJS = ao bo LOBJS = $(patsubst %.o, %.lo, $(OBJS)) 
+12
source share

GNU also offers the suggestion "Object-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. 

$ do it all CFLAGS: My Cflags
$ make lib_rule
lib_rule CFLAGS: my Cflags extended -fPIC
$
(Note: if you copy and paste the example, be sure to re-add the tabs before the command line. I will always catch that.)

+7
source share

Instead of placing the compiled .o files in the same directory as the source, I create them in the marked subdirectories. In your case, you can create static library files as source_dir/lib/*.o and your regular files as source_dir/bin/*.o For your various construction purposes, after setting up a unique CFLAGS simply create a DIR_NAME value containing the name of the corresponding subfolder. You can use this variable when creating paths for the compiler, which will be used when creating and linking.

+2
source share

In another make tool like CMake, you can express something like this a lot easier.

For example, you could do

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

Or you can repeatedly create the same directory with different flags by entering it several times from the logical parent directory, i.e.

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

... and then use if() or something else in the child directory to set the correct flags.

In particular, if you have many such configurations, using make becomes pretty fragile; make will incorrectly find the transitive closure of recursive make-dependencies (and, of course, it will incorrectly find a dependency on the makefile itself - if you change the flags, say), so if you are going to make a complex makefile mask: do it with the best tool!

(CMake just happens to replace make, but various other replacements are possible)

0
source share

All Articles