# binaries.mk # $Id: binaries.mk,v 1.6 1999/08/26 20:43:28 russo Exp $ # # This scrap is used to link binaries (with C++ main programs). # Set BINARIES to a list of the binaries to be built. # This will generate rules to build and install them in BINARY_DIR. # If BINARY_DIR is undefined, it defaults to bindir. # Unlike the default rules in SRT, this will do the build with # separate compile and link steps, and get the dependencies right. # # All binaries are assumed to depend on LOADLIBES. # Other dependencies can be specified explicitly. # All binaries also link with BINARY_SYSLIBES, but no dependencies # are made on these libraries. # # So, to build a binary foo.x from foo.cc which uses bar.o, libfee.a, # and the fortran libraries, one could do something like: # # BINARIES := foo.x # bin : $(bindir)foo.x # $(bindir)foo.x : foo.o $(libdir)bar.o -lfee # # include SoftRelTools/arch_spec_f77.mk # include SoftRelTools/standard.mk # include SoftRelTools/binaries.mk # # Note: If this is used with d0om_linkage.mk, this scrap should come first. # # scott snyder, jan 1999; adapted from d0_util. # ############################################################################### # # Option overrides. # # # We don't want to use --one_per when compiling objects which don't # go into a library. # ifneq (,$(findstring -KCC,$(BFARCH))) BINARIES_CXXFLAGS = $(filter-out --one_per,$(CXXFLAGS)) else BINARIES_CXXFLAGS = $(CXXFLAGS) endif ############################################################################### # # Where should the binaries go? # By default, in $(bindir). # ifndef BINARY_DIR BINARY_DIR := $(bindir) endif ############################################################################### # # Sort out the binaries based on extension. # BINARIES_X := $(filter %.x,$(BINARIES)) BINARIES_EXE := $(filter %.exe,$(BINARIES)) BINARIES_NOEXT := $(filter-out $(BINARIES_X) $(BINARIES_EXE),$(BINARIES)) ############################################################################### # # Handle LOADLIBES and library dependencies. # # Expand LOADLIBES to LOADLIBES_DEP. include SoftRelTools/binaries_expand_loadlibes.mk # # It's bad to have binaries depend directly on LOADLIBES. Why? # - Make will resolve -l style names. For example, if we depend # on LOADLIBES and LOADLIBES contains `-lm', then what we'll see # in the dependency list is something like `/usr/lib/libm.a'. # However, that's often wrong -- the compilers usually have their # own idea on where to find system libraries like that. So one would # have to fold those names back to -lX. # - Ordering. If the binaries rule below depended on LOADLIBES, # then the dependency list would have LOADLIBES _before_ # any other libraries which a particular binary depends on. # This is exactly the opposite of what we want to happen. # # Thus, it seems to be much easier to make the actual dependence through # a time-stamp file, and not let the contents of LOADLIBES get into the # dependency list for the link. We can then add LOADLIBES explicitly # to the command. # STAMPLIBES := $(workdir)stamp-libes-$(notdir $(shell pwd)) $(STAMPLIBES) : $(LOADLIBES_DEP) touch $(STAMPLIBES) # # In spite of what i said above, we also want to massage the libraries # on which a library depends to transform any system libraries from # PATH/libX.a to -lX. Otherwise, the user has to separate out any # system libraries and put them in LOADLIBES, which is a pain if they're # included in something like D0OM_DS_LIBES. # # We go ahead and do this translation for all libraries which are on a # path in LDFLAGS, not just `system' libraries. This should shorten # up the link command line. # # One further problem. The `-l' expansion in make only looks for # `.a' files, and only in a couple system directories. But sometimes, # there isn't such a system library to be found. For example, SGI # seems to supply only a shared version of -lftn. To make those work # transparently to the user, we can set up a dummy directory containing # files like `libftn.a' and get make to seach it for libraries. # Then we have to transform those back to `-lftn', of course. # The list of such dummy directories is in BINARIES_DUMMY_PATHS. # BINARIES_DUMMY_PATHS := $(addsuffix /SoftRelTools/binaries_dummylibs,\ $(patsubst -I%,%,$(filter -I%,$(CPPFLAGS)))) vpath %.a $(BINARIES_DUMMY_PATHS) BINARIES_LIB_PATHS := $(patsubst -L%,%,$(filter -L%,$(LDFLAGS))) \ /lib /usr/lib \ $(BINARIES_DUMMY_PATHS) # Do the transformation on `l'. binaries_transform_lib = $(firstword \ $(filter -l%,\ $(foreach libpath,$(BINARIES_LIB_PATHS), \ $(patsubst $(libpath)/lib%.a,-l%, \ $(patsubst $(libpath)/lib%.so,-l%,$(l))))) \ $(l)) ############################################################################### # # Do the actual link. # # # The dependency list gets massaged as follows: # - First all .o files, with duplicates removed. # - Then all non .o files, in the original order # (preserving duplicates, if any). We also need to filter out stamp-libes. # # # Here are the actions for linking. # ifneq (,$(findstring NT,$(BFARCH))) BINARIES_CHMOD = chmod +x $@ # Doesn't get set otherwise... else BINARIES_CHMOD := endif define BINARIES_DOLINK @echo "<--building--> $(@F)" $(CXX) $(BINARIES_CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ \ $(filter %.o,$^) \ $(foreach l,$(filter-out $(workdir)stamp-libes% %.o,$+),\ $(binaries_transform_lib)) \ $(LOADLIBES) $(BINARY_SYSLIBES) $(BINARIES_CHMOD) endef # # And now the rules for the various extensions. # $(foreach b,$(BINARIES_NOEXT),$(BINARY_DIR)$(b)): \ $(BINARY_DIR)%: $(workdir)%.o $(STAMPLIBES) $(BINARIES_DOLINK) $(foreach b,$(BINARIES_X),$(BINARY_DIR)$(b)): \ $(BINARY_DIR)%.x: $(workdir)%.o $(STAMPLIBES) $(BINARIES_DOLINK) $(foreach b,$(BINARIES_EXE),$(BINARY_DIR)$(b)): \ $(BINARY_DIR)%.exe: $(workdir)%.o $(STAMPLIBES) $(BINARIES_DOLINK) ############################################################################### # # Rules for compiling to workdir. # $(workdir)%.o : %.cc $(workdir)%.d @echo "<--compiling--> $( $( $( $(@F)"; { $(CPP) $(CPPMFLAGS) $(CPPFLAGS) $(CXXCFLAGS) $< || { rm $@; exit 1 ;} ;} | sed 's?$(*F)\.o?$(workdir)$(*F).o $@ ?g' > $@ ; fi if test -f $@ ; then if test ! -s $@ ; then echo "Warning: removing empty file $@"; rm $@; fi; fi endef BINARIES_CPP := $(wildcard $(addsuffix .cpp,$(BINARIES_STEMS))) ifneq (,$(BINARIES_CPP)) $(foreach b,$(basename $(BINARIES_CPP)),$(workdir)$(b).d) : $(workdir)%.d : %.cpp $(BINARIES_MAKEDFILES) endif BINARIES_CC := $(wildcard $(addsuffix .cc,$(BINARIES_STEMS))) ifneq (,$(BINARIES_CC)) $(foreach b,$(basename $(BINARIES_CC)),$(workdir)$(b).d) : $(workdir)%.d : %.cc $(BINARIES_MAKEDFILES) endif BINARIES_CXX := $(wildcard $(addsuffix .cxx,$(BINARIES_STEMS))) ifneq (,$(BINARIES_CXX)) $(foreach b,$(basename $(BINARIES_CXX)),$(workdir)$(b).d) : $(workdir)%.d : %.cxx $(BINARIES_MAKEDFILES) endif