U-Boot의 makefile을 살펴보았습니다.
config관련 사항으로 꽤 긴 라인으로 되어있지만, 실제 중요한 부분은 그닥 많지 않은 듯하네요.
세부적인 makefile의 문법적인 분석이 아니라, 대략적인 구성을 살펴보는 것으로 의의를 두고 시작하였습니다.
결론은, make시 몇가지 tip들을 얻을 수 있었다는 점이네요. (다 알고 있는 내용인데 나만 몰랐을 지도... ㅠㅠ)
- 대략적인 u-boot의 구성을 확인할 수있다.
- make 시 BUILD_DIR=path 를 지정하면, output path를 source path가 아닌 곳으로 설정 할 수 있다.
- unconfig 을 이용하여 config 관련 사항을 삭제할 수있다.
- distclean 을 이용하면 clobber과 unconfig 를 동시에 실행한다.
- backup 을 이용하면 xxx.tar.gz 형태로 코드를 백업할 수 있다.
이상입니다.
이후 글들은 그냥 편하게 적겠습니다. 사실 makefile을 때어다가 ctrl+c, v를 한거나 마찬가지일지도... ^^;;;
1. U-Boot의 Version 정보
25 PATCHLEVEL = 3
26 SUBLEVEL = 4
27 EXTRAVERSION =
28 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
29 VERSION_FILE = $(obj)include/version_autogenerated.h
2. BUILD_DIR 설정이 가능하다.
O=/path/ 혹은 export BUILD_DIR=/path/ 설정으로 object 및 target binary directory를 임의로 설정할 수 있다.
79 ifeq ("$(origin O)", "command line")
80 BUILD_DIR := $(O)
81 endif
82 endif
// BUILD_DIR 이 설정되지 않았을 경우, Source Code의 TOP_DIR이 BUILD_DIR이 된다.
84 ifneq ($(BUILD_DIR),)
85 saved-output := $(BUILD_DIR)
86
87 # Attempt to create a output directory.
88 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
89
90 # Verify if it was successful.
91 BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
92 $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
93 endif # ifneq ($(BUILD_DIR),)
>> How to Compile use specified Build Directory
1). 아무리 BUILD_DIR을 설정하였다 하여도, config 생성시 include에 추가되는 config.h는 Source Code의 include에 포함되어 있어야 한다. (v1.3.4 에서만 test됨, 상위버전의 경우 test 필요)
2 - 1) Add O=/pathname/ to the make command line
$ make O=/tmp/build
2 - 2) Set environement variable BUILD_DIR to point to the desired location
$ make xxxx_config
$ make
3. Cross Compiler 설정
1) mkconfig로 생성된 config.mk가 있는지 확인. config.mk에 ARCH, BOARD, CPU, SOC 등의 정보가 정의된다.
131
132 # load ARCH, BOARD, and CPU configuration
133 include $(obj)include/config.mk
134 export ARCH CPU BOARD VENDOR SOC
이렇게 export 함으로써 실제 각 폴더에 있는 Makefile 들이 동일한 설정으로 해당 변수들을 사용할 수 있다.
이 내용은 Source Directory에 포함된 Makefile을 분석할때 상세히 작성하도록 하겠다.
2) 해당되는 ARCH 비교문에서 CROSS_COMPILE을 설정하자. path가 잡혀있지 않으면 full path를 포함하여 기술하면 된다.
arm-linux-gcc, arm-linux-ld 등의 실행파일중 공통적으로 사용되는 arm-linux- 를 입력하면 된다.
137 ifeq ($(HOSTARCH),$(ARCH))
138 CROSS_COMPILE =
139 else
140 ifeq ($(ARCH),ppc)
141 CROSS_COMPILE = ppc_8xx-
142 endif
143 ifeq ($(ARCH),arm)
144 CROSS_COMPILE = ~/bin/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
145 endif
146 ifeq ($(ARCH),i386)
147 CROSS_COMPILE = i386-linux-
148 endif
. . . . . .
173 ifeq ($(ARCH),sparc)
174 CROSS_COMPILE = sparc-elf-
175 endif # sparc
176 endif # HOSTARCH,ARCH
177 endif # CROSS_COMPILE
178
179 export CROSS_COMPILE
4. 실제로 컴파일될 object, library, image 생성 등에 대한 rule
1) 실제 컴파일 및 Link 옵션등에 대한 파일을 Include한다.
2) Object & Library List
이후 컴파일에 사용될 object 및 library list들이 나열된다.
순서가 무척중요하덴다...
3) CPU 관련 object 설정, config.mk에서 정의된 CPU 폴더의 start.s 파일을 컴파일 하게 된다.
188 ifeq ($(CPU),i386)
189 OBJS += cpu/$(CPU)/start16.o
190 OBJS += cpu/$(CPU)/reset.o
191 endif
192 ifeq ($(CPU),ppc4xx)
193 OBJS += cpu/$(CPU)/resetvec.o
194 endif
195 ifeq ($(CPU),mpc85xx)
196 OBJS += cpu/$(CPU)/resetvec.o
197 endif
198
199 OBJS := $(addprefix $(obj),$(OBJS))
4) U-Boot image 생성시 포함될 라이브러리에 대한 설정이다.
각 폴더별로 컴파일하여 라이브러리를 생성한 후 최종적으로 linking하여 image를 만든다.
202 LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
203 "board/$(VENDOR)/common/lib$(VENDOR).a"; fi)
204 LIBS += cpu/$(CPU)/lib$(CPU).a
205 ifdef SOC
206 LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
207 endif
208 ifeq ($(CPU),ixp)
209 LIBS += cpu/ixp/npe/libnpe.a
210 endif
211 LIBS += lib_$(ARCH)/lib$(ARCH).a
212 LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
213 fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
214 LIBS += net/libnet.a
215 LIBS += disk/libdisk.a
216 LIBS += drivers/bios_emulator/libatibiosemu.a
217 LIBS += drivers/block/libblock.a
218 LIBS += drivers/dma/libdma.a
219 LIBS += drivers/hwmon/libhwmon.a
220 LIBS += drivers/i2c/libi2c.a
221 LIBS += drivers/input/libinput.a
222 LIBS += drivers/misc/libmisc.a
223 LIBS += drivers/mmc/libmmc.a
224 LIBS += drivers/mtd/libmtd.a
225 LIBS += drivers/mtd/nand/libnand.a
226 LIBS += drivers/mtd/nand_legacy/libnand_legacy.a
227 LIBS += drivers/mtd/onenand/libonenand.a
228 LIBS += drivers/mtd/spi/libspi_flash.a
229 LIBS += drivers/net/libnet.a
230 LIBS += drivers/net/sk98lin/libsk98lin.a
231 LIBS += drivers/pci/libpci.a
232 LIBS += drivers/pcmcia/libpcmcia.a
233 LIBS += drivers/spi/libspi.a
234 ifeq ($(CPU),mpc83xx)
235 LIBS += drivers/qe/qe.a
236 endif
237 ifeq ($(CPU),mpc85xx)
238 LIBS += drivers/qe/qe.a
239 endif
240 LIBS += drivers/rtc/librtc.a
241 LIBS += drivers/serial/libserial.a
242 LIBS += drivers/usb/libusb.a
243 LIBS += drivers/video/libvideo.a
244 LIBS += common/libcommon.a
245 LIBS += libfdt/libfdt.a
246 LIBS += api/libapi.a
247 LIBS += post/libpost.a
248
249 LIBS := $(addprefix $(obj),$(LIBS))
250 .PHONY : $(LIBS) $(VERSION_FILE)
251
252 LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
253 LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
254
255 # Add GCC lib
256 PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
5) Tools, Example 및 API Example Rule
259 # Don't include stuff already done in $(LIBS)
260 SUBDIRS = tools \
261 examples \
262 api_examples
263
264 .PHONY : $(SUBDIRS)
6) depend, elf, binary등의 생성에 관한 rule 및 각 library들의 생성에 대한 rule
LIBS 들은 각 폴더의 make 파일을 이용하여 다시 컴파일 하도록 되어있다.
267 NAND_SPL = nand_spl
268 U_BOOT_NAND = $(obj)u-boot-nand.bin
269 endif
270
271 ifeq ($(CONFIG_ONENAND_U_BOOT),y)
272 ONENAND_IPL = onenand_ipl
273 U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
274 endif
275
276 __OBJS := $(subst $(obj),,$(OBJS))
277 __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
278
279 #########################################################################
280 #########################################################################
281
282 ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
283 ifeq ($(ARCH),blackfin)
284 ALL += $(obj)u-boot.ldr
285 endif
286
287 all: $(ALL)
288
289 $(obj)u-boot.hex: $(obj)u-boot
290 $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
291
292 $(obj)u-boot.srec: $(obj)u-boot
293 $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
294
295 $(obj)u-boot.bin: $(obj)u-boot
296 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
297
298 $(obj)u-boot.ldr: $(obj)u-boot
299 $(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS)
300
301 $(obj)u-boot.ldr.hex: $(obj)u-boot.ldr
302 $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
303
304 $(obj)u-boot.ldr.srec: $(obj)u-boot.ldr
305 $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
306
307 $(obj)u-boot.img: $(obj)u-boot.bin
308 ./tools/mkimage -A $(ARCH) -T firmware -C none \
309 -a $(TEXT_BASE) -e 0 \
310 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
311 sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
312 -d $< $@
313
314 $(obj)u-boot.sha1: $(obj)u-boot.bin
315 $(obj)tools/ubsha1 $(obj)u-boot.bin
316
317 $(obj)u-boot.dis: $(obj)u-boot
318 $(OBJDUMP) -d $< > $@
319
320 $(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
321 UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
322 sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
323 cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
324 --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
325 -Map u-boot.map -o u-boot
326
327 $(OBJS): depend $(obj)include/autoconf.mk
328 $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
329
330 $(LIBS): depend $(obj)include/autoconf.mk
331 $(MAKE) -C $(dir $(subst $(obj),,$@))
332
333 $(LIBBOARD): depend $(LIBS) $(obj)include/autoconf.mk
334 $(MAKE) -C $(dir $(subst $(obj),,$@))
335
336 $(SUBDIRS): depend $(obj)include/autoconf.mk
337 $(MAKE) -C $@ all
338
339 $(LDSCRIPT): depend $(obj)include/autoconf.mk
340 $(MAKE) -C $(dir $@) $(notdir $@)
341
342 $(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk
343 $(MAKE) -C nand_spl/board/$(BOARDDIR) all
344
345 $(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
346 cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
347
348 $(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk
349 $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
350
351 $(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
352 cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
353 cat $(obj)onenand_ipl/onenand-ipl-4k.bin $(obj)u-boot.bin > $(obj)u-boot-flexonenand.bin
354
355 $(VERSION_FILE):
356 @( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \
357 '$(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion $(TOPDIR))' \
358 ) > $@.tmp
359 @cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@
360
361 gdbtools:
362 $(MAKE) -C tools/gdb all || exit 1
363
364 updater:
365 $(MAKE) -C tools/updater all || exit 1
366
367 env:
368 $(MAKE) -C tools/env all MTD_VERSION=${MTD_VERSION} || exit 1
369
370 depend dep: $(VERSION_FILE)
371 for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done
372
373 TAG_SUBDIRS += include
374 TAG_SUBDIRS += lib_generic board/$(BOARDDIR)
375 TAG_SUBDIRS += cpu/$(CPU)
376 TAG_SUBDIRS += lib_$(ARCH)
377 TAG_SUBDIRS += fs/cramfs
378 TAG_SUBDIRS += fs/fat
379 TAG_SUBDIRS += fs/fdos
380 TAG_SUBDIRS += fs/jffs2
381 TAG_SUBDIRS += net
382 TAG_SUBDIRS += disk
383 TAG_SUBDIRS += common
384 TAG_SUBDIRS += drivers/bios_emulator
385 TAG_SUBDIRS += drivers/block
386 TAG_SUBDIRS += drivers/hwmon
387 TAG_SUBDIRS += drivers/i2c
388 TAG_SUBDIRS += drivers/input
389 TAG_SUBDIRS += drivers/misc
390 TAG_SUBDIRS += drivers/mmc
391 TAG_SUBDIRS += drivers/mtd
392 TAG_SUBDIRS += drivers/mtd/nand
393 TAG_SUBDIRS += drivers/mtd/nand_legacy
394 TAG_SUBDIRS += drivers/mtd/onenand
395 TAG_SUBDIRS += drivers/mtd/spi
396 TAG_SUBDIRS += drivers/net
397 TAG_SUBDIRS += drivers/net/sk98lin
398 TAG_SUBDIRS += drivers/pci
399 TAG_SUBDIRS += drivers/pcmcia
400 TAG_SUBDIRS += drivers/qe
401 TAG_SUBDIRS += drivers/rtc
402 TAG_SUBDIRS += drivers/serial
403 TAG_SUBDIRS += drivers/spi
404 TAG_SUBDIRS += drivers/usb
405 TAG_SUBDIRS += drivers/video
406
407 tags ctags:
408 ctags -w -o $(obj)ctags `find $(SUBDIRS) $(TAG_SUBDIRS) \
409 -name '*.[ch]' -print`
410
411 etags:
412 etags -a -o $(obj)etags `find $(SUBDIRS) $(TAG_SUBDIRS) \
413 -name '*.[ch]' -print`
414 cscope:
415 find $(SUBDIRS) $(TAG_SUBDIRS) -name '*.[ch]' -print \
416 > cscope.files
417 cscope -b -q -k
418
419 $(obj)System.map: $(obj)u-boot
420 @$(NM) $< | \
421 grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
422 sort > $(obj)System.map
7) Auto generate에 관한 부분... 아직은 잘 모르겠다.
425 # Auto-generate the autoconf.mk file (which is included by all makefiles)
426 #
427 # This target actually generates 2 files; autoconf.mk and autoconf.mk.dep.
428 # the dep file is only include in this top level makefile to determine when
429 # to regenerate the autoconf.mk file.
430 $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
431 @$(XECHO) Generating $@ ; \
432 set -e ; \
433 : Generate the dependancies ; \
434 $(CC) -x c -DDO_DEPS_ONLY -M $(HOST_CFLAGS) $(CPPFLAGS) \
435 -MQ $(obj)include/autoconf.mk include/common.h > $@
436
437 $(obj)include/autoconf.mk: $(obj)include/config.h
438 @$(XECHO) Generating $@ ; \
439 set -e ; \
440 : Extract the config macros ; \
441 $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
442 sed -n -f tools/scripts/define2mk.sed > $@
443
444 sinclude $(obj)include/autoconf.mk.dep
8) config.mk를 생성하지 않고 컴파일 할 경우의 rule이다. 암튼 컴파일이 안된다.
:: 3. Cross Compiler 설정 에서 config.mk가 없을 경우 여기로 들어온다.
447 else # !config.mk
448 all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \
449 $(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \
450 $(SUBDIRS) $(VERSION_FILE) gdbtools updater env depend \
451 dep tags ctags etags cscope $(obj)System.map:
452 @echo "System not configured - see README" >&2
453 @ exit 1
454 endif # config.mk
455
456 .PHONY : CHANGELOG
457 CHANGELOG:
458 git log --no-merges U-Boot-1_1_5.. | \
459 unexpand -a | sed -e 's/\s\s*$$//' > $@ 460
461 #########################################################################
9)
- 코드를 처음 다운 받았을 때의 상태로 돌릴 수 있다.
464 @rm -f $(obj)include/config.h $(obj)include/config.mk \
465 $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
466 $(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep
2498 smdk2400_config : unconfig
2499 @$(MKCONFIG) $(@:_config=) arm arm920t smdk2400 NULL s3c24x0
2500
2501 smdk2410_config : unconfig
2502 @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
. . .
11) 최종 라인은 clean 및 clobber 관련 rule이 정의되어 있다. tar.gz로 묶어주는 backup 명령도 있구나. 흠....
3009
3010 clean:
3011 @rm -f $(obj)examples/82559_eeprom $(obj)examples/eepro100_eeprom \
3012 $(obj)examples/hello_world $(obj)examples/interrupt \
3013 $(obj)examples/mem_to_mem_idma2intr \
3014 $(obj)examples/sched $(obj)examples/smc91111_eeprom \
3015 $(obj)examples/test_burst $(obj)examples/timer
3016 @rm -f $(obj)tools/bmp_logo $(obj)tools/easylogo/easylogo \
3017 $(obj)tools/env/{fw_printenv,fw_setenv} \
3018 $(obj)tools/envcrc \
3019 $(obj)tools/gdb/{astest,gdbcont,gdbsend} \
3020 $(obj)tools/gen_eth_addr $(obj)tools/img2srec \
3021 $(obj)tools/mkimage $(obj)tools/mpc86x_clk \
3022 $(obj)tools/ncb $(obj)tools/ubsha1
3023 @rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \
3024 $(obj)board/netstar/{eeprom,crcek,crcit,*.srec,*.bin} \
3025 $(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom \
3026 $(obj)board/{integratorap,integratorcp}/u-boot.lds \
3027 $(obj)board/{bf533-ezkit,bf533-stamp,bf537-stamp,bf561-ezkit}/u-boot.lds \
3028 $(obj)cpu/blackfin/bootrom-asm-offsets.[chs]
3029 @rm -f $(obj)include/bmp_logo.h
3030 @rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
3031 @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
3032 @rm -f $(obj)api_examples/demo $(VERSION_FILE)
3033 @find $(OBJTREE) -type f \
3034 \( -name 'core' -o -name '*.bak' -o -name '*~' \
3035 -o -name '*.o' -o -name '*.a' \) -print \
3036 | xargs rm -f
3037
3038 clobber: clean
3039 @find $(OBJTREE) -type f \( -name .depend \
3040 -o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
3041 -print0 \
3042 | xargs -0 rm -f
3043 @rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
3044 $(obj)cscope.* $(obj)*.*~
3045 @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
3046 @rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
3047 @rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c,zlib.h}
3048 @rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
3049 @rm -f $(obj)cpu/mpc824x/bedbug_603e.c
3050 @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
3051 @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
3052 @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
3053 @[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
3054
3055 ifeq ($(OBJTREE),$(SRCTREE))
3056 mrproper \
3057 distclean: clobber unconfig
3058 else
3059 mrproper \
3060 distclean: clobber unconfig
3061 rm -rf $(obj)*
3062 endif
3063
3064 backup:
3065 F=`basename $(TOPDIR)` ; cd .. ; \
3066 gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
3067
3068 #########################################################################