| # ========================================================================== |
| # Support for building klibc and related programs |
| # ========================================================================== |
| # |
| # To create a kbuild file for a userspace program do the following: |
| # |
| # Kbuild: |
| # |
| # user-progs := cat |
| # |
| # This will compile a file named cat.c -> the executable 'cat' |
| # |
| # If the user space program consist of more files do the following: |
| # Kbuild: |
| # |
| # user-progs := ipconfig |
| # ipconfig-y := main.o netdev.c |
| |
| src := $(obj) |
| |
| .phony: __build |
| __build: |
| |
| # Generic Kbuild routines |
| include $(srctree)/scripts/Kbuild.include |
| |
| # Defines used when compiling early userspace (klibc programs) |
| # --------------------------------------------------------------------------- |
| KLIBSRC := usr/klibc |
| |
| # Arch specific definitions for klibc |
| include $(KLIBSRC)/arch/$(ARCH)/MCONFIG |
| |
| USERWARNFLAGS := -Wall -Wpointer-arith -Wwrite-strings \ |
| -Wstrict-prototypes -Winline |
| |
| USERCROSS := $(CROSS_COMPILE) |
| |
| USERLD := $(USERCROSS)ld |
| USERCC := $(USERCROSS)gcc |
| USERAR := $(USERCROSS)ar |
| USERRANLIB := $(USERCROSS)ranlib |
| USERSTRIP := $(USERCROSS)strip |
| USERNM := $(USERCROSS)nm |
| |
| USERCPPFLAGS := -I$(srctree)/usr/include/arch/$(ARCH) \ |
| -I$(srctree)/usr/include/bits$(BITSIZE) \ |
| -I$(srctree)/usr/include \ |
| -Iinclude \ |
| $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ |
| -D__KLIBC__ -DBITSIZE=$(BITSIZE) |
| USERCFLAGS := $(USERCPPFLAGS) $(ARCHREQFLAGS) $(OPTFLAGS) \ |
| $(USERWARNFLAGS) |
| USERAFLAGS := -D__ASSEMBLY__ $(USERCPPFLAGS) |
| USERSTRIPFLAGS := --strip-all -R .comment -R .note |
| |
| USERLIBGCC := $(shell $(USERCC) --print-libgcc) |
| USERSHAREDFLAGS := $(SHAREDFLAGS) |
| USERCRT0 := $(objtree)/$(KLIBSRC)/arch/$(ARCH)/crt0.o |
| USERLIBC := $(objtree)/$(KLIBSRC)/libc.a |
| |
| # |
| # This indicates the location of the final version of the shared library. |
| # THIS MUST BE AN ABSOLUTE PATH WITH NO FINAL SLASH. |
| # Leave this empty to make it the root. |
| # |
| SHLIBDIR = /lib |
| |
| export USERLD USERCC USERAR USERSTRIP USERNM |
| export USERCFLAGS USERAFLAGS USERLIBGCC USERSHAREDFLAGS USERSTRIPFLAGS |
| export USERCRT0 USERLIBC SHLIBDIR |
| |
| # kernel configuration |
| include .config |
| |
| # Add $(obj)/ for paths that is not absolute |
| objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) |
| |
| # Kbuild file in the directory that is being build |
| include $(obj)/Kbuild |
| |
| ##### |
| # user-progs := handling |
| |
| # user-progs based on a single .c file (with same name) |
| user-single := $(foreach p, $(user-progs), $(if $($(p)-y),,$(p))) |
| |
| # user-progs which is based on several .o files |
| user-multi := $(foreach p, $(user-progs), $(if $($(p)-y),$(p))) |
| # objects used for user-progs with more then one .o file |
| user-multi-objs := $(foreach p, $(user-multi), $($(p)-y)) |
| # objects build in this dir |
| user-real-objs := $(patsubst %/,,$(user-multi-objs)) |
| # Directories we need to visit before user-multi-obs are up-to-date |
| user-dirs := $(patsubst %/,%,$(filter %/, $(user-multi-objs))) |
| # replace all dir/ with dir/built-in.o |
| user-multi-objs := $(patsubst %/, %/built-in.o, $(user-multi-objs)) |
| |
| # $(output-dirs) are a list of directories that contain object files |
| output-dirs := $(dir $(user-dirs)) |
| output-dirs += $(foreach f, $(hostprogs-y) $(targets), \ |
| $(if $(dir $(f)), $(dir $(f)))) |
| output-dirs := $(strip $(sort $(filter-out ./,$(output-dirs)))) |
| |
| # prefix so we get full dir |
| user-progs := $(addprefix $(obj)/,$(user-progs)) |
| user-single := $(addprefix $(obj)/,$(user-single)) |
| user-multi := $(addprefix $(obj)/,$(user-multi)) |
| user-multi-objs := $(addprefix $(obj)/,$(user-multi-objs)) |
| user-real-objs := $(addprefix $(obj)/,$(user-real-objs)) |
| output-dirs := $(addprefix $(obj)/,$(output-dirs)) |
| user-dirs := $(addprefix $(obj)/,$(user-dirs)) |
| subdir-y := $(addprefix $(obj)/,$(subdir-y)) |
| always := $(addprefix $(obj)/,$(always)) |
| targets := $(addprefix $(obj)/,$(targets)) |
| |
| |
| _usercflags = $(USERCFLAGS) $(EXTRA_USERCFLAGS) $(USERCFLAGS_$(*F).o) |
| _useraflags = $(USERAFLAGS) $(EXTRA_USERAFLAGS) $(USERAFLAGS_$(*F).o) |
| |
| usercflags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(_usercflags) |
| useraflags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(_useraflags) |
| |
| ifneq ($(KBUILD_SRC),) |
| # Create output directory if not already present |
| _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) |
| |
| # Create directories for object files if directory does not exist |
| # Needed when obj-y := dir/file.o syntax is used |
| _dummy := $(foreach d,$(output-dirs), $(shell [ -d $(d) ] || mkdir -p $(d))) |
| endif |
| |
| # Do we have to make a built-in.o in this dir? |
| ifneq ($(strip $(obj-y) $(obj-n) $(obj-)),) |
| builtin-target := $(obj)/built-in.o |
| endif |
| |
| __build: $(subdir-y) $(builtin-target) $(always) |
| @: |
| |
| # Compile C sources (.c) |
| # --------------------------------------------------------------------------- |
| |
| quiet_cmd_cc_s_c = USERCC $@ |
| cmd_cc_s_c = $(USERCC) $(usercflags) -S -o $@ $< |
| |
| %.s: %.c FORCE |
| $(call if_changed_dep,cc_s_c) |
| |
| quiet_cmd_cc_i_c = USERCPP $@ |
| cmd_cc_i_c = $(USERCPP) $(usercflags) -o $@ $< |
| |
| %.i: %.c FORCE |
| $(call if_changed_dep,cc_i_c) |
| |
| quiet_cmd_cc_o_c = USERCC $@ |
| cmd_cc_o_c = $(USERCC) $(usercflags) -c -o $@ $< |
| |
| %.o: %.c FORCE |
| $(call if_changed_dep,cc_o_c) |
| |
| # Compile assembler sources (.S) |
| # --------------------------------------------------------------------------- |
| |
| quiet_cmd_as_s_S = USERCPP $@ |
| cmd_as_s_S = $(USERCPP) $(useraflags) -o $@ $< |
| |
| %.s: %.S FORCE |
| $(call if_changed_dep,as_s_S) |
| |
| quiet_cmd_as_o_S = USERAS $@ |
| cmd_as_o_S = $(USERCC) $(useraflags) -c -o $@ $< |
| |
| %.o: %.S FORCE |
| $(call if_changed_dep,as_o_S) |
| |
| targets += $(real-objs-y) |
| |
| # |
| # Rule to compile a set of .o files into one .o file |
| # |
| ifdef builtin-target |
| quiet_cmd_link_o_target = LD $@ |
| # If the list of objects to link is empty, just create an empty built-in.o |
| cmd_link_o_target = $(if $(strip $(obj-y)),\ |
| $(USERLD) $(USERLDFLAGS) -r -o $@ $(filter $(obj-y), $^),\ |
| rm -f $@; $(AR) rcs $@) |
| |
| $(builtin-target): $(obj-y) FORCE |
| $(call if_changed,link_o_target) |
| targets += $(builtin-target) |
| endif # builtin-target |
| |
| |
| ifdef user-progs |
| # Compile userspace programs for the target |
| # =========================================================================== |
| |
| __build : $(user-dirs) $(user-progs) |
| |
| # Descend if needed |
| $(sort $(addsuffix /built-in.o,$(user-dirs))): $(user-dirs) ; |
| |
| quiet_cmd_user-ld-single = USERLD $@ |
| cmd_user-ld-single = $(USERLD) $(USERLDFLAGS) -o $@ \ |
| $(USERCRT0) $< \ |
| $(filter-out FORCE,$^) \ |
| $(USERLIBC) $(USERLIBGCC) \ |
| $(USERLIBGCC); \ |
| $(USERSTRIP) $(USERSTRIPFLAGS) $@ |
| |
| $(user-single): %: %.o $(USERCRT0) $(USERLIBC) FORCE |
| $(call if_changed,user-ld-single) |
| |
| targets += $(user-single) $(user-single:=.o) |
| |
| multi-deps = $($(subst $(obj)/,,$@-y)) |
| link-multi-deps = $(addprefix $(obj)/, \ |
| $(patsubst %/, %/built-in.o, $(multi-deps))) |
| |
| quiet_cmd_user-ld-multi = USERLD $@ |
| cmd_user-ld-multi = $(USERLD) $(USERLDFLAGS) -o $@ \ |
| $(USERCRT0) \ |
| $(link-multi-deps) \ |
| $(USERLIBC) $(USERLIBGCC) \ |
| $(USERLIBGCC); \ |
| $(USERSTRIP) $(USERSTRIPFLAGS) $@ |
| |
| $(user-multi): $(user-multi-objs) FORCE |
| $(call if_changed,user-ld-multi) |
| |
| targets += $(user-multi) $(user-real-objs) |
| endif |
| |
| |
| # Compile programs on the host |
| # =========================================================================== |
| ifdef hostprogs-y |
| include $(srctree)/scripts/Makefile.host |
| endif |
| |
| # Descending |
| # --------------------------------------------------------------------------- |
| |
| .PHONY: $(subdir-y) $(user-dirs) |
| $(subdir-y) $(user-dirs): |
| $(Q)$(MAKE) $(klibc)=$@ |
| |
| # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
| # --------------------------------------------------------------------------- |
| |
| .PHONY: FORCE |
| |
| FORCE: |
| |
| # Linking |
| # Create a reloctable composite object file |
| # --------------------------------------------------------------------------- |
| quiet_cmd_userld = USERLD $@ |
| cmd_userld = $(USERLD) -r $(USERLDFLAGS) \ |
| $(EXTRA_USERLDFLAGS) $(USERLDFLAGS_$(@F)) \ |
| $(filter-out FORCE,$^) -o $@ |
| |
| |
| # Read all saved command lines and dependencies for the $(targets) we |
| # may be building above, using $(if_changed{,_dep}). As an |
| # optimization, we don't need to read them if the target does not |
| # exist, we will rebuild anyway in that case. |
| |
| targets := $(wildcard $(sort $(targets))) |
| cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) |
| |
| ifneq ($(cmd_files),) |
| include $(cmd_files) |
| endif |
| |
| # Shorthand for $(Q)$(MAKE) -f scripts/Kbuild.klibc obj |
| # Usage: |
| # $(Q)$(MAKE) $(klibc)=dir |
| klibc := -rR -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Kbuild.klibc obj |
| |