1ifdef _WLAN_COMMON_MK
2$(if $D,$(info Info: Avoiding redundant include ($(MAKEFILE_LIST))))
3else	# _WLAN_COMMON_MK
4_WLAN_COMMON_MK := 1
5unexport _WLAN_COMMON_MK	# in case of make -e
6
7################################################################
8# Summary and Namespace Rules
9################################################################
10#   This is a special makefile fragment intended for common use.
11# The most important design principle is that it be used only to
12# define variables and functions in a tightly controlled namespace.
13# If a make include file is used to set rules, pattern rules,
14# or well known variables like CFLAGS, it can have unexpected
15# effects on the including makefile, with the result that people
16# either stop including it or stop changing it.
17# Therefore, the only way to keep this a file which can be
18# safely included by any GNU makefile and extended at will is
19# to allow it only to set variables and only in its own namespace.
20#   The namespace is "WLAN_CamelCase" for normal variables,
21# "wlan_lowercase" for functions, and WLAN_UPPERCASE for boolean
22# "constants" (these are all really just make variables; only the
23# usage patterns differ).
24#   Internal (logically file-scoped) variables are prefixed with "-"
25# and have no other namespace restrictions.
26#   Every variable defined here should match one of these patterns.
27
28################################################################
29# Enforce required conditions
30################################################################
31
32ifneq (,$(filter 3.7% 3.80,$(MAKE_VERSION)))
33$(error $(MAKE): Error: version $(MAKE_VERSION) too old, 3.81+ required)
34endif
35
36################################################################
37# Derive including makefile since it's a little tricky.
38################################################################
39
40WLAN_Makefile := $(abspath $(lastword $(filter-out $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
41
42################################################################
43# Shiny new ideas, can be enabled via environment for testing.
44################################################################
45
46ifdef WLAN_MakeBeta
47$(info Info: BUILDING WITH "WLAN_MakeBeta" ENABLED!)
48SHELL := /bin/bash
49#export SHELLOPTS ?= pipefail
50#.SUFFIXES:
51#MAKEFLAGS += -r
52endif
53
54################################################################
55# Allow a makefile to force this file into all child makes.
56################################################################
57
58ifdef WLAN_StickyCommon
59export MAKEFILES := $(MAKEFILES) $(abspath $(lastword $(MAKEFILE_LIST)))
60endif
61
62################################################################
63# Host type determination
64################################################################
65
66_common-uname-s := $(shell uname -s)
67
68# Typically this will not be tested explicitly; it's the default condition.
69WLAN_HOST_TYPE := unix
70
71ifneq (,$(filter Linux,$(_common-uname-s)))
72  WLAN_LINUX_HOST := 1
73else ifneq (,$(filter CYGWIN%,$(_common-uname-s)))
74  WLAN_CYGWIN_HOST := 1
75  WLAN_WINDOWS_HOST := 1
76else ifneq (,$(filter Darwin,$(_common-uname-s)))
77  WLAN_MACOS_HOST := 1
78  WLAN_BSD_HOST := 1
79else ifneq (,$(filter FreeBSD NetBSD,$(_common-uname-s)))
80  WLAN_BSD_HOST := 1
81else ifneq (,$(filter SunOS%,$(_common-uname-s)))
82  WLAN_SOLARIS_HOST := 1
83endif
84
85################################################################
86# Utility variables
87################################################################
88
89empty :=
90space := $(empty) $(empty)
91comma := ,
92
93################################################################
94# Utility functions
95################################################################
96
97# Provides enhanced-format messages from make logic.
98wlan_die = $(error Error: $1)
99wlan_warning = $(warning Warning: $1)
100wlan_info = $(info Info: $1)
101
102# Debug function to enable make verbosity.
103wlan_dbg = $(if $D,$(call wlan_info,$1))
104
105# Debug function to expose values of the listed variables.
106wlan_dbgv = $(foreach _,$1,$(call wlan_dbg,$_=$($_)))
107
108# Make-time assertion.
109define wlan_assert
110ifeq (,$(findstring clean,$(MAKECMDGOALS)))
111$(if $1,,$(call wlan_die,$2))
112endif
113endef
114
115# Checks for the presence of an option in an option string
116# like "aaa-bbb-ccc-ddd".
117wlan_opt = $(if $(findstring -$1-,-$2-),1,0)
118
119# Compares two dotted numeric strings (e.g 2.3.16.1) for $1 >= $2
120define wlan_version_ge
121$(findstring TRUE,$(shell bash -c 'sort -cu -t. -k1,1nr -k2,2nr -k3,3nr -k4,4nr <(echo -e "$2\n$1") 2>&1 || echo TRUE'))
122endef
123
124# This is a useful macro to wrap around a compiler command line,
125# e.g. "$(call wlan_cc,<command-line>). It organizes flags in a
126# readable way while taking care not to change any ordering
127# which matters. It also provides a hook for externally
128# imposed C flags which can be passed in from the top level.
129# This would be the best place to add a check for
130# command line length. Requires a $(strlen) function;
131# GMSL has one.
132define wlan_cc
133$(filter-out -D% -I%,$1) $(filter -D%,$1) $(filter -I%,$1) $(WLAN_EXTERNAL_CFLAGS)
134endef
135
136# Applies the standard cygpath translation for a path on Cygwin.
137define wlan_cygpath
138$(if $(WLAN_CYGWIN_HOST),$(shell cygpath -m $1),$1)
139endef
140
141################################################################
142# Standard make variables
143################################################################
144
145# This points to the root of the build tree, currently known to
146# be 2 levels above the directory of this file.
147ifndef WLAN_TreeBaseA
148ifdef WLAN_CYGWIN_HOST
149WLAN_TreeBaseA := $(shell cygpath -m -a $(dir $(lastword $(MAKEFILE_LIST)))../..)
150else
151WLAN_TreeBaseA := $(subst \,/,$(realpath $(dir $(lastword $(MAKEFILE_LIST)))../..))
152endif
153endif
154
155# We've observed a bug, or at least a surprising behavior, in emake which
156# causes the $(realpath) above to fail so this fallback is used.
157ifndef WLAN_TreeBaseA
158WLAN_TreeBaseA := $(shell cd $(dir $(lastword $(MAKEFILE_LIST)))../.. && pwd)
159endif
160
161# Export these values so they can be used by scripts or nmake/pmake makefiles.
162export WLAN_TreeBaseA
163
164# We may eventually remove this and require an
165# explict absolute-vs-relative choice.
166export WLAN_TreeBase := $(WLAN_TreeBaseA)
167
168# Pick up the "relpath" make function.
169include $(WLAN_TreeBaseA)/src/makefiles/RelPath.mk
170
171# This is a relativized version of $(WLAN_TreeBaseA).
172export WLAN_TreeBaseR = $(call relpath,$(WLAN_TreeBaseA))
173
174# For compatibility, due to the prevalence of $(SRCBASE)
175WLAN_SrcBaseA := $(WLAN_TreeBaseA)/src
176WLAN_SrcBaseR  = $(patsubst %/,%,$(dir $(WLAN_TreeBaseR)))
177
178# Show makefile list before we start including things.
179$(call wlan_dbgv, CURDIR MAKEFILE_LIST)
180
181################################################################
182# Pick up the "universal settings file" containing
183# the list of all available software components.
184################################################################
185
186include $(WLAN_TreeBaseA)/src/tools/release/WLAN.usf
187
188################################################################
189# Calculate paths to requested components.
190################################################################
191
192# This uses pattern matching to pull component paths from
193# their basenames (e.g. src/wl/xyz => xyz).
194# It also strips out component paths which don't currently exist.
195# This may be required due to our "partial-source" build styles
196# and the fact that linux mkdep throws an error when a directory
197# specified with -I doesn't exist.
198define _common-component-names-to-rel-paths
199$(strip \
200  $(patsubst $(WLAN_TreeBaseA)/%,%,$(wildcard $(addprefix $(WLAN_TreeBaseA)/,\
201  $(sort $(foreach name,$(if $1,$1,$(WLAN_COMPONENT_PATHS)),$(filter %/$(name),$(WLAN_COMPONENT_PATHS))))))))
202endef
203
204# If WLAN_ComponentsInUse is unset it defaults to the full set (for now, anyway - TODO).
205# It's also possible to request the full set with a literal '*'.
206ifeq (,$(WLAN_ComponentsInUse))
207  WLAN_ComponentsInUse		:= $(sort $(notdir $(WLAN_COMPONENT_PATHS)))
208  # $(call wlan_die,no SW component request)
209else ifeq (*,$(WLAN_ComponentsInUse))
210  WLAN_ComponentsInUse		:= $(sort $(notdir $(WLAN_COMPONENT_PATHS)))
211  $(call wlan_info,all SW components requested ("$(WLAN_ComponentsInUse)"))
212else
213  WLAN_ComponentsInUse		:= $(sort $(WLAN_ComponentsInUse))
214endif
215WLAN_ComponentPathsInUse	:= $(call _common-component-names-to-rel-paths,$(WLAN_ComponentsInUse))
216
217# Test that all requested components exist.
218ifneq ($(sort $(WLAN_ComponentsInUse)),$(notdir $(WLAN_ComponentPathsInUse)))
219# TODO - turned off until old branches support this infrastructure.
220#  $(call wlan_warning,bogus component request: "$(sort $(WLAN_ComponentsInUse))" != "$(notdir $(WLAN_ComponentPathsInUse))")
221endif
222
223# Loop through all components in use. If an xyz.mk file exists at the base of
224# component xyz's subtree, include it and use its contents to modify the list
225# of include and src dirs. Otherwise, use the defaults for that component.
226# Also generate a WLAN_ComponentBaseDir_xyz variable for each component "xyz".
227WLAN_ComponentIncPathsInUse :=
228WLAN_ComponentSrcPathsInUse :=
229$(foreach _path,$(WLAN_ComponentPathsInUse), \
230  $(if $(wildcard $(WLAN_TreeBaseA)/$(_path)/$(notdir $(_path)).mk),$(eval include $(WLAN_TreeBaseA)/$(_path)/$(notdir $(_path)).mk)) \
231  $(eval $(notdir $(_path))_IncDirs ?= include) \
232  $(eval $(notdir $(_path))_SrcDirs ?= src) \
233  $(eval WLAN_ComponentIncPathsInUse += $(addprefix $(_path)/,$($(notdir $(_path))_IncDirs))) \
234  $(eval WLAN_ComponentSrcPathsInUse += $(addprefix $(_path)/,$($(notdir $(_path))_SrcDirs))) \
235  $(eval WLAN_ComponentBaseDir_$$(notdir $(_path)) := $$(WLAN_TreeBaseA)/$(_path)) \
236)
237
238# Phy specific subdirs
239ifeq ($(findstring phymods,$(WLAN_ComponentsInUse)),phymods)
240PHY_TOP_DIR = src/wl/phymods
241PHY_CMN_DIR_LIST = dbg
242PHY_1OFF_DIR_LIST =
243PHY_TYPE_LIST = cmn
244PHY_MOD_LIST = core radar
245PHY_MOD_SRC_DIRS = $(foreach PHY_CMN_DIR,$(PHY_CMN_DIR_LIST),$(PHY_TOP_DIR)/cmn/$(PHY_CMN_DIR)/src)
246PHY_MOD_SRC_DIRS += $(foreach PHY_1OFF_DIR,$(PHY_1OFF_DIR_LIST),$(PHY_TOP_DIR)/$(PHY_1OFF_DIR)/src)
247PHY_MOD_SRC_DIRS += $(foreach PHY_TYPE,$(PHY_TYPE_LIST),\
248	$(foreach PHY_MOD,$(PHY_MOD_LIST),$(PHY_TOP_DIR)/$(PHY_TYPE)/$(PHY_MOD)/src))
249PHY_MOD_INC_DIRS = $(foreach PHY_CMN_DIR,$(PHY_CMN_DIR_LIST),$(PHY_TOP_DIR)/cmn/$(PHY_CMN_DIR)/include)
250PHY_MOD_INC_DIRS += $(foreach PHY_1OFF_DIR,$(PHY_1OFF_DIR_LIST),$(PHY_TOP_DIR)/$(PHY_1OFF_DIR)/include)
251PHY_MOD_INC_DIRS += $(foreach PHY_TYPE,$(PHY_TYPE_LIST),\
252	$(foreach PHY_MOD,$(PHY_MOD_LIST),$(PHY_TOP_DIR)/$(PHY_TYPE)/$(PHY_MOD)/include))
253PHY_MOD_INC_DIRS += $(foreach PHY_DIR,$(PHY_MOD_SRC_DIRS),$(PHY_DIR))
254else
255PHY_MOD_SRC_DIRS =
256PHY_MOD_INC_DIRS =
257endif
258
259# Global include/source path
260WLAN_StdSrcDirs = src/shared src/wl/sys src/wl/phy src/bcmcrypto
261WLAN_StdSrcDirs += $(PHY_MOD_SRC_DIRS)
262WLAN_StdIncDirs = src/include src/common/include src/common/include/devctrl_if
263WLAN_StdIncDirs += $(PHY_MOD_INC_DIRS)
264
265WLAN_SrcIncDirs = src/shared src/wl/sys src/wl/ndis/include src/wl/phy src/bcmcrypto
266WLAN_SrcIncDirs += src/wl/keymgmt/src src/wl/iocv/src src/wl/ndis/src src/wl/shim/src
267WLAN_SrcIncDirs += $(PHY_MOD_SRC_DIRS)
268
269export WLAN_StdSrcDirsR	 = $(addprefix $(WLAN_TreeBaseR)/,$(WLAN_StdSrcDirs))
270export WLAN_StdIncDirsR	 = $(addprefix $(WLAN_TreeBaseR)/,$(WLAN_StdIncDirs))
271export WLAN_SrcIncDirsR  = $(addprefix $(WLAN_TreeBaseR)/,$(WLAN_SrcIncDirs))
272export WLAN_StdIncPathR	 = $(addprefix -I,$(WLAN_StdIncDirsR))
273export WLAN_IncDirsR	 = $(WLAN_StdIncDirsR) $(WLAN_SrcIncDirsR)
274export WLAN_IncPathR	 = $(addprefix -I,$(WLAN_IncDirsR))
275
276export WLAN_StdSrcDirsA	 = $(addprefix $(WLAN_TreeBaseA)/,$(WLAN_StdSrcDirs))
277export WLAN_StdIncDirsA	 = $(addprefix $(WLAN_TreeBaseA)/,$(WLAN_StdIncDirs))
278export WLAN_SrcIncDirsA	 = $(addprefix $(WLAN_TreeBaseA)/,$(WLAN_SrcIncDirs))
279export WLAN_StdIncPathA	 = $(addprefix -I,$(WLAN_StdIncDirsA))
280export WLAN_IncDirsA	 = $(WLAN_StdIncDirsA) $(WLAN_SrcIncDirsA)
281export WLAN_IncPathA	 = $(addprefix -I,$(WLAN_IncDirsA))
282
283# Public convenience macros based on WLAN_ComponentPathsInUse list.
284export WLAN_ComponentSrcDirsR	 = $(addprefix $(WLAN_TreeBaseR)/,$(WLAN_ComponentSrcPathsInUse))
285export WLAN_ComponentIncDirsR	 = $(addprefix $(WLAN_TreeBaseR)/,$(WLAN_ComponentIncPathsInUse))
286export WLAN_ComponentIncPathR	 = $(addprefix -I,$(WLAN_ComponentIncDirsR))
287
288export WLAN_ComponentSrcDirsA	 = $(addprefix $(WLAN_TreeBaseA)/,$(WLAN_ComponentSrcPathsInUse))
289export WLAN_ComponentIncDirsA	 = $(addprefix $(WLAN_TreeBaseA)/,$(WLAN_ComponentIncPathsInUse))
290export WLAN_ComponentIncPathA	 = $(addprefix -I,$(WLAN_ComponentIncDirsA))
291
292export WLAN_ComponentSrcDirs	 = $(WLAN_ComponentSrcDirsA)
293export WLAN_ComponentIncDirs	 = $(WLAN_ComponentIncDirsA)
294export WLAN_ComponentIncPath	 = $(WLAN_ComponentIncPathA)
295
296# Dump a representative sample of derived variables in debug mode.
297$(call wlan_dbgv, WLAN_TreeBaseA WLAN_TreeBaseR WLAN_SrcBaseA WLAN_SrcBaseR \
298    WLAN_ComponentPathsInUse WLAN_ComponentIncPath WLAN_ComponentIncPathR \
299    WLAN_ComponentSrcDirs WLAN_ComponentSrcDirsR)
300
301# Special case for Windows to reflect CL in the build log if used.
302ifdef WLAN_WINDOWS_HOST
303ifdef CL
304$(info Info: CL=$(CL))
305endif
306endif
307
308# A big hammer for debugging each shell invocation.
309# Warning: this can get lost if a sub-makefile sets SHELL explicitly, and
310# if so the parent should add $WLAN_ShellDebugSHELL to the call.
311ifeq ($D,2)
312WLAN_ShellDebug := 1
313endif
314ifdef WLAN_ShellDebug
315ORIG_SHELL := $(SHELL)
316SHELL = $(strip $(warning Shell: ORIG_SHELL=$(ORIG_SHELL) PATH=$(PATH))$(ORIG_SHELL)) -x
317WLAN_ShellDebugSHELL := SHELL='$$(warning Shell: ORIG_SHELL=$$(ORIG_SHELL) PATH=$$(PATH))$(ORIG_SHELL) -x'
318endif
319
320# Variables of general utility.
321WLAN_Perl := perl
322WLAN_Python := python
323WLAN_WINPFX ?= Z:
324
325# These macros are used to stash an extra copy of generated source files,
326# such that when a source release is made those files can be reconstituted
327# from the stash during builds. Required if the generating tools or inputs
328# are not shipped.
329define wlan_copy_to_gen
330  $(if $(WLAN_COPY_GEN),&& mkdir -p $(subst $(abspath $2),$(abspath $2/$(WLAN_GEN_BASEDIR)),$(dir $(abspath $1))) && \
331    cp -pv $1 $(subst $(abspath $2),$(abspath $2/$(WLAN_GEN_BASEDIR)),$(abspath $1).GEN))
332endef
333
334################################################################
335# CLM function; generates a rule to run ClmCompiler iff the XML exists.
336# USAGE: $(call WLAN_GenClmCompilerRule,target-dir,src-base[,flags[,ext]])
337#   This macro uses GNU make's eval function to generate an
338# explicit rule to generate a particular CLM data file each time
339# it's called. Make variables which should be evaluated during eval
340# processing get one $, those which must defer till "runtime" get $$.
341#   The CLM "base flags" are the default minimal set, the "ext flags"
342# are those which must be present for all release builds.
343# The "clm_compiled" phony target is provided for makefiles which need
344# to defer some other processing until CLM data is ready, and "clm_clean"
345# and "CLM_DATA_FILES" make it easier for internal client makefiles to
346# clean up CLM data (externally, this is treated as source and not removed).
347#   The outermost conditional allows this rule to become a no-op
348# in external settings where there is no XML input file while allowing
349# it to turn back on automatically if an XML file is provided.
350#   A vpath is used to find the XML input because this file is not allowed
351# to be present in external builds. Use of vpath allows it to be "poached"
352# from the internal build as necessary.
353#   There are a few ways to set ClmCompiler flags: passing them as the $3
354# parameter (preferred) or by overriding CLMCOMPDEFFLAGS. Additionally,
355# when the make variable CLM_TYPE is defined it points to a config file
356# for the compiler. The CLMCOMPEXTFLAGS variable contains "external flags"
357# which must be present for all external builds. It can be forced to "" for
358# debug builds.
359# Note: the .c file is listed with and without a path due to the way the
360# Linux kernel Makefiles generate .depend data.
361#   The undocumented $5 parameter has been used for dongle testing
362# against variant XML but its semantics are subject to change.
363CLMCOMPDEFFLAGS ?= --region '\#a/0' --region '\#r/0' --full_set
364CLMCOMPEXTFLAGS := --obfuscate
365define WLAN_GenClmCompilerRule
366$(eval\
367.PHONY: clm_compiled clm_clean
368vpath wlc_clm_data$4.c $1 $$(abspath $1)
369ifneq (,$(wildcard $(addsuffix /wl/clm/private/wlc_clm_data.xml,$2 $2/../../src $2/../../../src)))
370  vpath wlc_clm_data.xml $(wildcard $(addsuffix /wl/clm/private,$5 $2 $2/../../src $2/../../../src))
371  vpath %.clm $(addsuffix /wl/clm/types,$2 $2/../../src $2/../../../src)
372  $$(sort $1/wlc_clm_data$4.c ./wlc_clm_data$4.c): \
373      wlc_clm_data.xml $2/wl/clm/include/wlc_clm_data.h $$(wildcard $2/wl/clm/bin/ClmCompiler.py) $$(if $$(CLM_TYPE),$$(CLM_TYPE).clm) ; \
374    $$(strip $$(abspath $$(<D)/../../../tools/build/ClmCompiler) \
375      $$(if $$(CLM_TYPE),--config_file $$(lastword $$^) $3,$$(if $3,$3,$$(CLMCOMPDEFFLAGS))) \
376      $(CLMCOMPEXTFLAGS) $$< $$@ $$(call wlan_copy_to_gen,$$@,$2))
377else
378  vpath %.GEN $(subst $(abspath $2),$(abspath $2/$(WLAN_GEN_BASEDIR)),$1) $(sort $(patsubst %/,%,$(dir $(wildcard $(subst $(abspath $2),$(abspath $2/$(WLAN_GEN_BASEDIR)),$(dir $1))*/*.GEN))))
379  $1/%: %.GEN ; cp -pv $$< $$@
380endif
381  clm_compiled: $1/wlc_clm_data$4.c
382  clm_clean:: ; $$(RM) $1/wlc_clm_data$4.c
383  CLM_DATA_FILES += $1/wlc_clm_data$4.c
384)
385endef
386
387################################################################
388
389endif	# _WLAN_COMMON_MK
390