blob: 39b8d320779ee99b0b02d251fcb3eda0d24217b0 [file] [log] [blame]
# ==========================================================================
# 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