开发者

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

开发者 https://www.devze.com 2022-12-24 08:34 出处:网络
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开发者_JAVA百科 static library that would be some sort of SDK to d

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开发者_JAVA百科 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


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))


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.)


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.


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)

0

精彩评论

暂无评论...
验证码 换一张
取 消