]> rtime.felk.cvut.cz Git - omk.git/blob - snippets/build
a8e1c645f31b9a71b6a49f0b6cd6817c425d4750
[omk.git] / snippets / build
1
2 BUILD_DIR_NAME = _build
3 COMPILED_DIR_NAME = _compiled
4
5 USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
6 USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
7 USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
8 USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
9 USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
10 USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
11 LINK_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/link
12
13 USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
14 KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
15 OMK_WORK_DIR  = $(USER_OBJS_DIR)
16
17 strip_out = $(patsubst $(OUTPUT_DIR)/%,%,$(1))
18 repl_out  = $(patsubst $(OUTPUT_DIR)/%,$$(OUTPUT_DIR)/%,$(1))
19
20 .PHONY: FORCE
21
22 #####################
23 # Build pseudo-pass #
24 #####################
25
26 rule_targets   = $($(1)_targets)
27 rule_deps      = $($(1)_deps)
28 rule_quiet_cmd = $($(1)_quiet_cmd)
29 rule_cmd       = $($(1)_cmd)
30
31 # Usage: $(call build_rule,<target>)
32 define build_rule
33 $(rule_target): $(rule_deps)    # TODO: dep on .cmd file
34         @$(QUIET_CMD_ECHO) "  "$(rule_quiet_cmd) "$$(call strip_out,$$(@))"
35         $(Q)$(rule_cmd)
36 endef
37
38 # TODO: Include target.omk only in the subtree
39 -include $(shell true; find $(USER_BUILD_DIR) -name '*.target.omk') # `true' is a hack for MinGW
40 -include $(shell true; find $(USER_BUILD_DIR) -name '*.var.omk') # `true' is a hack for MinGW
41
42 $(foreach target,$(minor_targets),$(eval $(call build_rule,$(target))))
43
44 .PHONY: build-pseudo-pass
45 build-pseudo-pass: $(foreach target,$(major_targets),$(target))
46
47 ################
48 # Prepare pass #
49 ################
50
51 $(eval $(call omk_pass_template,prepare-pass,$(USER_OBJS_DIR),,always))
52
53 var_omk_file = $(OMK_WORK_DIR)/$(notdir $(1)).var.omk
54 var_omk_target = $(1:$(OUTPUT_DIR)/%=%)
55
56 target_omk_file = $(OMK_WORK_DIR)/$(notdir $(1)).target.omk
57
58 ###
59 # prepare is used to generate .var.omk files during prepare-pass.
60 # All paths in this file should be relative to $(OUTPUT_DIR)
61 # Usage: $(call prepare,<target-name>,<targets>,<deps>,<quiet_cmd>,<cmd>)
62 define prepare
63 prepare-pass-local: $(var_omk_file)
64
65 $(var_omk_file): FORCE
66         $(Q)echo 'minor_targets += $(var_omk_target)' > $$@.tmp; \
67             echo '$(var_omk_target)_targets = $$(call strip_out,$(2))' >> $$@.tmp; \
68             echo '$(var_omk_target)_deps += $$(call strip_out,$(3))' >> $$@.tmp; \
69             echo '$(var_omk_target)_quiet_cmd = $(4)' >> $$@.tmp; \
70             echo '$(var_omk_target)_cmd = $$(call repl_out,$(5))' >> $$@.tmp; \
71         if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi
72 endef
73
74 define target
75 prepare-pass-local: $(var_omk_file)
76 $(target_omk_file): FORCE
77         $(Q)echo 'major_targets += $(var_omk_target)' > $$@
78 endef
79
80 ############
81 # Programs #
82 ############
83
84 # Syntax: $(call compile_c_o_template,<source>,<target>,<additional c-flags>)
85 define compile_c_o_template
86
87 $(2): $(1) $$(GEN_HEADERS)
88         @$(QUIET_CMD_ECHO) "  CC      $$@"
89         $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
90         then mv -f "$$@.d.tmp" "$$@.d" ; \
91         else rm -f "$$@.d.tmp" ; exit 1; \
92         fi
93 endef
94
95
96 # Usage: $(call program_template,<executable-name>,<bin|utils|test>)
97 define program_template
98 $(1)_OBJS += $$(patsubst %.c,%.o,$$(filter %.c,$$($(1)_SOURCES)))
99 $(1)_OBJS := $$(addprefix $(USER_OBJS_DIR),$$(sort $$($(1)_OBJS:%/=%)))
100
101 USER_OBJS  += $$($(1)_OBJS)
102 USER_SOURCES += $$($(1)_SOURCES)
103
104
105 program_targets = $(USER_BIN_DIR)/$(1)$(EXE_SUFFIX)
106 program_deps = $$($(1)_OBJS) $$($(1)_LIBS)
107 program_cmd = $$(if $$(filter %.cc,$$($(1)_SOURCES)),$$(CXX),$$(CC)) \
108         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) \
109         -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$$$@
110
111 $(call prepare,\
112         $(2)_PROGRAMS_$(1),\
113         $$(program_targets),\
114         $$(program_deps),\
115         "LINK    ",\
116         $$(program_cmd))
117 endef
118
119 c_o_cmd := set -e; cd $$(dir $$@); \
120         if $$(c_o_COMPILE) $$(CC_DEPFLAGS) -o $$@ -c $$< ; \
121         then mv -f "$$@.d.tmp" "$$@.d" ; \
122         else rm -f "$$@.d.tmp" ; \
123         fi
124
125
126 $(foreach prog,$(bin_PROGRAMS),$(eval $(call program_template,$(prog),bin)))
127 $(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call prepare,\
128         $(USER_OBJS_DIR)/$(src:%.c=%.o),\
129         $(USER_OBJS_DIR)/$(src:%.c=%.o),\
130         $(SOURCES_DIR)/$(src),\
131         "CC      ",\
132         $(c_o_cmd))))
133
134 default: prepare-pass
135