1# -*- mode: makefile;-*-
2#
3# Copyright (C) 1999-2012 Apple Inc. All rights reserved.
4#
5# MakeInc.kernel augments the single-architecture
6# recursive build system with rules specific
7# to assembling and linking a kernel.
8#
9
10#
11# Validate configuration options
12#
13ifeq ($(filter $(CURRENT_ARCH_CONFIG),$(SUPPORTED_ARCH_CONFIGS)),)
14$(error Unsupported CURRENT_ARCH_CONFIG $(CURRENT_ARCH_CONFIG))
15endif
16
17ifeq ($(filter $(CURRENT_KERNEL_CONFIG),$(SUPPORTED_KERNEL_CONFIGS)),)
18$(error Unsupported CURRENT_KERNEL_CONFIG $(CURRENT_KERNEL_CONFIG))
19endif
20
21ifeq ($(filter $(CURRENT_MACHINE_CONFIG),$(SUPPORTED_$(CURRENT_ARCH_CONFIG)_MACHINE_CONFIGS)),)
22$(error Unsupported CURRENT_MACHINE_CONFIG $(CURRENT_MACHINE_CONFIG))
23endif
24
25ifeq ($(filter $(PLATFORM),$(SUPPORTED_PLATFORMS)),)
26$(error Unsupported PLATFORM $(PLATFORM))
27endif
28
29STATIC_KMODS =  $(SRCROOT)/kmods.a
30
31#
32# Rules for the highly parallel "build" phase, where each build configuration
33# writes into their own $(TARGET) independent of other build configs
34#
35# There are 3 primary build outputs:
36# 1) $(KERNEL_FILE_NAME).unstripped    (raw linked kernel, unstripped)
37# 2) $(KERNEL_FILE_NAME)               (stripped kernel, with optional CTF data)
38# 3) $(KERNEL_FILE_NAME).dSYM          (dSYM)
39#
40
41do_build_all:: do_build_kernel
42
43.PHONY: do_build_kernel
44
45do_build_kernel: $(TARGET)/$(KERNEL_FILE_NAME) $(TARGET)/$(KERNEL_FILE_NAME).unstripped
46	@:
47
48ifeq ($(BUILD_DSYM),1)
49do_build_all:: do_build_kernel_dSYM
50endif
51
52.PHONY: do_build_kernel_dSYM
53
54do_build_kernel_dSYM: $(TARGET)/$(KERNEL_FILE_NAME).dSYM 
55	@:
56
57.LDFLAGS: ALWAYS
58	$(_v)$(REPLACECONTENTS) $@ $(LD) $(LDFLAGS_KERNEL) $(LD_KERNEL_LIBS)
59.CFLAGS: ALWAYS
60	$(_v)$(REPLACECONTENTS) $@ $(KCC) $(CFLAGS) $(INCFLAGS)
61
62$(TARGET)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME).unstripped
63	@echo STRIP $(@F)
64	$(_v)$(STRIP) $(STRIP_FLAGS) $< -o $@
65	$(_v)$(RM) $@.ctfdata
66ifeq ($(DO_CTFMERGE),1)
67	@echo CTFMERGE $(@F)
68	$(_v)$(FIND) $(TARGET)/ -name \*.ctf -size +0 | 		\
69		$(XARGS) $(CTFMERGE) -l xnu -o $@ -Z $@.ctfdata || true
70endif
71	$(_v)if [ -s $@.ctfdata ]; then								\
72		echo CTFINSERT $(@F);								\
73		$(CTFINSERT) $@	$(ARCH_FLAGS_$(CURRENT_ARCH_CONFIG)) 				\
74			     $@.ctfdata -o $@;							\
75	fi;
76	$(_v)$(LN) $(call function_convert_build_config_to_objdir,$(CURRENT_BUILD_CONFIG))/$(KERNEL_FILE_NAME) $(OBJROOT)/$(KERNEL_FILE_NAME)
77
78$(TARGET)/$(KERNEL_FILE_NAME).dSYM: $(TARGET)/$(KERNEL_FILE_NAME).unstripped
79	$(_v)echo DSYMUTIL $(@F)
80	$(_v)$(DSYMUTIL) $(DSYMUTIL_FLAGS) $< -o $@
81	$(_v)$(MV) $@/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME).unstripped $@/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
82	$(_v)$(TOUCH) $@
83
84$(TARGET)/$(KERNEL_FILE_NAME).unstripped: $(addprefix $(TARGET)/,$(foreach component,$(COMPONENT_LIST),$(component)/$(CURRENT_KERNEL_CONFIG)/$(component).filelist)) lastkernelconstructor.o $(SRCROOT)/config/version.c $(SRCROOT)/config/MasterVersion .LDFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
85	$(_v)${MAKE} -f $(firstword $(MAKEFILE_LIST)) version.o
86	@echo LD $(@F)
87	$(_v)$(CAT) $(filter %.filelist,$+) < /dev/null > link.filelist
88	$(_v)$(LD) $(LDFLAGS_KERNEL) -filelist link.filelist version.o $(filter %.o,$+) -o $@ $(LD_KERNEL_LIBS)
89
90-include version.d
91version.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
92version.o: $(OBJPATH)/version.c
93	${C_RULE_0}
94	${C_RULE_1A}$<
95	${C_RULE_2}
96	${C_RULE_4}
97
98# Always recreate version.sh
99$(OBJPATH)/version.c: $(SRCROOT)/config/version.c $(NEWVERS) $(SRCROOT)/config/MasterVersion ALWAYS
100	$(_v)$(CP) $< $@
101	$(_v)$(NEWVERS) $(OBJPATH)/version.c > /dev/null;
102
103-include lastkernelconstructor.d
104lastkernelconstructor.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
105lastkernelconstructor.o: $(SRCROOT)/libsa/lastkernelconstructor.c
106	${C_RULE_0}
107	${C_RULE_1A}$< $(CFLAGS_NOLTO_FLAG)
108	${C_RULE_2}
109	${C_RULE_3}
110	${C_RULE_4}
111	$(_v)$(SEG_HACK) -s __DATA -n __LAST -o $@__ $@
112	$(_v)$(MV) $@__ $@
113
114#
115# Install rules. Each build config is classified as "primary" (the first
116# config for an architecture) or "non-primary". Primary build configs
117# have the semantic of competing to *combine* single-architecture
118# files into a multi-architecture output in the DSTROOT, like
119# $(DSTROOT)/$(KERNEL_FILE_NAME), and consequently each primary build config
120# has its install target run serially with respect to other primary
121# build configs. Non-primary build configs will never compete for
122# files in the DSTROOT or SYMROOT, and can be installed in parallel
123# with other non-primary configs (and even primary configs)
124#
125
126do_build_install_primary:: do_install_machine_specific_kernel
127ifeq ($(BUILD_DSYM),1)
128do_build_install_primary:: do_install_machine_specific_kernel_dSYM
129endif
130
131do_build_install_non_primary:: do_install_machine_specific_kernel
132ifeq ($(BUILD_DSYM),1)
133do_build_install_non_primary:: do_install_machine_specific_kernel_dSYM
134endif
135
136ifeq ($(BUILD_DSYM),1)
137ifeq ($(INSTALL_KERNEL_SYM_TO_KDK),1)
138do_build_install_primary:: do_install_machine_specific_KDK_dSYM
139do_build_install_non_primary:: do_install_machine_specific_KDK_dSYM
140endif
141endif
142
143ifeq ($(INSTALL_XNU_DEBUG_FILES),1)
144do_build_install_primary:: do_install_xnu_debug_files
145endif
146
147.PHONY: do_install_xnu_debug_files
148
149do_install_xnu_debug_files:	$(DSTROOT)/$(DEVELOPER_EXTRAS_DIR)/README.DEBUG-kernel.txt
150	@:
151
152#
153# If the timestamp indicates the DSTROOT kernel is out of
154# date, start over. Normal dependencies don't work because we can have
155# ( BUILDA, BUILDB, INSTALLB, INSTALLA ) in which case at INSTALLA time
156# the timestamps would $(DSTROOT)/$(KERNEL_FILE_NAME) is not out of date compared
157# to BUILDA. So we maintain a separate file at the time make(1)
158# was run and use it to determine what actions to take
159#
160
161$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME) ALWAYS
162	$(_v)$(MKDIR) $(dir $@)
163	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ ]; then	\
164		echo INSTALL $(@F) "($(CURRENT_ARCH_CONFIG_LC) $(CURRENT_MACHINE_CONFIG_LC))"; \
165		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@;			\
166		cmdstatus=$$?;						\
167	else								\
168		echo INSTALL $(@F) "($(CURRENT_ARCH_CONFIG_LC) $(CURRENT_MACHINE_CONFIG_LC))"; \
169		$(LIPO) -create $@ $< -output $@;			\
170		cmdstatus=$$?;						\
171	fi;								\
172	exit $$cmdstatus
173
174$(SYMROOT)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME).unstripped ALWAYS
175	$(_v)$(MKDIR) $(dir $@)
176	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ ]; then		\
177		echo INSTALLSYM $(@F) "($(CURRENT_ARCH_CONFIG_LC))";	\
178		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@;				\
179		cmdstatus=$$?;							\
180	else									\
181		echo INSTALLSYM $(@F) "($(CURRENT_ARCH_CONFIG_LC))";	\
182		$(LIPO) -create $@ $< -output $@;				\
183		cmdstatus=$$?;							\
184	fi;									\
185	exit $$cmdstatus
186
187$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros $(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros: $(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros
188	$(_v)$(MKDIR) $(dir $@)
189	@echo INSTALLMACROS $(@F) "($(CURRENT_ARCH_CONFIG_LC))"
190	$(_v)$(CP) -r $< $(dir $@)
191	$(_v)$(TOUCH) $@
192
193$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME) $(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME): $(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME)
194	$(_v)$(MKDIR) $(dir $@)
195	@echo INSTALLMACROS $(@F) "($(CURRENT_ARCH_CONFIG_LC))"
196	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
197
198$(DSTROOT)/$(DEVELOPER_EXTRAS_DIR)/README.DEBUG-kernel.txt: $(SRCROOT)/config/README.DEBUG-kernel.txt
199	$(_v)$(MKDIR) $(dir $@)
200	@echo INSTALL $(@F)
201	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
202
203$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist $(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist: $(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist
204	$(_v)$(MKDIR) $(dir $@)
205	@echo INSTALLSYM dSYM $(@F) "($(CURRENT_ARCH_CONFIG_LC))"
206	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
207
208$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME) $(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME) ALWAYS
209	$(_v)$(MKDIR) $(dir $@)
210	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ ]; then			\
211		echo INSTALLSYM dSYM $(@F).dSYM "($(CURRENT_ARCH_CONFIG_LC))";	\
212		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@; 				\
213		cmdstatus=$$?;		       	   					\
214	else										\
215		echo INSTALLSYM dSYM $(@F).dSYM "($(CURRENT_ARCH_CONFIG_LC))";	\
216		$(LIPO) -create $@ $< -output $@; 					\
217		cmdstatus=$$?;		       	   					\
218	fi;										\
219	exit $$cmdstatus
220
221.PHONY: do_install_machine_specific_kernel do_install_machine_specific_kernel_dSYM
222
223do_install_machine_specific_kernel: $(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME) \
224			$(SYMROOT)/$(KERNEL_FILE_NAME)
225	@:
226
227do_install_machine_specific_kernel_dSYM: \
228			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist \
229			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros \
230			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME) \
231			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
232	@:
233
234.PHONY: do_install_machine_specific_KDK_dSYM
235
236do_install_machine_specific_KDK_dSYM: \
237			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist \
238			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros \
239			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME) \
240			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
241	@:
242
243# The $(RM) is needed so that the $(LN) doesn't dereference an existing
244# symlink during incremental builds and create a new symlink inside
245# the target of the existing symlink
246do_installhdrs_mi:: $(DSTROOT)/$(KRESDIR)/Info.plist
247	$(_v)$(MKDIR) $(DSTROOT)/$(KINCFRAME)
248	$(_v)$(MKDIR) $(DSTROOT)/$(KPINCDIR)
249	$(_v)$(MKDIR) $(DSTROOT)/$(KRESDIR)
250	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Versions/Current
251	$(_v)$(LN) $(KINCVERS) $(DSTROOT)/$(KINCFRAME)/Versions/Current
252	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Headers
253	$(_v)$(LN) Versions/Current/Headers			\
254		   $(DSTROOT)/$(KINCFRAME)/Headers
255	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/PrivateHeaders
256	$(_v)$(LN) Versions/Current/PrivateHeaders		\
257		   $(DSTROOT)/$(KINCFRAME)/PrivateHeaders
258	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Resources
259	$(_v)$(LN) Versions/Current/Resources			\
260		   $(DSTROOT)/$(KINCFRAME)/Resources
261
262$(DSTROOT)/$(KRESDIR)/Info.plist: $(SOURCE)/EXTERNAL_HEADERS/Info.plist
263	$(_v)$(MKDIR) $(DSTROOT)/$(KRESDIR)
264	$(_v)$(INSTALL) $(DATA_INSTALL_FLAGS) $< $@
265	$(_v)$(NEWVERS) $@ $(_vstdout)
266ifeq ($(USE_BINARY_PLIST),1)
267	$(_v)$(PLUTIL) -convert binary1 -o $@ $@
268endif
269
270print_exports:
271	$(_v)printenv | sort
272