Build system overhauled to use Kbuild (XCC)
[akaros.git] / Makefile
1 # Top-level Makefile for Akaros
2 # Barret Rhoden
3 #
4 #
5 # Notes:
6 #       - I downloaded the kbuild guts from git://github.com/lacombar/kconfig.git,
7 #       and added things from a recent linux makefile.  It is from aug 2011, so
8 #       some things might not match up.
9 #       - There's still some mysterious bits floating around, such as compile
10 #       parameters like -D"KBUILD_STR(s)=#s" (they come from Makefile.lib).  They
11 #       don't hurt, so I'm not removing them.  We might need them in the future
12 #       too.
13 #       - Kernel output in obj/: So Linux has the ability to output into another
14 #       directory, via the KBUILD_OUTPUT variable.  This induces a recursive make
15 #       in the output directory.  I mucked with it for a little, but didn't get it
16 #       to work quite right.  Also, there will be other Akaros issues since this
17 #       makefile is also used for userspace and tests.  For now, I'm leaving things
18 #       the default Linux way.
19 #
20 # TODO:
21 #       - Connect to kconfig, have it generate our CONFIGS, instead of makelocal.
22 #               - We also want to consider having changes to .config force rebuilds.
23 #               Right now, a change to the CFLAGS (CONFIGS) rebuilds it all.  Ideally,
24 #               we'd only rebuild files that need the change. 
25 #               - CONFIG_ are getting included twice, since we have includes of KCONFIG
26 #               in both Makefile.build and here.
27 #               - Might involve auto.conf{,.cmd} too.
28 #
29 #       - Do we want some sort of default config?  Or the ability to change arches
30 #       and keep common vars?
31 #
32 #       - Review, with an eye for being better about $(srctree).  It might only be
33 #       necessary in this file, if we every do the KBUILD_OUTPUT option
34 #
35 #       - It's a bit crazy that we build symlinks for parlib, instead of it
36 #       managing its own links based on $(ARCH)
37 #
38 #       - Consider using Kbuild to build userspace and tests
39 #
40 #       - There are a few other TODOs sprinkled throughout the makefile.
41
42 # Do not:
43 # o  use make's built-in rules and variables
44 #    (this increases performance and avoids hard-to-debug behaviour);
45 # o  print "Entering directory ...";
46 MAKEFLAGS += -rR --no-print-directory
47
48 # That's our default target when none is given on the command line
49 # This can be overriden with a Makelocal
50 PHONY := all
51 all: akaros-kernel
52
53 # Symlinks
54 # =========================================================================
55 # We have a few symlinks so that code can include <arch/whatever.h>.  This
56 # section builds and maintains those, as best we can.
57 #
58 # When invoking make, we can pass in ARCH=some-arch.  This value gets 'saved'
59 # in the symlink, so that later invocations do not need ARCH=.  If this value
60 # differs from the symlink, it appears like we are changing arches, which
61 # triggers a clean and symlink reconstruction.
62 #
63 # When the user changes from one arch to another, they ought to reconfig, since
64 # many of the CONFIG_ vars will depend on the arch.  If they try anything other
65 # than one of the "non-build-goals" (cleans or configs), we'll abort.
66 #
67 # Make targets that need these symlinks (like building userspace, the kernel,
68 # configs, etc, should depend on symlinks.
69
70 clean-goals := clean mrproper realclean userclean testclean doxyclean objclean
71 non-build-goals := %config $(clean-goals)
72 goals := $(MAKECMDGOALS)
73 ifeq ($(filter $(non-build-goals), $(goals)),)
74 goals-has-build-targets := 1
75 endif
76
77 PHONY += symlinks clean_symlinks
78 clean_symlinks:
79         @-rm -f kern/include/arch kern/boot user/parlib/include/arch
80
81 arch-link := $(notdir $(shell readlink kern/include/arch))
82 valid-arches := $(notdir $(wildcard kern/arch/*))
83
84 ifneq ($(ARCH),)
85
86 ifeq ($(filter $(valid-arches), $(ARCH)),)
87 $(error ARCH $(ARCH) invalid, must be one of: $(valid-arches))
88 endif
89
90 ifneq ($(ARCH),$(arch-link))
91
92 ifeq ($(goals-has-build-targets),1)
93 $(error Attempted to make [$(goals)] while changing ARCH. \
94         You need to make *config.)
95 endif
96
97 symlinks: clean_symlinks clean
98         @echo Making symlinks...
99         $(Q)ln -fs ../arch/$(ARCH) kern/include/arch
100         $(Q)ln -fs arch/$(ARCH)/boot kern/boot
101         $(Q)ln -fs $(ARCH) user/parlib/include/arch
102 else
103 symlinks:
104 endif # ifneq ($(ARCH),$(arch-link))
105
106 else # $(ARCH) is empty
107
108 ifneq ($(arch-link),)
109
110 ARCH := $(arch-link)
111 symlinks:
112
113 else
114
115 # Allow a clean
116 ifeq ($(filter $(clean-goals), $(goals)),)
117 $(error No arch saved or specified.  Make *config with ARCH=arch. \
118         'arch' must be one of: $(valid-arches))
119 endif
120
121 endif # ifneq ($(arch-link),)
122
123 endif # ifeq ($(ARCH),)
124
125 export ARCH
126
127
128 # Init / Include Stuff and Akaros Settings
129 # =========================================================================
130
131 KCONFIG_CONFIG ?= .config
132 export KCONFIG_CONFIG
133 $(KCONFIG_CONFIG): ;
134
135 # The user can override this, though it won't apply for any of the in-tree
136 # kernel build output.  Right now, it's only passed down to tests/
137 OBJDIR ?= obj
138 dummy-1 := $(shell mkdir -p $(OBJDIR)/kern/)
139
140 KERNEL_OBJ := $(OBJDIR)/kern/akaros-kernel
141 CMP_KERNEL_OBJ := $(KERNEL_OBJ).gz
142
143 # TODO: have the KFS paths be determined in .config
144 # Give it a reasonable default path for initramfs to avoid build breakage
145 INITRAMFS_PATHS = kern/kfs
146 FIRST_INITRAMFS_PATH = $(firstword $(INITRAMFS_PATHS))
147
148 export OBJDIR INITRAMFS_PATHS FIRST_INITRAMFS_PATH
149
150 # TODO: replace Makeconfig with .config, and slim down Makelocal
151 # Using fake rules so make doesn't get confused (do not try to remake the file)
152 $(srctree)Makeconfig: ;
153 include $(srctree)Makeconfig
154 $(srctree)Makelocal: ;
155 -include $(srctree)Makelocal
156 -include $(srctree)$(KCONFIG)
157
158 # Some Global Settings (Kbuild stuff)
159 # =========================================================================
160
161 # To put more focus on warnings, be less verbose as default
162 # Use 'make V=1' to see the full commands
163
164 ifeq ("$(origin V)", "command line")
165   KBUILD_VERBOSE = $(V)
166 endif
167 ifndef KBUILD_VERBOSE
168   KBUILD_VERBOSE = 0
169 endif
170
171 srctree         := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
172 objtree         := $(CURDIR)
173
174 export srctree objtree
175
176 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
177           else if [ -x /bin/bash ]; then echo /bin/bash; \
178           else echo sh; fi ; fi)
179
180 HOSTCC       = gcc
181 HOSTCXX      = g++
182 HOSTCFLAGS   = -Wall -Wno-char-subscripts -Wmissing-prototypes \
183                -Wstrict-prototypes -O2 -fomit-frame-pointer
184 HOSTCXXFLAGS = -O2
185 HOSTOBJDUMP  = objdump
186 HOSTOBJCOPY  = objcopy
187
188 export CONFIG_SHELL HOSTCC HOSTCXX HOSTCFLAGS HOSTCXXFLAGS
189 export HOSTOBJDUMP HOSTOBJCOPY
190
191 # Beautify output
192 # ---------------------------------------------------------------------------
193 #
194 # Normally, we echo the whole command before executing it. By making
195 # that echo $($(quiet)$(cmd)), we now have the possibility to set
196 # $(quiet) to choose other forms of output instead, e.g.
197 #
198 #         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
199 #         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
200 #
201 # If $(quiet) is empty, the whole command will be printed.
202 # If it is set to "quiet_", only the short version will be printed. 
203 # If it is set to "silent_", nothing will be printed at all, since
204 # the variable $(silent_cmd_cc_o_c) doesn't exist.
205 #
206 # A simple variant is to prefix commands with $(Q) - that's useful
207 # for commands that shall be hidden in non-verbose mode.
208 #
209 #       $(Q)ln $@ :<
210 #
211 # If KBUILD_VERBOSE equals 0 then the above command will be hidden.
212 # If KBUILD_VERBOSE equals 1 then the above command is displayed.
213
214 ifeq ($(KBUILD_VERBOSE),1)
215   quiet =
216   Q =
217 else
218   quiet=quiet_
219   Q = @
220 endif
221 export quiet Q KBUILD_VERBOSE
222
223 # We need some generic definitions (do not try to remake the file).
224 $(srctree)/scripts/Kbuild.include: ;
225 include $(srctree)/scripts/Kbuild.include
226
227 # Basic helpers built in scripts/
228 PHONY += scripts_basic
229 scripts_basic:
230         $(Q)$(MAKE) $(build)=scripts/basic
231         $(Q)rm -f .tmp_quiet_recordmcount
232
233 config: scripts_basic symlinks FORCE
234         $(Q)$(MAKE) $(build)=scripts/kconfig $@
235
236 %config: scripts_basic symlinks FORCE
237         $(Q)$(MAKE) $(build)=scripts/kconfig $@
238
239 PHONY += scripts
240
241 # Not sure if this needs to depend on the config.  Linux's depends on
242 # include/config/auto.conf include/config/tristate.conf
243 scripts: scripts_basic $(KCONFIG)
244         $(Q)$(MAKE) $(build)=$(@)
245
246
247 # Akaros Build Environment
248 # =========================================================================
249 AKAROSINCLUDE   := \
250                                 -I$(srctree)/kern/arch/ \
251                                 -I$(srctree)/kern/include/
252
253 CROSS_COMPILE := $(ARCH)-ros-
254
255 CC          := $(CROSS_COMPILE)gcc 
256 CPP         := $(CROSS_COMPILE)g++
257 AS          := $(CROSS_COMPILE)as
258 AR          := $(CROSS_COMPILE)ar
259 LD          := $(CROSS_COMPILE)ld
260 OBJCOPY := $(CROSS_COMPILE)objcopy
261 OBJDUMP := $(CROSS_COMPILE)objdump
262 NM          := $(CROSS_COMPILE)nm
263 STRIP   := $(CROSS_COMPILE)strip
264
265 ifeq ($(shell which $(CROSS_COMPILE)gcc 2>/dev/null ),)
266 ifeq ($(goals-has-build-targets),1)
267 $(error Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
268         Be sure to build the cross-compiler and update your PATH)
269 endif
270 else
271 # Computing these without a cross compiler complains loudly
272 gcc-lib := $(shell $(CC) -print-libgcc-file-name)
273 NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
274 # Note: calling this GCC_ROOT interferes with the host tools
275 XCC_ROOT := $(dir $(shell which $(CC)))../
276 endif
277
278 CFLAGS_KERNEL += -O2 -pipe -MD -gstabs
279 CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
280 CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
281 CFLAGS_KERNEL += -fno-stack-protector
282 CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused
283 CFLAGS_KERNEL += -DROS_KERNEL 
284
285 # TODO: do we need this, or can we rely on the compiler's defines?
286 CFLAGS_KERNEL += -D$(ARCH)
287
288 # TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
289 # source of bugs/problems.
290 # note we still pull in stdbool and stddef from the compiler
291 CFLAGS_KERNEL += -fno-builtin
292
293 AFLAGS_KERNEL := $(CFLAGS_KERNEL)
294
295 KBUILD_BUILTIN := 1
296 KBUILD_CHECKSRC := 0
297
298 export AKAROSINCLUDE CROSS_COMPILE
299 export CC CPP AS AR LD OBJCOPY OBJDUMP NM STRIP
300 export CFLAGS_KERNEL AFLAGS_KERNEL
301 export NOSTDINC_FLAGS XCC_ROOT
302 export KBUILD_BUILTIN KBUILD_CHECKSRC
303
304 CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline
305 CXXFLAGS_USER += -O2
306
307 export CFLAGS_USER CXXFLAGS_USER
308
309 # Akaros Kernel Build
310 # =========================================================================
311 # Add top level directories, either to an existing entry (core-y) or to its
312 # own. 
313 #
314 # From these, we determine deps and dirs.  We recursively make through the
315 # dirs, generating built-in.o at each step, which are the deps from which we
316 # link akaros.
317 #
318 # We have all-arch-dirs and all-dirs, so that we can still clean even without
319 # an arch symlink.
320
321 core-y += kern/src/
322 arch-y += kern/arch/$(ARCH)/
323
324 akaros-dirs     := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y)))
325
326 all-arch-dirs   := $(patsubst %,kern/arch/%/,$(valid-arches))
327 akaros-all-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(all-arch-dirs)))
328
329 core-y          := $(patsubst %/, %/built-in.o, $(core-y))
330 arch-y          := $(patsubst %/, %/built-in.o, $(arch-y))
331
332 kbuild_akaros_main := $(core-y) $(arch-y)
333 akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/kernel.ld
334
335 kern_cpio := $(OBJDIR)/kern/initramfs.cpio
336 kern_cpio_obj := $(kern_cpio).o
337 ifneq ($(EXT2_BDEV),)
338 ext2_bdev_obj := $(OBJDIR)/kern/$(shell basename $(EXT2_BDEV)).o
339 endif
340
341 kern_initramfs_files := $(shell mkdir -p $(INITRAMFS_PATHS); \
342                           find $(INITRAMFS_PATHS))
343
344 $(kern_cpio) initramfs: $(kern_initramfs_files)
345         @echo "  Building initramfs:"
346         @if [ "$(INITRAMFS_BIN)" != "" ]; then \
347         sh $(INITRAMFS_BIN); \
348     fi
349         $(Q)for i in $(INITRAMFS_PATHS); do cd $$i; \
350         echo "    Adding $$i to initramfs..."; \
351         find -L . | cpio --quiet -oH newc > \
352                         $(CURDIR)/$(kern_cpio); \
353         cd $$OLDPWD; \
354     done;
355
356 ld_emulation := $(shell $(HOSTOBJDUMP) -i | grep -v BFD | grep ^[a-z] |head -n1)
357 ld_arch := $(shell $(HOSTOBJDUMP) -i | grep -v BFD | grep "^  [a-z]" | head -n1)
358
359 $(kern_cpio_obj): $(kern_cpio)
360         $(Q)$(HOSTOBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@
361
362 $(ext2_bdev_obj): $(EXT2_BDEV)
363         $(Q)$(HOSTOBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@
364
365 quiet_cmd_link-akaros = LINK    $@
366       cmd_link-akaros = $(LD) -T kern/arch/$(ARCH)/kernel.ld -o $@ \
367                               $(akaros-deps) \
368                               $(gcc-lib) \
369                               $(kern_cpio_obj) \
370                               $(ext2_bdev_obj) ; \
371                               $(OBJDUMP) -S $@ > $@.asm
372
373 # For some reason, the if_changed doesn't work with FORCE (like it does in
374 # Linux).  It looks like it can't find the .cmd file or something (also
375 # complaints of $(targets), so that all is probably messed up).
376 $(KERNEL_OBJ): $(akaros-deps) $(kern_cpio_obj) $(ext2_bdev_obj)
377         $(call if_changed,link-akaros)
378
379 akaros-kernel: $(KERNEL_OBJ)
380
381 $(sort $(akaros-deps)): $(akaros-dirs) ;
382
383 # Recursively Kbuild all of our directories.  If we're changing arches
384 # mid-make, we might have issues ( := on akaros-dirs, etc).
385 PHONY += $(akaros-dirs)
386 $(akaros-dirs): scripts symlinks
387         $(Q)$(MAKE) $(build)=$@
388
389 $(CMP_KERNEL_OBJ): $(KERNEL_OBJ)
390         @echo "Compressing kernel image"
391         $(Q)gzip -c $^ > $@
392
393
394 # Akaros Userspace Building and Misc Helpers
395 # =========================================================================
396 # Recursively make user libraries and tests.
397 #
398 # User library makefiles are built to expect to be called from their own
399 # directories.  The test code can be called from the root directory.
400
401 # List all userspace directories here, and state any dependencies between them,
402 # such as how pthread depends on parlib.
403
404 user-dirs = parlib pthread benchutil
405 pthread: parlib
406
407 ifeq ($(ARCH),i686)
408 user-dirs += c3po
409 c3po: parlib
410 endif
411
412 PHONY += install-libs $(user-dirs)
413 install-libs: $(user-dirs) symlinks
414
415 $(user-dirs):
416         @cd user/$@ && $(MAKE) && $(MAKE) install
417
418
419 PHONY += userclean $(clean-user-dirs)
420 clean-user-dirs := $(addprefix _clean_user_,$(user-dirs))
421 userclean: $(clean-user-dirs) testclean
422
423 $(clean-user-dirs):
424         @cd user/$(patsubst _clean_user_%,%,$@) && $(MAKE) clean
425
426 tests/: tests
427 tests: install-libs
428         @$(MAKE) -f tests/Makefile
429
430 testclean:
431         @$(MAKE) -f tests/Makefile clean
432
433 install-tests:
434         @$(MAKE) -f tests/Makefile install
435
436 # TODO: cp -u all of the .sos, but flush it on an arch change (same with tests)
437 fill-kfs: install-libs install-tests
438         @mkdir -p $(FIRST_INITRAMFS_PATH)/lib
439         @cp $(addprefix $(XCC_ROOT)/$(ARCH)-ros/lib/, \
440           libc.so.6 ld.so.1 libm.so libgcc_s.so.1) $(FIRST_INITRAMFS_PATH)/lib
441         $(Q)$(STRIP) --strip-debug $(addprefix $(FIRST_INITRAMFS_PATH)/lib/, \
442                                                libc.so.6 ld.so.1)
443
444 # Use doxygen to make documentation for ROS (Untested since 2010 or so)
445 doxygen-dir := $(CUR_DIR)/Documentation/doxygen
446 docs: 
447         @echo "  Making doxygen"
448         @doxygen-dir=$(doxygen-dir) doxygen $(doxygen-dir)/rosdoc.cfg
449         @if [ ! -d $(doxygen-dir)/rosdoc/html/img ]; \
450          then \
451                 ln -s ../../img $(doxygen-dir)/rosdoc/html; \
452          fi
453
454 doxyclean:
455         @echo + clean [ROSDOC]
456         @rm -rf $(doxygen-dir)/rosdoc
457
458 objclean:
459         @echo + clean [OBJDIR]
460         @rm -rf $(OBJDIR)/*
461
462 realclean: userclean mrproper doxyclean objclean
463
464 # Cleaning
465 # =========================================================================
466 # This is mostly the Linux kernel cleaning.  We could hook in to the userspace
467 # cleaning with the 'userclean' target attached to clean, though historically
468 # 'clean' means the kernel.
469
470 # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
471 # Usage:
472 # $(Q)$(MAKE) $(clean)=dir
473 clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
474
475 # clean - Delete all generated files
476 #
477 clean-dirs         := $(addprefix _clean_,$(akaros-all-dirs))
478
479 PHONY += $(clean-dirs) clean
480 $(clean-dirs):
481         $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
482
483 RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
484                    -o -name .pc -o -name .hg -o -name .git \) -prune -o
485 clean: $(clean-dirs)
486         @find $(patsubst _clean_%,%,$(clean-dirs)) $(RCS_FIND_IGNORE) \
487             \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
488             -o -name '*.ko.*' \
489             -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
490             -o -name '*.symtypes' -o -name 'modules.order' \
491             -o -name modules.builtin -o -name '.tmp_*.o.*' \
492             -o -name '*.gcno' \) -type f -print | xargs rm -f
493
494 # Could add in an archclean if we need arch-specific cleanup, or a userclean if
495 # we want to start cleaning that too.
496 #clean: archclean
497 #clean: userclean
498
499 # mrproper - Delete all generated files, including .config, and reset ARCH
500 #
501 mrproper-dirs      := $(addprefix _mrproper_,scripts)
502
503 PHONY += $(mrproper-dirs) mrproper
504 $(mrproper-dirs):
505         $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
506
507 mrproper: $(mrproper-dirs) clean clean_symlinks
508         @-rm -f .config
509         @find $(patsubst _mrproper_%,%,$(mrproper-dirs)) $(RCS_FIND_IGNORE) \
510             \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
511             -o -name '*.ko.*' \
512             -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
513             -o -name '*.symtypes' -o -name 'modules.order' \
514             -o -name modules.builtin -o -name '.tmp_*.o.*' \
515             -o -name '*.gcno' \) -type f -print | xargs rm -f
516
517 # Epilogue
518 # =========================================================================
519
520 PHONY += FORCE
521 FORCE:
522
523 # Declare the contents of the .PHONY variable as phony.  We keep that
524 # information in a variable so we can use it in if_changed and friends.
525 .PHONY: $(PHONY)