xref: /xnu-10002.1.13/makedefs/MakeInc.kernel (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
1# -*- mode: makefile;-*-
2#
3# Copyright (C) 1999-2020 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
29# Generate xnu version file early (from build environment or SDK/KDK)
30do_build_setup:: $(XNU_VERSION)
31
32ifeq ($(BUILD_JSON_COMPILATION_DATABASE),1)
33do_build_setup::
34	$(_v)$(CAT) > $(OBJPATH)/compile_commands.json < /dev/null
35endif
36
37ifeq ($(BUILD_STATIC_LINK),1)
38ifeq ($(USE_LTO),1)
39# <rdar://problem/46252406>
40# To run LTO in the xnu project while linking the final result in KCB, without losing debugging info,
41# run ld -r on only the LTO bitcode object files to produce one mach-o for KCB to use, which is added
42# to the static link archive, along with the non-LTO objects (not linked, since ld -r on mach-o objects
43# does not preserve DWARF.)
44PRE_LTO=1
45endif
46endif
47
48#
49# Rules for the highly parallel "build" phase, where each build configuration
50# writes into their own $(TARGET) independent of other build configs
51#
52# There are 5 primary build outputs:
53# 1) $(KERNEL_FILE_NAME).unstripped    (raw linked kernel, unstripped)
54# 2) $(KERNEL_FILE_NAME)               (stripped kernel, with optional CTF data)
55# 3) $(KERNEL_FILE_NAME).dSYM          (dSYM)
56# 4) $(KERNEL_FILE_NAME).link          (bits for static linking)
57# 5) lib$(KERNEL_FILE_NAME).a          (static archive for testing)
58
59ifeq ($(BUILD_STATIC_LINK),1)
60ifeq ($(BUILD_XNU_LIBRARY),1)
61
62KERNEL_STATIC_LINK_TARGETS = \
63	$(TARGET)/lib$(KERNEL_FILE_NAME).a
64KERNEL_STATIC_LINK_DST = \
65	$(DSTROOT)/$(INSTALL_KERNEL_DIR)/lib$(KERNEL_FILE_NAME).a
66
67else
68
69KERNEL_STATIC_LINK_TARGETS = \
70	$(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).a
71
72KERNEL_STATIC_LINK_DST = \
73			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).a             \
74			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarguments \
75			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarchives  \
76			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).exp           \
77			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).alias.exp     \
78			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros                   \
79			$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME)
80
81endif
82endif
83
84do_build_all:: do_build_kernel
85
86.PHONY: do_build_kernel
87
88ifeq ($(BUILD_XNU_LIBRARY),1)
89do_build_kernel: $(KERNEL_STATIC_LINK_TARGETS)
90
91else
92
93do_build_kernel: $(TARGET)/$(KERNEL_FILE_NAME) $(TARGET)/$(KERNEL_FILE_NAME).unstripped $(KERNEL_STATIC_LINK_TARGETS)
94	@:
95
96ifeq ($(BUILD_DSYM),1)
97do_build_all:: do_build_kernel_dSYM
98endif
99
100.PHONY: do_build_kernel_dSYM
101
102do_build_kernel_dSYM: $(TARGET)/$(KERNEL_FILE_NAME).dSYM
103	@:
104
105endif
106
107.LDFLAGS: ALWAYS
108	$(_v)$(REPLACECONTENTS) $@ $(LD) $(LDFLAGS_KERNEL) $(LDFLAGS_KERNEL_ONLY) $(LD_KERNEL_LIBS)
109.CFLAGS: ALWAYS
110	$(_v)$(REPLACECONTENTS) $@ $(KCC) $(CFLAGS) $(INCFLAGS)
111
112
113#
114# CTF generation requires the following files:
115
116#     kernel.unstripped.noctf  Unstripped kernel with no CTF
117#     kernel.ctf               CTF from the dSYM associated with kernel.unstripped.noctf
118#     kernel.unstripped        kernel.unstripped.noctf merged with kernel.ctf (Debug Rich Executable)
119#     kernel                   Stripped kernel.unstripped.noctf merged with kernel.ctf (Final Kernel)
120
121# Note: "kernel" here is a placeholder for the actual name of the kernel which
122# varies.
123#
124
125
126# Convert DWARF to CTF
127$(TARGET)/$(KERNEL_FILE_NAME).ctf: $(TARGET)/$(KERNEL_FILE_NAME).dSYM $(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf
128ifeq ($(DO_CTFMERGE),1)
129	@$(LOG_CTFCONVERT) "$(@F)"
130	$(_v)$(CTFCONVERT) -c -l xnu -u xnu -o $@ $(TARGET)/$(KERNEL_FILE_NAME).dSYM/Contents/Resources/DWARF/$(KERNEL_FILE_NAME)
131endif
132
133# Strip the kernel and merge in the CTF
134$(TARGET)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf $(TARGET)/$(KERNEL_FILE_NAME).dSYM $(TARGET)/$(KERNEL_FILE_NAME).ctf
135	@$(LOG_STRIP) "$(@F)"
136	$(_v)$(STRIP) $(STRIP_FLAGS) $< -o $@
137	@echo "built kernel at $@"
138	$(_v)$(RM) [email protected]
139ifeq ($(DO_CTFMERGE),1)
140	@$(LOG_CTFMERGE) "$(@F)"
141	$(_v)$(CTFMERGE) -l xnu -o $@ -Z [email protected] [email protected]
142	$(_v)if [ -s [email protected] ]; then                          \
143		$(LOG_CTFINSERT) "$(@F)";                            \
144		$(CTFINSERT) $@	$(ARCH_FLAGS_$(CURRENT_ARCH_CONFIG)) \
145			     [email protected] -o $@;                           \
146	else                                                     \
147	    exit 1;                                              \
148	fi;
149	-$(_v)$(CTFDUMP) -S $@ $(_vstdout) $(_vstderr)
150endif
151	$(_v)$(LN) $(call function_convert_build_config_to_objdir,$(CURRENT_BUILD_CONFIG))/$(KERNEL_FILE_NAME) $(OBJROOT)/$(KERNEL_FILE_NAME)
152
153# Merge the CTF into the unstripped kernel (Debug Rich Executable)
154$(TARGET)/$(KERNEL_FILE_NAME).unstripped: $(TARGET)/$(KERNEL_FILE_NAME).ctf $(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf
155	$(_v)$(CP) $(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf $(TARGET)/$(KERNEL_FILE_NAME).unstripped
156	$(_v)$(RM) [email protected]
157ifeq ($(DO_CTFMERGE),1)
158	@$(LOG_CTFMERGE) "$(@F)"
159	$(_v)$(CTFMERGE) -l xnu -o $@ -Z [email protected] $(TARGET)/$(KERNEL_FILE_NAME).ctf
160	$(_v)if [ -s [email protected] ]; then                          \
161		$(LOG_CTFINSERT) "$(@F)";                            \
162		$(CTFINSERT) $@	$(ARCH_FLAGS_$(CURRENT_ARCH_CONFIG)) \
163			     [email protected] -o $@;                           \
164	else                                                     \
165	    exit 1;                                              \
166	fi;
167	-$(_v)$(CTFDUMP) -S $@ $(_vstdout) $(_vstderr)
168endif
169
170$(TARGET)/$(KERNEL_FILE_NAME).dSYM: $(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf
171ifeq ($(BUILD_DSYM),1)
172	@$(LOG_DSYMUTIL) "$(@F)"
173	$(_v)$(BASH) -c "$(DSYMUTIL) $(DSYMUTIL_FLAGS) $< -o $@ $(_vstdout) 2> >(grep -v '^warning:.*could not find object file symbol for symbol' 1>&2)"
174	$(_v)$(MV) $@/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME).unstripped.noctf $@/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
175else
176	$(_v)$(MKDIR) $@
177endif
178	$(_v)$(TOUCH) $@
179
180ifeq ($(BUILD_XNU_LIBRARY),1)
181$(TARGET)/lib$(KERNEL_FILE_NAME).a: $(addprefix $(TARGET)/,$(foreach component,$(COMPONENT_LIST),$(component)/$(CURRENT_KERNEL_CONFIG)/$(component).libfilelist)) nonlto.o version.o .LDFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
182	@$(LOG_LIBTOOL) "$(@F)"
183	$(_v)$(CAT) $(filter %.libfilelist,$+) < /dev/null > link.filelist
184	$(_v)$(LIBTOOL) -static -csD -filelist link.filelist -o $@
185	$(_v)$(LN) $(call function_convert_build_config_to_objdir,$(CURRENT_BUILD_CONFIG))/lib$(KERNEL_FILE_NAME).a $(OBJROOT)/lib$(KERNEL_FILE_NAME).a
186endif
187
188$(TARGET)/$(KERNEL_FILE_NAME).unstripped.noctf: $(addprefix $(TARGET)/,$(foreach component,$(COMPONENT_LIST),$(component)/$(CURRENT_KERNEL_CONFIG)/$(component).filelist)) lastkerneldataconst.o lastkernelconstructor.o nonlto.o version.o $(LDFILES_KERNEL_ONLY) .LDFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
189ifeq ($(PRE_LTO),1)
190	@$(LOG_LTO) "$(@F)"
191	$(_v)$(RM) ltolink.filelist
192	$(_v)$(RM) nonltolink.filelist
193	$(_v)$(RM) -r $(TARGET)/justlto.o
194	$(_v)files="$$($(CAT) $(filter %.filelist,$+)) $(filter %.o,$+)"; \
195	for ofile in $$files; \
196	do \
197		hdr=$$(od -An -N 4 -t x4 $$ofile); \
198		if [ $$hdr = "0b17c0de" ]; \
199			then \
200				if [ -z "$$lto" ]; \
201					then \
202						lto="$$ofile"; \
203					else \
204						lto="$$(printf '%s\n%s' "$$lto" "$$ofile")"; \
205				fi; \
206			else \
207				if [ -z "$$nonlto" ]; \
208					then \
209						nonlto="$$ofile"; \
210					else \
211						nonlto="$$(printf '%s\n%s' "$$nonlto" "$$ofile")"; \
212				fi; \
213			fi; \
214	done; \
215	printf '%s\n' "$$lto" >ltolink.filelist; \
216	printf '%s\n' "$$nonlto" >nonltolink.filelist
217	@$(LOG_LD) "$(@F)"
218	$(_v)if [ -s ltolink.filelist ]; \
219	then \
220		$(LD) $($(addsuffix $(CURRENT_ARCH_CONFIG),ARCH_FLAGS_)) -r nonlto.o -filelist ltolink.filelist $(LDFLAGS_KERNEL_LTO) -Wl,-object_path_lto,$(TARGET)/justlto.o -o $(TARGET)/justlto.tmp.o && \
221		if test -d $(TARGET)/justlto.o; \
222		then \
223		    $(LD) $(LDFLAGS_KERNEL) $(LDFLAGS_KERNEL_ONLY) -filelist nonltolink.filelist $(TARGET)/justlto.o/*.o $(LDFLAGS_KERNEL_STRIP_LTO) -o $@ $(LD_KERNEL_LIBS) $(LD_KERNEL_ARCHIVES); \
224		else \
225		    $(LD) $(LDFLAGS_KERNEL) $(LDFLAGS_KERNEL_ONLY) -filelist nonltolink.filelist $(TARGET)/justlto.o $(LDFLAGS_KERNEL_STRIP_LTO) -o $@ $(LD_KERNEL_LIBS) $(LD_KERNEL_ARCHIVES); \
226		fi; \
227	else \
228		$(LD) $(LDFLAGS_KERNEL) $(LDFLAGS_KERNEL_ONLY) -filelist nonltolink.filelist -o $@ $(LD_KERNEL_LIBS) $(LD_KERNEL_ARCHIVES); \
229	fi
230else
231	@$(LOG_LD) "$(@F)"
232	$(_v)$(CAT) $(filter %.filelist,$+) < /dev/null > link.filelist
233	$(_v)$(LD) $(LDFLAGS_KERNEL) $(LDFLAGS_KERNEL_ONLY) -filelist link.filelist $(filter %.o,$+) -o $@ $(LD_KERNEL_LIBS) $(LD_KERNEL_ARCHIVES)
234endif
235
236# for now, rename LASTDATA_CONST to LAST on static kernel cache builds
237EXTRA_KC_LINKARGS = -Wl,-rename_segment,__LASTDATA_CONST,__LAST
238
239$(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).a:   $(TARGET)/$(KERNEL_FILE_NAME).unstripped .LDFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
240	@$(LOG_LIBTOOL) "$(@F)"
241	$(_v)$(MKDIR) $(dir $@)
242ifeq ($(PRE_LTO),1)
243	$(_v)if [ -d $(TARGET)/justlto.o ]; \
244	then \
245	    $(LIBTOOL) -ca $(TARGET)/justlto.o/*.o -filelist nonltolink.filelist -o $@; \
246	else \
247	    $(LIBTOOL) -ca $(TARGET)/justlto.o -filelist nonltolink.filelist -o $@; \
248	fi
249else
250	$(_v)$(LIBTOOL) -ca -filelist link.filelist version.o lastkerneldataconst.o lastkernelconstructor.o -o $@
251endif
252	$(_v)cp $(TARGET)/all-kpi.exp $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).exp
253	$(_v)cp $(TARGET)/all-alias.exp $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).alias.exp
254	$(_v)echo "$(LD_KERNEL_ARCHIVES)" >$(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarchives
255	$(_v)echo "$(LDFLAGS_KERNEL) $(LD_KERNEL_LIBS) $(EXTRA_KC_LINKARGS)" >$(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarguments
256	$(_v)$(LN) $(call function_convert_build_config_to_objdir,$(CURRENT_BUILD_CONFIG))/$(KERNEL_FILE_NAME).link $(OBJROOT)/$(KERNEL_FILE_NAME).link
257
258nonlto.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
259nonlto.o:   $(SRCROOT)/libsa/nonlto.c
260	${C_RULE_0}
261	${C_RULE_1A}$< $(CFLAGS_NOLTO_FLAG)
262	${C_RULE_2}
263
264-include version.d
265version.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
266version.o: $(OBJPATH)/version.c
267	${C_RULE_0}
268	${C_RULE_1A}$<
269	${C_RULE_2}
270	${C_RULE_4}
271
272$(OBJPATH)/version.c: $(SRCROOT)/config/version.c.template $(NEWVERS) $(XNU_VERSION)
273	$(_v)$(CP) $< $@
274	$(_v)$(NEWVERS) $@ > /dev/null;
275
276# Generate xnuVersion file from B&I env var or the System.kext/Info.plist
277# found in the SDK or KDK. Only update the file if the version number has
278# actually changed to avoid rebuilding dependent source files unnecessarily.
279ifeq ($(origin RC_DARWIN_KERNEL_VERSION), undefined)
280SDK_SYSTEM_KEXT_INFO_PLIST := $(firstword $(wildcard $(addsuffix $(SYSTEM_KEXT_INFO_PLIST),$(SDKROOT_RESOLVED) $(KDKROOT))))
281ifneq ($(SDK_SYSTEM_KEXT_INFO_PLIST),)
282RC_DARWIN_KERNEL_VERSION := $(strip $(shell $(PLUTIL) -extract CFBundleVersion raw -n $(SDK_SYSTEM_KEXT_INFO_PLIST)))
283endif
284endif
285ifeq ($(RC_DARWIN_KERNEL_VERSION),)
286$(error Could not determine xnu version from SDK or KDK! Set RC_DARWIN_KERNEL_VERSION environment variable.)
287endif
288EXISTING_KERNEL_VERSION := $(strip $(shell test -r $(XNU_VERSION) && head -1 $(XNU_VERSION)))
289ifneq ($(EXISTING_KERNEL_VERSION), $(RC_DARWIN_KERNEL_VERSION))
290$(XNU_VERSION): ALWAYS
291	@$(LOG_GENERATE) "$(notdir $@)$(Color0) with version \"$(ColorF)$(RC_DARWIN_KERNEL_VERSION)$(Color0)\""
292	$(_v)printf > $@ '%s\n' "$(RC_DARWIN_KERNEL_VERSION)"
293else ifeq ($(VERBOSE),YES)
294$(XNU_VERSION): ALWAYS
295	@echo "xnuVersion unchanged: checked for \"$(RC_DARWIN_KERNEL_VERSION)\" in $@"
296endif
297
298-include lastkerneldataconst.d
299lastkerneldataconst.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
300lastkerneldataconst.o: $(SRCROOT)/libsa/lastkerneldataconst.c
301	${C_RULE_0}
302	${C_RULE_1A}$<
303	${C_RULE_2}
304
305
306lastkernelconstructor.o_CFLAGS_RM = -fprofile-instr-generate
307# the LAST segment is mapped read-only on arm, so if we include llvm profiling
308# here it will segfault the kernel.  (see arm_vm_init.c) We don't currently have
309# a way of retrieving these counters from LAST anyway, so there's no harm in just
310# disabling them.
311
312LAST_FILES=lastkernelconstructor.o
313-include lastkernelconstructor.d
314lastkernelconstructor.o: .CFLAGS $(filter %/MakeInc.kernel,$(MAKEFILE_LIST))
315lastkernelconstructor.o: $(SRCROOT)/libsa/lastkernelconstructor.c
316	${C_RULE_0}
317	${C_RULE_1A}$< $(CFLAGS_NOLTO_FLAG)
318	${C_RULE_2}
319	${C_RULE_3}
320	${C_RULE_4}
321	$(_v)for last_file in ${LAST_FILES};				\
322	do							\
323		$(SEG_HACK) -s __DATA -n __LASTDATA_CONST -o $${last_file}__ $${last_file} || exit 1; \
324		mv $${last_file}__ $${last_file} || exit 1;		\
325	done
326EXTRA_KC_LINKARGS = -Wl,-rename_segment,__LASTDATA_CONST,__LAST
327
328#
329# Install rules. Each build config is classified as "primary" (the first
330# config for an architecture) or "non-primary". Primary build configs
331# have the semantic of competing to *combine* single-architecture
332# files into a multi-architecture output in the DSTROOT, like
333# $(DSTROOT)/$(KERNEL_FILE_NAME), and consequently each primary build config
334# has its install target run serially with respect to other primary
335# build configs. Non-primary build configs will never compete for
336# files in the DSTROOT or SYMROOT, and can be installed in parallel
337# with other non-primary configs (and even primary configs)
338#
339
340do_build_install_primary:: do_install_machine_specific_kernel
341ifeq ($(BUILD_DSYM),1)
342do_build_install_primary:: do_install_machine_specific_kernel_dSYM
343endif
344
345do_build_install_non_primary:: do_install_machine_specific_kernel
346ifeq ($(BUILD_DSYM),1)
347do_build_install_non_primary:: do_install_machine_specific_kernel_dSYM
348endif
349
350ifeq ($(BUILD_DSYM),1)
351ifeq ($(INSTALL_KERNEL_SYM_TO_KDK),1)
352do_build_install_primary:: do_install_machine_specific_KDK_dSYM
353do_build_install_non_primary:: do_install_machine_specific_KDK_dSYM
354endif
355endif
356
357ifneq ($(BUILD_XNU_LIBRARY),1)
358ifeq ($(INSTALL_XNU_DEBUG_FILES),1)
359do_build_install_primary:: do_install_xnu_debug_files
360endif
361
362.PHONY: do_install_xnu_debug_files
363
364do_install_xnu_debug_files:	$(DSTROOT)/$(DEVELOPER_EXTRAS_DIR)/README.DEBUG-kernel.txt
365	@:
366endif
367
368#
369# If the timestamp indicates the DSTROOT kernel is out of
370# date, start over. Normal dependencies don't work because we can have
371# ( BUILDA, BUILDB, INSTALLB, INSTALLA ) in which case at INSTALLA time
372# the timestamps would $(DSTROOT)/$(KERNEL_FILE_NAME) is not out of date compared
373# to BUILDA. So we maintain a separate file at the time make(1)
374# was run and use it to determine what actions to take
375#
376
377$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME) ALWAYS
378	$(_v)$(MKDIR) $(dir $@)
379	@$(LOG_INSTALL) "$(@F)$(Color0) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
380    # -nt and -ot are evaluated differently by bash, dash, and zsh (and are not part of the POSIX specification).
381    # Explicitly specify what should happen when the right hand file doesn't exist.
382	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ -o \( -e $(OBJROOT)/.mach_kernel.timestamp -a \! -e $@ \) ]; then	\
383		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@;			\
384		cmdstatus=$$?;						\
385	else								\
386		$(LIPO) -create $@ $< -output $@;			\
387		cmdstatus=$$?;						\
388	fi;								\
389	exit $$cmdstatus
390
391ifeq ($(BUILD_STATIC_LINK),1)
392ifeq ($(BUILD_XNU_LIBRARY),1)
393
394$(DSTROOT)/$(INSTALL_KERNEL_DIR)/lib$(KERNEL_FILE_NAME).a: $(TARGET)/lib$(KERNEL_FILE_NAME).a ALWAYS
395	$(_v)$(MKDIR) $(dir $@)
396	@$(LOG_INSTALL) "$(@F)"
397	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
398
399else
400$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).a: $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).a ALWAYS
401	$(_v)$(MKDIR) $(dir $@)
402	@$(LOG_INSTALL) "$(@F)"
403	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
404
405$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarguments: $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarguments ALWAYS
406	$(_v)$(MKDIR) $(dir $@)
407	@$(LOG_INSTALL) "$(@F)"
408	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
409
410$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarchives: $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).linkarchives ALWAYS
411	$(_v)$(MKDIR) $(dir $@)
412	@$(LOG_INSTALL) "$(@F)"
413	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
414
415$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).exp: $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).exp ALWAYS
416	$(_v)$(MKDIR) $(dir $@)
417	@$(LOG_INSTALL) "$(@F)"
418	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
419
420$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).alias.exp: $(TARGET)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).alias.exp ALWAYS
421	$(_v)$(MKDIR) $(dir $@)
422	@$(LOG_INSTALL) "$(@F)"
423	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
424endif
425
426# BUILD_STATIC_LINK
427endif
428
429$(SYMROOT)/$(KERNEL_FILE_NAME): $(TARGET)/$(KERNEL_FILE_NAME).unstripped ALWAYS
430	$(_v)$(MKDIR) $(dir $@)
431	@$(LOG_INSTALLSYM) "$(@F)$(Color0) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
432    # -nt and -ot are evaluated differently by bash, dash, and zsh (and are not part of the POSIX specification).
433    # Explicitly specify what should happen when the right hand file doesn't exist.
434	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ -o \( -e $(OBJROOT)/.mach_kernel.timestamp -a \! -e $@ \) ]; then		\
435		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@;				\
436		cmdstatus=$$?;							\
437	else									\
438		$(LIPO) -create $@ $< -output $@;				\
439		cmdstatus=$$?;							\
440	fi;									\
441	exit $$cmdstatus
442
443
444$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros                                                                     \
445$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros                      \
446$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros:                                          \
447$(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros
448	$(_v)$(MKDIR) $(dir $@)
449	@$(LOG_INSTALLMACROS) "$(@F)$(Color0) $(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
450	$(_v)$(CP) -r $< $(dir $@)
451	$(_v)$(TOUCH) $@
452
453$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME)                                                   \
454$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME).link/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME)    \
455$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME):                        \
456$(TARGET)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME)
457	$(_v)$(MKDIR) $(dir $@)
458	@$(LOG_INSTALLMACROS) "$(@F)$(Color0) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
459	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
460
461$(DSTROOT)/$(DEVELOPER_EXTRAS_DIR)/README.DEBUG-kernel.txt: $(SRCROOT)/config/README.DEBUG-kernel.txt
462	$(_v)$(MKDIR) $(dir $@)
463	@$(LOG_INSTALL) "$(@F)"
464	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
465
466$(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
467	$(_v)$(MKDIR) $(dir $@)
468	@$(LOG_INSTALLSYM) "$(ColorL)dSYM$(Color0) $(ColorF)$(@F)$(Color0) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
469	$(_v)$(INSTALL) $(INSTALL_FLAGS) $< $@
470
471$(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
472	$(_v)$(MKDIR) $(dir $@)
473	@$(LOG_INSTALLSYM) "$(ColorL)dSYM$(Color0) $(ColorF)$(@F).dSYM$(ColorF) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0))"
474    # -nt and -ot are evaluated differently by bash, dash, and zsh (and are not part of the POSIX specification).
475    # Explicitly specify what should happen when the right hand file doesn't exist.
476	$(_v)if [ $(OBJROOT)/.mach_kernel.timestamp -nt $@ -o \( -e $(OBJROOT)/.mach_kernel.timestamp -a \! -e $@ \) ]; then			\
477		$(INSTALL) $(EXEC_INSTALL_FLAGS) $< $@;					\
478		cmdstatus=$$?;								\
479	else										\
480		$(LIPO) -create $@ $< -output $@;					\
481		cmdstatus=$$?;								\
482	fi;										\
483	exit $$cmdstatus
484
485.PHONY: do_install_machine_specific_kernel do_install_machine_specific_kernel_dSYM
486.PHONY: do_install_machine_specific_KDK_dSYM
487
488ifeq ($(BUILD_XNU_LIBRARY),1)
489
490do_install_machine_specific_kernel: $(KERNEL_STATIC_LINK_DST)
491	@:
492do_install_machine_specific_kernel_dSYM:
493	@:
494
495else
496
497do_install_machine_specific_kernel: $(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME)                \
498			$(SYMROOT)/$(KERNEL_FILE_NAME)                                                              \
499			$(KERNEL_STATIC_LINK_DST)
500	@:
501
502do_install_machine_specific_kernel_dSYM: \
503			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist \
504			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros \
505			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME) \
506			$(SYMROOT)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
507	@:
508
509do_install_machine_specific_KDK_dSYM: \
510			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMINFODIR)/Info.plist \
511			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/lldbmacros \
512			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMLLDBMACROSDIR)/$(KERNEL_LLDBBOOTSTRAP_NAME) \
513			$(DSTROOT)/$(INSTALL_KERNEL_SYM_DIR)/$(KERNEL_FILE_NAME).dSYM/$(DSYMDWARFDIR)/$(KERNEL_FILE_NAME)
514	@:
515
516endif
517
518# The $(RM) is needed so that the $(LN) doesn't dereference an existing
519# symlink during incremental builds and create a new symlink inside
520# the target of the existing symlink
521ifneq ($(INSTALLHDRS_SKIP_HOST),YES)
522do_installhdrs_mi:: $(DSTROOT)/$(KRESDIR)/Info.plist
523	$(_v)$(MKDIR) $(DSTROOT)/$(KINCFRAME)
524	$(_v)$(MKDIR) $(DSTROOT)/$(KPINCDIR)
525	$(_v)$(MKDIR) $(DSTROOT)/$(KRESDIR)
526	$(_v)$(MKDIR) $(DSTROOT)/$(KLIBCXXINCDIR)
527	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Versions/Current
528	$(_v)$(LN) $(KINCVERS) $(DSTROOT)/$(KINCFRAME)/Versions/Current
529	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Headers
530	$(_v)$(LN) Versions/Current/Headers			\
531		   $(DSTROOT)/$(KINCFRAME)/Headers
532	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/PrivateHeaders
533	$(_v)$(LN) Versions/Current/PrivateHeaders		\
534		   $(DSTROOT)/$(KINCFRAME)/PrivateHeaders
535	$(_v)$(RM) $(DSTROOT)/$(KINCFRAME)/Resources
536	$(_v)$(LN) Versions/Current/Resources			\
537		   $(DSTROOT)/$(KINCFRAME)/Resources
538endif
539
540ifneq ($(INSTALLHDRS_SKIP_HOST),YES)
541$(DSTROOT)/$(KRESDIR)/Info.plist: $(SOURCE)/EXTERNAL_HEADERS/Info.plist $(NEWVERS) $(XNU_VERSION)
542	$(_v)$(MKDIR) $(DSTROOT)/$(KRESDIR)
543	$(_v)$(INSTALL) $(DATA_INSTALL_FLAGS) $< $@
544	$(_v)$(NEWVERS) $@ $(_vstdout)
545ifeq ($(USE_BINARY_PLIST),1)
546	$(_v)$(PLUTIL) -convert binary1 -o $@ $@
547endif
548endif
549
550$(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(ALIAS_FILE_NAME): ALWAYS
551	@$(LOG_ALIAS) "$(@F)$(Color0) ($(ColorLF)$(CURRENT_ARCH_CONFIG_LC)$(Color0) $(ColorLF)$(CURRENT_MACHINE_CONFIG_LC)$(Color0) $(ColorLF)$(CURRENT_ALIAS_MACHINE_CONFIG_LC)$(Color0))"
552	$(_v)$(INSTALL) $(EXEC_INSTALL_FLAGS) $(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(KERNEL_FILE_NAME) $@
553
554install_alias: $(DSTROOT)/$(INSTALL_KERNEL_DIR)/$(ALIAS_FILE_NAME)
555
556print_exports:
557	$(_v)printenv | sort
558
559# vim: set ft=make:
560