-#
-# This makefile system follows the structuring conventions
-# recommended by Peter Miller in his excellent paper:
-#
-# Recursive Make Considered Harmful
-# http://aegis.sourceforge.net/auug97.pdf
-#
+# The ROS Top level Makefile
+# Make sure that 'all' is the first target
+
+#############################################################################
+########## Initial Setup so that we can build for different TARGETS #########
+#############################################################################
+
+ARCH_LINK := $(shell readlink kern/include/arch)
+ifneq ($(ARCH_LINK),)
+ ARCH_LINK := $(shell basename $(ARCH_LINK))
+ TARGET_ARCH ?= $(ARCH_LINK)
+endif
+ifeq ($(TARGET_ARCH),)
+busted:
+ @echo "You must initially specify your target in the form TARGET_ARCH=<target>"
+ @echo "Current valid values for TARGET_ARCH are 'i686' and 'sparc'"
+ @echo "Subsequent calls for the same target can be made by simply invoking 'make'"
+endif
+$(TARGET_ARCH):
+ @if [ "$(ARCH_LINK)" != "$@" ];\
+ then\
+ $(MAKE) realclean;\
+ $(MAKE) realall -j $(MAKE_JOBS);\
+ else\
+ $(MAKE) all -j $(MAKE_JOBS);\
+ fi
+
+#############################################################################
+########## Beginning of the guts of the real Makefile #######################
+#############################################################################
+
+# Default values for configurable Make system variables
+COMPILER := GCC
OBJDIR := obj
+V := @
-# Make sure that 'all' is the first target
-all: symlinks
+# Make sure that 'all' is the first target when not erroring out
+realall: symlinks
+
+# Number of make jobs to spawn. Define it in Makelocal
+MAKE_JOBS :=
-# User defined constants passed on the command line
-TARGET_ARCH := i386
-COMPILER := IVY
+# Give it a reasonable default path for initramfs to avoid build breakage
+INITRAMFS_PATHS = kern/kfs
+# Then grab the users Makelocal file to let them override Make system variables
+# and set up other Make targets
+include Makeconfig
-include Makelocal
-TOP_DIR := .
+TOP_DIR := $(shell pwd)
ARCH_DIR := $(TOP_DIR)/kern/arch
INCLUDE_DIR := $(TOP_DIR)/kern/include
+DOXYGEN_DIR := $(TOP_DIR)/Documentation/doxygen
UNAME=$(shell uname -m)
-V = @
# Cross-compiler ros toolchain
#
# This Makefile will automatically use the cross-compiler toolchain
-# installed as 'i386-ros-*', if one exists. If the host tools ('gcc',
-# 'objdump', and so forth) compile for a 32-bit x86 ELF target, that will
+# installed as '$(TARGET_ARCH)-ros-*', if one exists. If the host tools ('gcc',
+# 'objdump', and so forth) compile for a 32-bit ELF target, that will
# be detected as well. If you have the right compiler toolchain installed
# using a different name, set GCCPREFIX explicitly in your Makelocal file
-# try to infer the correct GCCPREFIX
+# Try to infer the correct GCCPREFIX
+ifneq ($(TARGET_ARCH),)
ifndef GCCPREFIX
-GCCPREFIX := $(shell if i386-ros-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
- then echo 'i386-ros-'; \
- elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
- then echo ''; \
- else echo "***" 1>&2; \
- echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
- echo "*** Is the directory with i386-ros-gcc in your PATH?" 1>&2; \
- echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
- echo "*** prefix other than 'i386-ros-', set your GCCPREFIX" 1>&2; \
- echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
- echo "*** To turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \
- echo "***" 1>&2; exit 1; fi)
+TEST_PREFIX := $(TARGET_ARCH)-ros-
+else
+TEST_PREFIX := $(GCCPREFIX)
+endif
+GCC_EXISTS = $(shell which $(TEST_PREFIX)gcc)
+ifneq ($(GCC_EXISTS),)
+ GCCPREFIX := $(TEST_PREFIX)
+else
+ ERROR := "*** Error: Couldn't find $(TEST_PREFIX) version of GCC/binutils."
+endif
+ifdef ERROR
+error:
+ @echo $(ERROR)
+ @exit 1
+else
+error:
+endif
endif
# Default programs for compilation
+USER_CFLAGS += -O2
ifeq ($(COMPILER),IVY)
-KERN_CFLAGS := --deputy\
- --no-rc-sharc\
- --sc-dynamic-is-error\
- --sc-ops=$(INCLUDE_DIR)/ivy/sharc.h\
- --sc-all-in-thread\
- --enable-precompile\
-# --enable-error-db\
-
-USER_CFLAGS := --deputy --enable-error-db
+KERN_CFLAGS += --deputy \
+ --no-rc-sharc \
+ --sc-dynamic-is-error \
+ --sc-ops=$(INCLUDE_DIR)/ivy/sharc.h \
+ --sc-all-in-thread \
+ --enable-precompile \
+# --enable-error-db \
+
+USER_CFLAGS += --deputy --enable-error-db
CC := ivycc --gcc=$(GCCPREFIX)gcc
else
CC := $(GCCPREFIX)gcc
OBJCOPY := $(GCCPREFIX)objcopy
OBJDUMP := $(GCCPREFIX)objdump
NM := $(GCCPREFIX)nm
+STRIP := $(GCCPREFIX)strip
PERL := perl
EXTRAARGS ?= -std=gnu99 -Wno-attributes -fno-stack-protector -fgnu89-inline
+# GCC Library path
+ifneq ($(GCC_EXISTS),)
+GCC_LIB := $(shell $(CC) -print-libgcc-file-name)
+endif
+
# Universal compiler flags
# -fno-builtin is required to avoid refs to undefined functions in the kernel.
# Only optimize to -O1 to discourage inlining, which complicates backtraces.
-CFLAGS := $(CFLAGS) -D$(TARGET_ARCH) $(EXTRAARGS)
-CFLAGS += -O2 -pipe -MD -fno-builtin -gstabs
-CFLAGS += -Wall -Wno-format -Wno-unused -fno-strict-aliasing
-#CFLAGS += -nostdinc -Igccinclude/$(TARGET_ARCH)
+KERN_CFLAGS += -D$(TARGET_ARCH) $(EXTRAARGS)
+KERN_CFLAGS += -O2 -pipe -MD -fno-builtin -gstabs
+KERN_CFLAGS += -Wall -Wno-format -Wno-unused -fno-strict-aliasing
+KERN_CFLAGS += -nostdinc -I$(dir $(GCC_LIB))/include
# Universal loader flags
LDFLAGS := -nostdlib
-# GCC Library path
-ifneq ($(shell which $(CC)),)
-GCC_LIB := $(shell $(CC) -print-libgcc-file-name)
-endif
-
# List of directories that the */Makefrag makefile fragments will add to
OBJDIRS :=
+# List of directories that the */Makefrag makefile fragments will add to
+ROS_USER_LIBS :=
+
ROS_ARCH_DIR ?= $(TARGET_ARCH)
-symlinks-remove:
- @rm -rf kern/include/arch
- @rm -rf kern/boot
-symlinks: symlinks-remove
- @ln -s ../arch/$(ROS_ARCH_DIR)/ kern/include/arch
- @ln -s arch/$(ROS_ARCH_DIR)/boot/ kern/boot
+arch:
+ @echo "TARGET_ARCH=$(TARGET_ARCH)"
+
+symlinks: error
+ ln -fs ../arch/$(ROS_ARCH_DIR) kern/include/arch
+ ln -fs arch/$(ROS_ARCH_DIR)/boot kern/boot
+ ln -fs $(ROS_ARCH_DIR) user/include/arch
+ @$(MAKE) -j $(MAKE_JOBS) all
# Include Makefrags for subdirectories
+ifneq ($(TARGET_ARCH),)
include user/Makefrag
+include tests/Makefrag
include kern/Makefrag
+endif
+
+ifeq ($(GCCPREFIX),$(TARGET_ARCH)-ros-)
+GCC_ROOT := $(shell which $(GCCPREFIX)gcc | xargs dirname)/../
+tests/: tests
+tests:
+ @$(MAKE) -j $(MAKE_JOBS) realtests
+realtests: $(TESTS_EXECS)
+# No longer automatically copying to the FS dir (deprecated)
+# @mkdir -p fs/$(TARGET_ARCH)/tests
+# cp -R $(OBJDIR)/$(TESTS_DIR)/* $(TOP_DIR)/fs/$(TARGET_ARCH)/tests
+
+install-libs: $(ROS_USER_LIBS)
+ cp $(ROS_USER_LIBS) $(GCC_ROOT)/$(TARGET_ARCH)-ros/lib
+ cp $(ROS_USER_LIBS) $(TOP_DIR)/fs/$(TARGET_ARCH)/lib
+ cp -R $(USER_DIR)/include/* $(GCC_ROOT)/$(TARGET_ARCH)-ros/include
+.PHONY: tests
+endif
# Eliminate default suffix rules
.SUFFIXES:
# Use doxygen to make documentation for ROS
docs:
- @doxygen doc/rosdoc.cfg
- @if [ ! -d doc/rosdoc/html/img ]; \
- then \
- ln -s ../../img doc/rosdoc/html; \
+ @DOXYGEN_DIR=$(DOXYGEN_DIR) doxygen $(DOXYGEN_DIR)/rosdoc.cfg
+ @if [ ! -d $(DOXYGEN_DIR)/rosdoc/html/img ]; \
+ then \
+ ln -s ../../img $(DOXYGEN_DIR)/rosdoc/html; \
fi
doxyclean:
- rm -rf doc/rosdoc
-
-augment-gcc: symlinks
- scripts/augment-gcc $(dir $(shell which $(CC))).. $(TARGET_ARCH)
+ rm -rf $(DOXYGEN_DIR)/rosdoc
# For deleting the build
+userclean:
+ @rm -rf $(OBJDIR)/user
+
clean:
@rm -rf $(OBJDIR)
+ @echo All clean and pretty!
+
+realclean: clean
@rm -f kern/boot
@rm -f kern/include/arch
- @echo All clean and pretty!
+ @rm -f user/include/arch
always:
@: