# Generic configuration for Hurd compilation # Directory makefiles should set the variable makemode to either # `server' if they compile and install a single program for /hurd # `utility' if they compile and install a single program for /bin # `servers' if they compile and install multiple programs for /hurd # `utilities' if they compile and install multiple programs for /bin # `library' if they compile and install a library # `misc' if they do none of those # Every makefile should define # SRCS (all actual source code) # LCLHDRS (all source headers in this directory [NOT MiG created]) # OBJS (all .o files used to produce some target). # HURDLIBS (all Hurd libraries used; with no directory name or `lib' attached) # For types `server' and `utility' an automatic dependency will be # written for these, and type `library' will include a .so dependency. # Types `servers' and `utilities'; you have to do it yourself. # Types `server' and `utility' should define # target (the name of the program built) # OTHERLIBS (all libraries used) # Types `servers' and `utilities' should define # targets (the names of all the programs built) # special-targets (targets which should not be built the normal way # and have their own rules) # Type `library' should define # libname (the name of the library, without .a.) # installhdrs (header files that should be installed in /include) # installhdrsubdir (the subdirectory they should go in, default `hurd') # and must not define $(targets). # Put this first so it's the default all: # What version of the Hurd is this? hurd-version := 0.3 # Figure out how to locate the parent directory from here. ifeq (.,$(dir)) .. = else .. = ../ endif ifndef srcdir # We are building in the source directory itself. srcdir = . ifeq (.,$(dir)) top_srcdir = . else top_srcdir = .. endif endif # Generic compiler options, appended to whatever the particular makefile set. # The config.make file will append the values chosed by configure. INCLUDES = -I. $(srcdirinc) ifneq (.,$(dir)) INCLUDES += -I.. $(top_srcdirinc) endif INCLUDES += -I$(..)include -I$(top_srcdir)/include CPPFLAGS += $(INCLUDES) \ -D_GNU_SOURCE -D_IO_MTSAFE_IO -D_FILE_OFFSET_BITS=64 \ $($*-CPPFLAGS) CFLAGS += -std=gnu99 -Wall -g -O3 \ $($*-CFLAGS) # Include the configure-generated file of parameters. # This sets up variables for build tools and installation directories. ifneq (,$(wildcard $(..)config.make)) include $(..)config.make # Set a flag for the makefiles to indicated config.make was included. configured = yes endif # If we're not configured, don't do deps; then `make TAGS' and such can work. ifndef configured no_deps = t endif # Test build options set by configure. ifeq (no,$(build-profiled)) no_prof = t endif # Flags for compilation. # It is important to have this inclusion first; that picks up our # library header files locally rather than from installed copies. # Append to any value set by the specific Makefile or by configure. ifeq ($(srcdir),.) srcdirinc= else srcdirinc=-I$(srcdir) endif ifeq ($(top_srcdir),..) top_srcdirinc= else top_srcdirinc=-I$(top_srcdir) endif # More useful version of HURDLIBS library_deps=$(foreach lib,$(HURDLIBS),$(..)lib$(lib)/lib$(lib).so) # Local programs: MKINSTALLDIRS = $(top_srcdir)/mkinstalldirs # Decode makemode. # After this section, $(targets) and $(progtarg) will be defined, # and everything else should use only those and not $(target). # targets will have all the (one or more) targets that should be installed; # progtarg will have all the (one or more) programs that should be linked; # linktarg will have the complete set of linked targets, including both # .static versions of $(progtarg) and/or shared library object targets. ifeq ($(makemode),server) doinst := one makemode-instdir := hurd clean := yes targets = $(target) progtarg = $(targets) endif ifeq ($(makemode),utility) doinst := one makemode-instdir := bin clean := yes targets = $(target) endif ifeq ($(makemode),servers) doinst := many makemode-instdir := hurd clean := yes progtarg := $(targets) endif ifeq ($(makemode),utilities) doinst := many makemode-instdir := bin clean := yes progtarg := $(targets) endif ifeq ($(makemode),library) linktarg := $(libname).so.$(hurd-version) clean := yes cleantarg := $(linktarg) $(addprefix $(libname),.a _p.a _pic.a \ .so .so.$(hurd-version)) targets := $(libname).a $(libname).so ifneq ($(no_pic),t) targets += $(libname)_pic.a endif ifneq ($(no_prof),t) targets += $(libname)_p.a endif ifndef installhdrsubdir installhdrsubdir = hurd endif else ifeq ($(makemode),misc) ifndef doinst doinst := many endif ifeq ($(doinst),one) targets = $(target) endif ifeq (,$(installationdir)) ifneq (,$(targets)) ?Error subdir Makefile must define installationdir else makemode-instdir := NOINSTALL endif endif else # server/utility modes progtarg := $(filter-out $(special-targets),$(targets)) linktarg := $(progtarg) $(progtarg:=.static) endif endif ifndef installationdir installationdir := $($(makemode-instdir)dir) endif ifeq ($(cleantarg),) cleantarg := $(linktarg) endif # This is a hack to give all hurd utilities a default bug-reporting # address (defined in libhurdbugaddr/bugaddr.c). BUGADDR = $(..)libhurdbugaddr/libhurdbugaddr.a BUGADDR_REF = -uargp_program_bug_address # Standard targets .PHONY: all install libs relink clean objs # Just build all the object files. objs: $(OBJS) ifneq ($(no_prof),t) objs: $(OBJS:%.o=%_p.o) endif ifeq ($(makemode),library) ifneq ($(no_pic),t) objs: $(OBJS:%.o=%_pic.o) endif endif # Installation ifneq ($(makemode),library) # not library installable := $(sort $(linktarg) $(targets)) install-targets := $(targets) $(filter $(build-static:=.static),$(linktarg)) all: $(install-targets) install: $(installationdir) $(addprefix $(installationdir)/,$(install-targets)) $(addprefix $(installationdir)/,$(installable)): $(installationdir)/%: % $(INSTALL_PROGRAM) $(INSTALL-$<-ops) $< $@ else # library (several parts, library itself, headers, etc.) all: libs install libs: add-to-librecord add-to-librecord: $(targets) install: $(libdir) $(includedir)/$(installhdrsubdir) $(libdir)/$(libname).so.$(hurd-version) $(addprefix $(libdir)/,$(targets)) $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) install-headers: $(includedir)/$(installhdrsubdir) $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) $(includedir)/$(installhdrsubdir): $(includedir) @$(MKINSTALLDIRS) $@ # Arrange to have the headers installed locally anytime we build the library. # Not quite perfect, but at least it does end up getting done; and once done # it never needs to be repeated for a particular header. ifeq ($(installhdrsubdir),.) local-installhdrsubdir = include else local-installhdrsubdir = $(installhdrsubdir) endif ifneq ($(local-installhdrsubdir),$(dir)) INSTALLED_LOCAL_HEADERS := $(installhdrs:%=../$(local-installhdrsubdir)/%) $(INSTALLED_LOCAL_HEADERS): ../$(local-installhdrsubdir)/%: ../config.make @rm -f $@ echo '#include "../$(dir)/$*"' > $@ endif libs: $(INSTALLED_LOCAL_HEADERS) # Make sure we make those before compiling, since -MG will be unhelpful. $(patsubst %.o,%.d,$(filter %.o,$(OBJS))): $(INSTALLED_LOCAL_HEADERS) # The installed local headers referring to our own files will use # relative names with ../$(dir) and make won't notice that's us. ../$(dir)/%: % ; $(addprefix $(libdir)/$(libname),_p.a .a _pic.a): $(libdir)/%: % $(INSTALL_DATA) $< $@ $(RANLIB) $@ $(libdir)/$(libname).so.$(hurd-version): $(libname).so.$(hurd-version) $(INSTALL_DATA) $< $@ $(libdir)/$(libname).so: $(libdir)/$(libname).so.$(hurd-version) ln -f -s $( $@ # Making a snapshot distfiles = Makefile ChangeLog $(SRCS) $(LCLHDRS) $(DIST_FILES) lndist: $(distfiles) $(top_srcdir)/hurd-snap/$(dir) FORCE ln $(addprefix $(srcdir)/,$(distfiles)) $(top_srcdir)/hurd-snap/$(dir) ifeq ($(dir),.) $(top_srcdir)/hurd-snap/$(dir): else $(top_srcdir)/hurd-snap/$(dir): mkdir $@ endif # TAGS files ifneq ($(dir),.) ifdef configured ifneq ($(OBJS:.o=.d),) DEP_SRCS = sed -e 's/^.*://' -e 's/ \\$$//' | tr ' ' '\012'| \ sed -n -e 's@^$(srcdir)@&@p' -e 's@^[^/]@&@p' | sort -ur TAGSFILES=$(OBJS:.o=.d) $(OTHERTAGS) else TAGSFILES=$(OTHERTAGS) endif else TAGSFILES=$(SRCS) $(OTHERTAGS) endif TAGS: $(TAGSFILES) ifeq ($(strip ($(TAGSFILES))),) # no tags, but parent will include this file, so make empty one. > $@ else ifdef DEP_SRCS cat $(OBJS:.o=.d) | $(DEP_SRCS) | etags -o $@ - $(OTHERTAGS) else etags -o $@ $^ endif endif endif # Cleaning ifeq ($(clean),yes) clean: rm -f *.d *.o *Server.c *User.c *_S.h *_U.h *.[su]defsi \ $(cleantarg) relink: rm -f $(linktarg) endif clean: relink: # Subdependencies # We record which libraries have been built in this run in the file # $(librecord). That file contains a series of lines like # `../libfoo/libfoo.a ../libfoo/libfoo.so: ; /bin/true' # that serve to inhibit the pattern rule which follows from doing anything. # Above, when we make `libs' in library directories, we always append # to $(librecord), so that future make invocations don't bother repeating # the effort. # if this is the first level, then set librecord. Otherwise, read it in. #ifeq ($(MAKELEVEL),0) #librecord:=/tmp/hurd-make-$(shell echo $$$$) #export librecord #else #include $(librecord) #endif # How to create it. #$(librecord): # touch $(librecord) # `libs' target depends on this. #add-to-librecord: # echo $(addprefix ../$(dir)/,$(targets)) : \; /bin/true >> $(librecord) # Building libraries from other directories. We force both libraries to be # built if either is, because it will use the appropriate one even if the other # is specified in someone's dependency list. #../%.a ../%.so: FORCE # $(MAKE) -C $(dir $@) libs # Tell make where to find other -l libraries that we use vpath libutil.% $(libdir)/ ifneq ($(dir),libstore) $(boot-store-types:%=../libstore/libstore_%.a): ../libstore/libstore.so endif # Default rules to build PIC object files. %_pic.o: %.c $(COMPILE.c) $< -DPIC -fPIC -o $@ %_pic.o: %.S $(COMPILE.S) $< -DPIC -o $@ # Default rules to build profiled object files. %_p.o: %.c $(COMPILE.c) $< -DPROF -pg -o $@ %_p.o: %.S $(COMPILE.S) $< -DPROF -o $@ # How to build RPC stubs # We always need this setting, because libc does not include the bogus names. MIGCOMFLAGS := -subrprefix __ # User settable variables: # mig-sheader-prefix prepend to foo_S.h for name of foo.defs stub header # MIGSFLAGS flags to CPP when building server stubs and headers # foo-MIGSFLAGS same, but only for interface `foo' # MIGCOMSFLAGS flags to MiG when building server stubs and headers # foo-MIGCOMSFLAGS same, but only for interface `foo' # MIGUFLAGS flags to CPP when building user stubs and headers # foo-MIGUFLAGS same, but only for interface `foo' # MIGCOMUFLAGS flags to MiG when building user stubs and headers # foo-MIGCOMUFLAGS same, but only for interface `foo' # CPPFLAGS flags to CPP # Implicit rules for building server and user stubs from mig .defs files. # These chained rules could be (and used to be) single rules using pipes. # But it's convenient to be able to explicitly make the intermediate # files when you want to deal with a problem in the MiG stub generator. %.sdefsi %.sdefs.d: %.defs $(CPP) $(CPPFLAGS) $(MIGSFLAGS) $($*-MIGSFLAGS) -DSERVERPREFIX=S_ \ -MD -MF $*.sdefs.d.new \ $< -o $*.sdefsi sed -e 's/[^:]*:/$*Server.c $(mig-sheader-prefix)$*_S.h:/' \ < $*.sdefs.d.new > $*.sdefs.d rm $*.sdefs.d.new $(mig-sheader-prefix)%_S.h %Server.c: %.sdefsi $(MIGCOM) $(MIGCOMFLAGS) $(MIGCOMSFLAGS) $($*-MIGCOMSFLAGS) \ -sheader $(mig-sheader-prefix)$*_S.h -server $*Server.c \ -user /dev/null -header /dev/null < $< %.udefsi %.udefs.d: %.defs $(CPP) $(CPPFLAGS) $(MIGUFLAGS) $($*-MIGUFLAGS) \ -MD -MF $*.udefs.d.new \ $< -o $*.udefsi sed -e 's/[^:]*:/$*User.c $*_U.h:/' \ < $*.udefs.d.new > $*.udefs.d rm $*.udefs.d.new %_U.h %User.c: %.udefsi $(MIGCOM) $(MIGCOMFLAGS) $(MIGCOMUFLAGS) $($*-MIGCOMUFLAGS) < $< \ -user $*User.c -server /dev/null -header $*_U.h # Where to find .defs files. vpath %.defs $(top_srcdir)/hurd # These we want to find in the libc include directory... mach_defs_names = bootstrap exc mach mach4 \ mach_host mach_port mach_timer_reply memory_object \ memory_object_default notify device_defs_names = dev_forward device device_reply device_request mach_defs = $(addsuffix .defs,$(mach_defs_names)) device_defs = $(addsuffix .defs,$(device_defs_names)) $(mach_defs): %.defs: echo '#include ' > $@ $(device_defs): %.defs: echo '#include ' > $@ FORCE: # How to build automatic dependencies # Don't include dependencies if $(no_deps) is set; the master makefile # does this for clean and other such targets that don't need # dependencies. That then avoids rebuilding dependencies. ifneq ($(no_deps),t) # The MIG stubs depend on their definition files. # These lines assume that every Makefile that uses a foo_S.h or foo_U.h file # also mentions the associated fooServer.o or fooUser.o file. -include $(subst Server.o,.sdefs.d,$(filter %Server.o,$(OBJS))) /dev/null -include $(subst User.o,.udefs.d,$(filter %User.o,$(OBJS))) /dev/null ifneq ($(prof-depend),t) ifneq ($(no_prof),t) -include $(addsuffix .prof_d,$(progtarg)) /dev/null endif endif # For each .o file we need a .d file. -include $(subst .o,.d,$(filter %.o,$(OBJS))) /dev/null endif # Here is how to build those dependency files %.prof_d: $(srcdir)/Makefile $(MAKE) $* prof-depend=t ifeq ($(prof-depend),t) $(progtarg): %: FORCE rm -f $@.prof_d echo $@.prof: $(subst .so,_p.a,$(subst .o,_p.o,$(filter-out FORCE,$+))) > $@.prof_d endif define make-deps set -e; $(CC) $(CFLAGS) $(CPPFLAGS) -M -MG $< | \ sed > $@.new -e 's/$*\.o:/$*.o $*_pic.o $*_p.o $@:/' \ -e 's% [^ ]*/gcc-lib/[^ ]*\.h%%g' mv -f $@.new $@ endef # Here is how to make .d files from .c files %.d: %.c; $(make-deps) # Here is how to make .d files from .S files %.d: %.S; $(make-deps) # .s files don't go through the preprocessor, so we do this # This rule must come *after* the genuine ones above, so that # make doesn't build a .s file and then make an empty dependency # list. %.d: %.s echo '$*.o: $<' > $@ # Rule to make executable shell scripts from .sh files. %: %.sh $(top_srcdir)/sh-version.sed sed -e 's/STANDARD_HURD_VERSION_\\(.[^_]*\\)_/\\1 (GNU Hurd) $(hurd-version)/' < $< > $@ chmod +x $@