]> rtime.felk.cvut.cz Git - omk.git/blob - snippets/nuttx-compile.omk
510cf965643b02d779c75cb4d093c48ceed5c930
[omk.git] / snippets / nuttx-compile.omk
1
2 # Rules for NuttX binaries compilation of C, C++ and assembler
3 # sources using GNU toolchain.
4
5 # Interface to other rules:
6
7 # Input variables:
8 # NUTTX_EXPORT - export directory of NuttX build
9 #                it should contain subdirectories:
10 #                arch  build  include  libs  registry  startup)
11 # LIB_DIR - directory where compiled libraries are stored
12 # OBJS_DIR - directory where intermediate files (.o, .map, ...) are stored
13 # INCLUDE_DIR - where includes can be found
14 # from config.omk or Makefile.omk
15 # CROSS_COMPILE - target architecture tools prefix
16 # TARGET_ARCH, DEBUG, OPTIMIZE, DEFS - forms CFLAGS
17 # from base: SOURCES_DIR
18 # from Makefile.omk: lib_LOADLIBES
19
20 # Output variables:
21 # SOURCES - all the source files that needs to be compiled (except for shared library sources)
22 # SOLIB_SOURCES - all the source files that needs to be compiled for a shared library
23 # OBJ_EXT - extension of object files
24 # LIB_EXT - extension of library files
25 # LIB_PREF - prefix for library files
26 # ASM_EXT - extension of assembler sources
27
28 # Templates:
29 # COMPILER_DEFS_template - definitions that should be defined before
30 # the following templates can be used. The input variables needs to be
31 # defined before evaluating this template
32
33 # COMPILE_c_o_template, COMPILE_cc_o_template, COMPILE_S_o_template -
34 # templates that create rules for compilation of sources
35
36 # PROGRAM_template, LIBRARY_template, SOLIB_template - templates that
37 # create rules for compilation of a program, library and shared
38 # library. The rules can use rules produced by COMPILE_xxx_template.
39
40 define COMPILER_DEFS_template
41 OBJ_EXT = .o
42 LIB_EXT = .a
43 LIB_PREF = lib
44 ASM_EXT = .S
45
46 CC = $(CROSS_COMPILE)gcc
47 CXX = $(CROSS_COMPILE)g++
48 LINK = $(CROSS_COMPILE)ld
49 AR = $(CROSS_COMPILE)ar
50 OBJCOPY = $(CROSS_COMPILE)objcopy
51 NM = $(CROSS_COMPILE)nm
52
53 CFLAGS += $(TARGET_ARCH) $(DEBUG) $(OPTIMIZE)
54 CFLAGS  += -Wall
55 CFLAGS += -I$(SOURCES_DIR)
56 CFLAGS += -I$(INCLUDE_DIR)
57
58 LOADLIBES += -L$(LIB_DIR)
59 LOADLIBES += $(lib_LOADLIBES:%=-l%)
60
61
62 -include $(OBJS_DIR)/*.d
63
64 SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.s .o/.o
65
66 SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.s .lo/.lo
67
68 #%.lo: %.c
69 #       $(CC) -o $@ $(LCFLAGS) -c $<
70
71 c_o_COMPILE = $$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(OMK_CPPFLAGS) \
72         $(CPPFLAGS) $(OMK_CFLAGS) $$(CFLAGS)
73
74 cc_o_COMPILE = $$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(OMK_CPPFLAGS) \
75         $(CPPFLAGS) $(CXXFLAGS) $(OMK_CFLAGS) $$(CFLAGS)
76
77 S_o_COMPILE = $$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
78         $(CPPFLAGS) $(OMK_CFLAGS) $$(CFLAGS) $(ASFLAGS)
79
80
81 # Check GCC version for user build
82 ifndef CC_MAJOR_VERSION
83 CC_MAJOR_VERSION = $$(shell $$(CC) -dumpversion | $(SED4OMK) -e 's/\([^.]\)\..*/\1/')
84 endif
85 # Prepare suitable define for dependency building
86 ifeq ($$(CC_MAJOR_VERSION),2)
87 CC_DEPFLAGS = -Wp,-MD,"$$@.d.tmp"
88 else
89 CC_DEPFLAGS = -MT $$@ -MD -MP -MF "$$@.d.tmp"
90 endif
91
92 endef # COMPILER_DEFS_template
93
94
95 # Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
96 define COMPILE_c_o_template
97 $(2): $(1) $$(GEN_HEADERS)
98         @$(QUIET_CMD_ECHO) "  CC      $$@"
99         $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
100         then mv -f "$$@.d.tmp" "$$@.d" ; \
101         else rm -f "$$@.d.tmp" ; exit 1; \
102         fi
103 endef
104
105
106 # Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
107 define COMPILE_cc_o_template
108 $(2): $(1) $$(GEN_HEADERS)
109         @$(QUIET_CMD_ECHO) "  CXX     $$@"
110         $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
111         then mv -f "$$@.d.tmp" "$$@.d" ; \
112         else rm -f "$$@.d.tmp" ; exit 1; \
113         fi
114 endef
115
116 # Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
117 define COMPILE_S_o_template
118 $(2): $(1) $$(GEN_HEADERS)
119         @$(QUIET_CMD_ECHO) "  AS      $$@"
120         $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
121         then if [ -e "$$@.d.tmp" ] ; then mv -f "$$@.d.tmp" "$$@.d" ; fi ; \
122         else rm -f "$$@.d.tmp" ; exit 1; \
123         fi
124 endef
125
126 # Syntax: $(call PROGRAM_template,<executable-name>,<dir>,<link-variant>)
127 define PROGRAM_template
128
129 GEN_SOURCES += $$($(1)_GEN_SOURCES)
130
131 $(foreach x, $(SOURCES2OBJS),
132 $(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
133                 $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
134 )
135 $(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
136
137 SOURCES += $$($(1)_SOURCES)
138
139 ifneq ($$($(1)_PROGBUILTIN),)
140 ifneq ($$($(1)_PROGBUILTIN),all)
141 $(1)_PROGBUILTIN_LIST = $$($(1)_PROGBUILTIN)
142 else
143 $(1)_PROGBUILTIN_TMP = $$(wildcard $$(USER_COMPILED_DIR_NAME)/registry/*.pbi)
144 $(1)_PROGBUILTIN_LIST = $$($(1)_PROGBUILTIN_TMP:$$(USER_COMPILED_DIR_NAME)/registry/%.pbi=%)
145 endif
146
147 $(1)_PROGBUILTIN_PBI=$$($(1)_PROGBUILTIN_LIST:%=$$(USER_COMPILED_DIR_NAME)/registry/%.pbi)
148 $(1)_PROGBUILTIN_ldat=$$($(1)_PROGBUILTIN_LIST:%=$$(USER_COMPILED_DIR_NAME)/registry/%.ldat)
149 $(1)_PROGBUILTIN_PDAT=$$($(1)_PROGBUILTIN_LIST:%=$$(USER_COMPILED_DIR_NAME)/registry/%.pdat) \
150         $$(wildcard $(NUTTXREGISTRY)/*.pdat)
151 $(1)_PROGBUILTIN_BDAT=$$($(1)_PROGBUILTIN_LIST:%=$$(USER_COMPILED_DIR_NAME)/registry/%.bdat) \
152         $$(wildcard $(NUTTXREGISTRY)/*.bdat)
153
154 ifneq ($$($(1)_PROGBUILTIN_PDAT),)
155 $(1)_BUILTINTABLE = $(OBJS_DIR)/$(1)-builtintab.c
156
157 $$($(1)_BUILTINTABLE): $$($(1)_PROGBUILTIN_PDAT) $$($(1)_PROGBUILTIN_BDAT)
158         $(Q) cat $$($(1)_PROGBUILTIN_PDAT) >$$@
159         $(Q) echo "#include <nuttx/config.h>" >>$$@
160         $(Q) echo "#include <nuttx/binfmt/builtin.h>" >>$$@
161         $(Q) echo "const struct builtin_s g_builtins[] = {" >>$$@
162         $(Q) cat $$($(1)_PROGBUILTIN_BDAT) >>$$@
163         $(Q) echo "{ NULL, 0, 0, 0 }};" >>$$@
164         $(Q) echo "const int g_builtin_count = sizeof(g_builtins) / sizeof(g_builtins[0]);" >>$$@
165
166 GEN_SOURCES += $$($(1)_BUILTINTABLE)
167 endif
168 endif
169
170
171 ifneq ($$(LD_SCRIPT$(3:%=-%)),)
172 $(1)$(3:%=-%)_LD_SCRIPT_FN = $$(LD_SCRIPT$(3:%=-%))
173 else
174 $(1)$(3:%=-%)_LD_SCRIPT_FN = $$(LD_SCRIPT)
175 endif
176
177 ifeq ($$(dir $$($(1)$(3:%=-%)_LD_SCRIPT_FN)),)
178 $(1)$(3:%=-%)_LD_SCRIPT = $$(LIB_DIR)/$$($(1)$(3:%=-%)_LD_SCRIPT_FN)
179 else
180 $(1)$(3:%=-%)_LD_SCRIPT = $$($(1)$(3:%=-%)_LD_SCRIPT_FN)
181 endif
182
183 $(1)$(3:%=-%)_LDFLAGS = -Wl,-T,$$($(1)$(3:%=-%)_LD_SCRIPT)
184
185 $(2)/$(1)$(3:%=-%): $$($(1)_OBJS) $$($(1)_BUILTINTABLE:%.c=%.o) $$($(1)_PROGBUILTIN_ldat) $$($(1)$(3:%=-%)_LD_SCRIPT)
186         @$(QUIET_CMD_ECHO) "  LINK    $$@"
187         $(Q) if [ -n "$$($(1)_PROGBUILTIN_LIST)" ] ; then echo ; fi
188         $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES)) , \
189           $$(CXX) $$(CPPFLAGS) $$(OMK_CPPFLAGS) $$(OMK_CXXFLAGS) $$(CXXFLAGS) , \
190           $$(CC)  $$(CPPFLAGS) $$(OMK_CPPFLAGS) $$(OMK_CFLAGS)   $$(CFLAGS) ) \
191           $$(OMK_LDFLAGS) $$(LDFLAGS) $$($(1)$(3:%=-%)_LDFLAGS) -Wl,-Map,$(1)$(3:%=-%).map \
192           $$($(1)_OBJS) $$($(1)_MOREOBJS) $$($(1)_BUILTINTABLE:%.c=%.o) \
193           $$($(1)_PROGBUILTIN_PBI) $$(LOADLIBES) $$($(1)_LIBS:%=-l%) \
194           $$(shell for i in $$($(1)_PROGBUILTIN_ldat); do cat $$$$i ; done) $$(NUTTXLIBES) \
195           -o $$@
196         @echo "$(2)/$(1)$(3:%=-%): \\" >$(OBJS_DIR)/$(1)$(3:%=-%).exe.d
197         @$(SED4OMK) -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(OBJS_DIR)/$(1)$(3:%=-%).map|tr '&' '\134'  >>$(OBJS_DIR)/$(1)$(3:%=-%).exe.d
198         @echo >>$(OBJS_DIR)/$(1).exe.d
199 endef
200
201 # Syntax: $(call ELF_template,<executable-name>,<dir>)
202 define ELF_template
203
204 $(2)/$(1).elf: $$($(1)_OBJS)
205         @$(QUIET_CMD_ECHO) "  ELF     $$@"
206         $(Q) $(LINK) \
207           -r -e main -T $(NUTTX_EXPORT)/build/gnu-elf.ld \
208           -Map $(1).elf.map \
209           $$($(1)_OBJS) $$($(1)_MOREOBJS) $$(LOADLIBES) $$($(1)_LIBS:%=-l%) \
210           -o $$@
211         @echo "$(2)/$(1).elf: \\" >$(OBJS_DIR)/$(1).elf.d
212         @echo "  $(NUTTX_EXPORT)/build/gnu-elf.ld \\" >>$(OBJS_DIR)/$(1).elf.d
213         @$(SED4OMK) -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(OBJS_DIR)/$(1).elf.map|tr '&' '\134'  >>$(OBJS_DIR)/$(1).elf.d
214         @echo >>$(OBJS_DIR)/$(1).elf.d
215 endef
216
217 # Syntax: $(call PROGBUILTIN_template,<executable-name>,<dir>,<registry-dir>)
218 define PROGBUILTIN_template
219
220 $(1)_PRIORITY ?= SCHED_PRIORITY_DEFAULT
221 $(1)_STACKSIZE ?= 2048
222
223 $(2)/$(1).pbi: $$($(1)_OBJS)
224         @$(QUIET_CMD_ECHO) "  PROGMOD $$@"
225         $(Q) $(LINK) \
226           -r -x --defsym=$(1)_main=main \
227           -Map $(1).pbi.map \
228           $$($(1)_OBJS) $$($(1)_MOREOBJS) \
229           -o $(OBJS_DIR)/$(1).pbo
230         $(Q) $(OBJCOPY) --keep-global-symbol=$(1)_main $(OBJS_DIR)/$(1).pbo $$@
231         @echo "$(2)/$(1).pbi: \\" >$(OBJS_DIR)/$(1).pbi.d
232         @$(SED4OMK) -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(OBJS_DIR)/$(1).pbi.map|tr '&' '\134'  >>$(OBJS_DIR)/$(1).pbi.d
233         @echo >>$(OBJS_DIR)/$(1).pbi.d
234         @echo "{ \"$1\", $$($(1)_PRIORITY), $$($(1)_STACKSIZE), $(1)_main }," >$(3)/$(1).bdat
235         @echo "int $(1)_main(int argc, char *argv[]);" >$(3)/$(1).pdat
236         @echo "$$(LOADLIBES) $$($(1)_LIBS:%=-l%)" >$(3)/$(1).ldat
237 endef
238
239
240 # Rules for other output formats (can be specified by OUTPUT_FORMATS)
241 %.bin: %
242         @$(QUIET_CMD_ECHO) "  OBJCOPY $@"
243         $(Q) $(OBJCOPY)  --output-target=binary -S $< $@
244
245 %.hex: %
246         @$(QUIET_CMD_ECHO) "  OBJCOPY $@"
247         $(Q) $(OBJCOPY)  --output-target=ihex -S $< $@
248
249 %.srec: %
250         @$(QUIET_CMD_ECHO) "  OBJCOPY $@"
251         $(Q) $(OBJCOPY)  --output-target=srec -S $< $@
252
253 # Syntax: $(call LIBRARY_template,<library-name>)
254 define LIBRARY_template
255
256 GEN_SOURCES += $$($(1)_GEN_SOURCES)
257
258 $(foreach x, $(SOURCES2OBJS),
259 $(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
260                 $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
261 )
262 $(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
263
264 SOURCES += $$($(1)_SOURCES)
265
266 $(LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
267         @$(QUIET_CMD_ECHO) "  AR      $$@"
268         $(Q) $(AR) rcs $$@ $$^
269 endef
270
271
272 # Syntax: $(call SOLIB_template,<library-name>)
273 define SOLIB_template
274
275 SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
276
277 $(foreach x, $(SOURCES2OBJSLO),
278 $(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
279                 $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
280 )
281 $(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
282
283 SOLIB_OBJS  += $$($(1)_OBJSLO)
284 SOLIB_SOURCES += $$($(1)_SOURCES)
285
286 $(LIB_DIR)/lib$(1).so: $$($(1)_OBJSLO)
287         @$(QUIET_CMD_ECHO) "  LINK    $$@"
288         $(Q) $(LD) --shared --soname=lib$(1).so -o $$@ $$^
289 endef
290
291 ifneq ($(bin_PROGRAMS),)
292 library-pass_HOOKS += force_builtin_library_hook
293
294 .PHONY: force_builtin_library_hook
295 force_builtin_library_hook:
296
297 endif