summaryrefslogtreecommitdiff
path: root/buildlib/defaults.mak
blob: 5b970876a35d0b7f67c7a73c76281f3a6de2c603 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# -*- make -*-

# This file configures the default environment for the make system
# The way it works is fairly simple, each module is defined in it's
# own *.mak file. It expects a set of variables to be set to values
# for it to operate as expected. When included the module generates
# the requested rules based on the contents of its control variables.

# This works out very well and allows a good degree of flexibility.
# To accommodate some of the features we introduce the concept of 
# local variables. To do this we use the 'Computed Names' feature of
# gmake. Each module declares a LOCAL scope and access it with,
#   $($(LOCAL)-VAR)
# This works very well but it is important to remember that within
# a rule the LOCAL var is unavailable, it will have to be constructed
# from the information in the rule invocation. For stock rules like 
# clean this is simple, we use a local clean rule called clean/$(LOCAL)
# and then within the rule $(@F) gets back $(LOCAL)! Other rules will
# have to use some other mechanism (filter perhaps?) The reason such
# lengths are used is so that each directory can contain several 'instances'
# of any given module. I notice that the very latest gmake has the concept
# of local variables for rules. It is possible this feature in conjunction
# with the generated names will provide a very powerful solution indeed!

# A build directory is used by default, all generated items get put into
# there. However unlike automake this is not done with a VPATH build
# (vpath builds break the distinction between #include "" and #include <>)
# but by explicitly setting the BUILD variable. Make is invoked from
# within the source itself which is much more compatible with compilation
# environments.
ifndef NOISY
.SILENT:
endif

# Search for the build directory
ifdef BUILD
BUILD_POSSIBLE := $(BUILD) $(BASE)/$(BUILD)
else
BUILD_POSSIBLE := $(BASE) $(BASE)/build-$(shell uname -m) $(BASE)/build
endif

BUILDX:= $(foreach i,$(BUILD_POSSIBLE),$(wildcard $(i)/environment.mak*))

ifeq ($(words $(BUILDX)),0)

# Check for a busted wildcard function. We use this function in several 
# places, it must work.
ifeq ($(words $(wildcard *)),0)
error-all/environment.mak:
	echo You have a broken version of GNU Make - upgrade.
	error-out-and-die
else
error-all/environment.mak:
	echo Can not find the build directory in $(BUILD_POSSIBLE) -- use BUILD=
	error-out-and-die
endif

# Force include below to come to the error target
BUILDX := error-all
else
BUILDX:= $(patsubst %/,%,$(firstword $(dir $(BUILDX))))
endif

override BUILD := $(BUILDX)

# Base definitions
INCLUDE := $(BUILD)/include
BIN := $(BUILD)/bin
LIB := $(BIN)
OBJ := $(BUILD)/obj/$(SUBDIR)
DEP := $(OBJ)
DOC := $(BUILD)/docs
PO := $(BUILD)/po
LOCALE := $(BUILD)/locale
PO_DOMAINS := $(BUILD)/po/domains

# Module types
LIBRARY_H = $(BASE)/buildlib/library.mak
DEBIANDOC_H = $(BASE)/buildlib/debiandoc.mak
MANPAGE_H = $(BASE)/buildlib/manpage.mak
PROGRAM_H = $(BASE)/buildlib/program.mak
PYTHON_H = $(BASE)/buildlib/python.mak
COPY_H = $(BASE)/buildlib/copy.mak
PO4A_MANPAGE_H = $(BASE)/buildlib/po4a_manpage.mak
FAIL_H = $(BASE)/buildlib/fail.mak
PODOMAIN_H = $(BASE)/buildlib/podomain.mak

include $(BUILD)/environment.mak

ifdef STATICLIBS
LIBRARY_H += $(BASE)/buildlib/staticlibrary.mak
endif

ifdef ONLYSTATICLIBS
LIBRARY_H = $(BASE)/buildlib/staticlibrary.mak
endif

# Source location control
# SUBDIRS specifies sub components of the module that
# may be located in subdirectories of the source dir. 
# This should be declared before including this file
SUBDIRS+=

# Header file control. 
# TARGETDIRS indicates all of the locations that public headers 
# will be published to.
# This should be declared before including this file
HEADER_TARGETDIRS+=

# Options
CPPFLAGS+= -I$(INCLUDE)
LDFLAGS+= -L$(LIB)

# Directors to create
MKDIRS := $(BIN) 

# Phony rules. Other things hook these by appending to the dependency
# list
.PHONY: headers library clean veryclean all binary program doc dirs
.PHONY: maintainer-clean dist-clean distclean pristine sanity
all: dirs binary doc
binary: library program
maintainer-clean dist-clean distclean pristine sanity: veryclean
startup headers library clean veryclean program test update-po manpages debiandoc:

veryclean:
	echo Very Clean done for $(SUBDIR)
clean:
	echo Clean done for $(SUBDIR)
dirs:
	mkdir -p $(patsubst %/,%,$(sort $(MKDIRS)))

# Header file control. We want all published interface headers to go
# into the build directory from their source dirs. We setup some
# search paths here
vpath %.h $(SUBDIRS)
$(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) : %.h
	cp $< $@

# Dependency generation. We want to generate a .d file using gnu cpp.
# For GNU systems the compiler can spit out a .d file while it is compiling,
# this is specified with the INLINEDEPFLAG. Other systems might have a 
# makedep program that can be called after compiling, that's illustrated
# by the DEPFLAG case.
# Compile rules are expected to call this macro after calling the compiler
ifdef GCC3DEP
DFILE = $(DEP)/$(basename $(@F)).d
else
DFILE = $(basename $(@F)).d
endif
ifdef INLINEDEPFLAG
 define DoDep
	sed -e "1s/.*:/$(subst /,\\/,$@):/" $(DFILE) > $(DEP)/$(@F).d
	#sed -e "1s/.*:/$(subst /,\\/,$@):/" $(DEP)/$(basename $(@F)).d > $(DEP)/$(@F).d
	-rm -f $(basename $(@F)).d
 endef
else
 ifdef DEPFLAG
  define DoDep
	$(CXX) $(DEPFLAG) $(CPPFLAGS) -o $@ $<
	sed -e "1s/.*:/$(subst /,\\/,$@):/" $(basename $(@F)).d > $(DEP)/$(@F).d
	-rm -f $(basename $(@F)).d
  endef
 else
  define DoDep
  endef
 endif
endif	

# Automatic -j support
ifeq ($(NUM_PROCS),1)
  PARALLEL_RUN=no
endif

# mvo: commented out, lead to build failures in the arch-build target
#ifndef PARALLEL_RUN
# PARALLEL_RUN=yes
# .EXPORT: PARALLEL_RUN
# # handle recursion
# ifneq ($(NUM_PROCS),)
#  MAKEFLAGS += -j $(NUM_PROCS)
# endif
#endif