From: Michal Sojka Date: Mon, 8 Dec 2008 23:49:32 +0000 (+0100) Subject: Started attempt to make a simple rules for testing new approach X-Git-Url: http://rtime.felk.cvut.cz/gitweb/omk.git/commitdiff_plain/1f121e07c40efc5a9a1f159e085e1f3b50197b2d Started attempt to make a simple rules for testing new approach These rules should only compile C programs. This simplification allows me to throw most of the OMK complexity and test only what is the easiest way to implement prepare/build approach. --- diff --git a/rulesdef.py b/rulesdef.py index 6ab6374..89001dc 100755 --- a/rulesdef.py +++ b/rulesdef.py @@ -8,4 +8,5 @@ rules = { 'rtems': [ 'base', 'include', 'rtems', 'config_h', 'sources-list' ], 'sdcc': [ 'base', 'include', 'sdcc', 'config_h', 'sources-list', 'localeval' ], 'vxworks': [ 'base', 'include', 'vxworks', 'config_h', 'sources-list' ], + 'test': [ 'base', 'build' ], } diff --git a/snippets/build b/snippets/build new file mode 100644 index 0000000..a8e1c64 --- /dev/null +++ b/snippets/build @@ -0,0 +1,135 @@ + +BUILD_DIR_NAME = _build +COMPILED_DIR_NAME = _compiled + +USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include +USER_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib +USER_UTILS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils +USER_TESTS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests +USER_BIN_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin +USER_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user +LINK_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/link + +USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR) +KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR) +OMK_WORK_DIR = $(USER_OBJS_DIR) + +strip_out = $(patsubst $(OUTPUT_DIR)/%,%,$(1)) +repl_out = $(patsubst $(OUTPUT_DIR)/%,$$(OUTPUT_DIR)/%,$(1)) + +.PHONY: FORCE + +##################### +# Build pseudo-pass # +##################### + +rule_targets = $($(1)_targets) +rule_deps = $($(1)_deps) +rule_quiet_cmd = $($(1)_quiet_cmd) +rule_cmd = $($(1)_cmd) + +# Usage: $(call build_rule,) +define build_rule +$(rule_target): $(rule_deps) # TODO: dep on .cmd file + @$(QUIET_CMD_ECHO) " "$(rule_quiet_cmd) "$$(call strip_out,$$(@))" + $(Q)$(rule_cmd) +endef + +# TODO: Include target.omk only in the subtree +-include $(shell true; find $(USER_BUILD_DIR) -name '*.target.omk') # `true' is a hack for MinGW +-include $(shell true; find $(USER_BUILD_DIR) -name '*.var.omk') # `true' is a hack for MinGW + +$(foreach target,$(minor_targets),$(eval $(call build_rule,$(target)))) + +.PHONY: build-pseudo-pass +build-pseudo-pass: $(foreach target,$(major_targets),$(target)) + +################ +# Prepare pass # +################ + +$(eval $(call omk_pass_template,prepare-pass,$(USER_OBJS_DIR),,always)) + +var_omk_file = $(OMK_WORK_DIR)/$(notdir $(1)).var.omk +var_omk_target = $(1:$(OUTPUT_DIR)/%=%) + +target_omk_file = $(OMK_WORK_DIR)/$(notdir $(1)).target.omk + +### +# prepare is used to generate .var.omk files during prepare-pass. +# All paths in this file should be relative to $(OUTPUT_DIR) +# Usage: $(call prepare,,,,,) +define prepare +prepare-pass-local: $(var_omk_file) + +$(var_omk_file): FORCE + $(Q)echo 'minor_targets += $(var_omk_target)' > $$@.tmp; \ + echo '$(var_omk_target)_targets = $$(call strip_out,$(2))' >> $$@.tmp; \ + echo '$(var_omk_target)_deps += $$(call strip_out,$(3))' >> $$@.tmp; \ + echo '$(var_omk_target)_quiet_cmd = $(4)' >> $$@.tmp; \ + echo '$(var_omk_target)_cmd = $$(call repl_out,$(5))' >> $$@.tmp; \ + if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi +endef + +define target +prepare-pass-local: $(var_omk_file) +$(target_omk_file): FORCE + $(Q)echo 'major_targets += $(var_omk_target)' > $$@ +endef + +############ +# Programs # +############ + +# Syntax: $(call compile_c_o_template,,,) +define compile_c_o_template + +$(2): $(1) $$(GEN_HEADERS) + @$(QUIET_CMD_ECHO) " CC $$@" + $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \ + then mv -f "$$@.d.tmp" "$$@.d" ; \ + else rm -f "$$@.d.tmp" ; exit 1; \ + fi +endef + + +# Usage: $(call program_template,,) +define program_template +$(1)_OBJS += $$(patsubst %.c,%.o,$$(filter %.c,$$($(1)_SOURCES))) +$(1)_OBJS := $$(addprefix $(USER_OBJS_DIR),$$(sort $$($(1)_OBJS:%/=%))) + +USER_OBJS += $$($(1)_OBJS) +USER_SOURCES += $$($(1)_SOURCES) + + +program_targets = $(USER_BIN_DIR)/$(1)$(EXE_SUFFIX) +program_deps = $$($(1)_OBJS) $$($(1)_LIBS) +program_cmd = $$(if $$(filter %.cc,$$($(1)_SOURCES)),$$(CXX),$$(CC)) \ + $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) \ + -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$$$@ + +$(call prepare,\ + $(2)_PROGRAMS_$(1),\ + $$(program_targets),\ + $$(program_deps),\ + "LINK ",\ + $$(program_cmd)) +endef + +c_o_cmd := set -e; cd $$(dir $$@); \ + if $$(c_o_COMPILE) $$(CC_DEPFLAGS) -o $$@ -c $$< ; \ + then mv -f "$$@.d.tmp" "$$@.d" ; \ + else rm -f "$$@.d.tmp" ; \ + fi + + +$(foreach prog,$(bin_PROGRAMS),$(eval $(call program_template,$(prog),bin))) +$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call prepare,\ + $(USER_OBJS_DIR)/$(src:%.c=%.o),\ + $(USER_OBJS_DIR)/$(src:%.c=%.o),\ + $(SOURCES_DIR)/$(src),\ + "CC ",\ + $(c_o_cmd)))) + +default: prepare-pass +