mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Imported Genode release 11.11
This commit is contained in:
committed by
Christian Helmuth
parent
6bcc9aef0e
commit
da4e1feaa5
50
tool/README
Normal file
50
tool/README
Normal file
@@ -0,0 +1,50 @@
|
||||
This directory contains tools for managing and using the source code
|
||||
of Genode.
|
||||
|
||||
:'create_builddir'
|
||||
|
||||
The 'create_builddir' tool provides a convenient way to create build
|
||||
directories for different platforms. Its usage information is printed when
|
||||
starting the tool without arguments.
|
||||
|
||||
:'builddir/':
|
||||
|
||||
This directory contains a Makefile template and configuration snippets used
|
||||
by the 'create_builddir' tool.
|
||||
|
||||
:'tool_chain':
|
||||
|
||||
This tool downloads, builds, and installs the tool chain needed to build the
|
||||
Genode OS Framework. For getting usage information, start the tool without
|
||||
arguments.
|
||||
|
||||
:'create_iso':
|
||||
|
||||
This simple tool helps to build bootable ISO images from your build of
|
||||
Genode. For getting usage information, start the tool without arguments.
|
||||
|
||||
:'beautify':
|
||||
|
||||
Beautify is a coding-style checking tool that analyzes source code for its
|
||||
adherence to Genode's coding style as described in 'doc/coding_style.txt'.
|
||||
Whenever possible, the tool tries to fix the issues and outputs a corrected
|
||||
file. Some corrections, however, require human interaction. In this case,
|
||||
the tool stops the analysis with an error.
|
||||
|
||||
:'parse_cxx':
|
||||
|
||||
This tool is a C++ parser used as front-end for Beautify.
|
||||
|
||||
:'fix_include_ifndef':
|
||||
|
||||
This tool helps with assigning consistent include guards to header files.
|
||||
|
||||
:'boot':
|
||||
|
||||
This directory contains boot-loader files needed to create boot images.
|
||||
|
||||
:'autopilot':
|
||||
|
||||
Autopilot is a tool for the automatic execution of run scripts among multiple
|
||||
base platforms.
|
||||
|
||||
360
tool/autopilot
Executable file
360
tool/autopilot
Executable file
@@ -0,0 +1,360 @@
|
||||
#!/usr/bin/tclsh
|
||||
|
||||
#
|
||||
# \brief Automated exection of test cases
|
||||
# \author Norman Feske
|
||||
# \date 2011-07-2
|
||||
#
|
||||
# The autopilot utility automates the process of executing multiple run
|
||||
# scripts on different platforms. For each executed run script, the exit
|
||||
# value is checked and the result gets logged to a file.
|
||||
#
|
||||
|
||||
##
|
||||
# Execute 'func' for each command line argument of type 'tag'
|
||||
#
|
||||
proc foreach_cmdline_arg { tag func } {
|
||||
global argv
|
||||
set re "(\\s|^)-$tag\\s*(\[^\\s\]+)"
|
||||
set args $argv
|
||||
while {[regexp -- $re $args dummy dummy $tag]} {
|
||||
eval $func
|
||||
regsub -- $re $args "" args
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Determine base directory of genode source tree based on the known location of
|
||||
# the 'autopilot' tool within the tree
|
||||
#
|
||||
proc genode_dir { } {
|
||||
global argv0;
|
||||
return [file dirname [file dirname $argv0]]
|
||||
}
|
||||
|
||||
|
||||
proc default_test_dir { } { global env; return "/tmp/autopilot.$env(USER)" }
|
||||
proc default_log_file { } { return "autopilot.log" }
|
||||
|
||||
|
||||
##
|
||||
# Present usage information
|
||||
#
|
||||
proc help { } {
|
||||
|
||||
set help_text {
|
||||
Automatically execute test cases on different platforms
|
||||
|
||||
usage: autopilot -p <platform> ... [-r <run-script> ...]
|
||||
[-d <test-dir>] [-j <make-jobs>]
|
||||
[--help] [--cleanup] [--force]
|
||||
[--stdout] [--skip-clean-rules]
|
||||
[--enable-ccache]
|
||||
|
||||
--force replace test directory if it already exists
|
||||
--cleanup remove test directory at exit
|
||||
--stdout print test output instead of writing log files
|
||||
--skip-clean-rules skip cleanall tests, keep build-directory content
|
||||
--enable-ccache use ccache instead of plain gcc
|
||||
}
|
||||
|
||||
append help_text "\ndefault test directory is [default_test_dir]\n"
|
||||
|
||||
regsub -all {\n\t\t} $help_text "\n" help_text
|
||||
|
||||
puts $help_text
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return true if command-line switch was specified
|
||||
#
|
||||
proc get_cmd_switch { arg_name } {
|
||||
global argv
|
||||
return [expr [lsearch $argv $arg_name] >= 0]
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Remove test directory
|
||||
#
|
||||
proc wipe_test_dir { } {
|
||||
global test_dir
|
||||
exec rm -rf $test_dir
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Remove build artifacts if commanded via the '--cleanup' argument
|
||||
#
|
||||
proc cleanup { } {
|
||||
if {[get_cmd_switch --cleanup]} {
|
||||
puts "cleaning up $test_dir"
|
||||
wipe_test_dir
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Abort execution with a message and an error code
|
||||
#
|
||||
proc fail { message error_code } {
|
||||
cleanup
|
||||
puts stderr "Error: $message"
|
||||
exit $error_code
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return build directory used for the specified platform
|
||||
#
|
||||
proc build_dir { platform } {
|
||||
global test_dir
|
||||
return [file join $test_dir $platform]
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return name of log file for test of 'run_script' on 'platform'
|
||||
#
|
||||
proc log_file { platform run_script } {
|
||||
global test_dir
|
||||
return [file join $test_dir $platform.$run_script.log]
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return file descriptor for writing the log output of test case
|
||||
#
|
||||
proc log_fd { platform run_script } {
|
||||
|
||||
# if '--stdout' was specified, don't write log output to files
|
||||
if {[get_cmd_switch --stdout]} { return stdout }
|
||||
|
||||
# create file descriptor of log file on demand
|
||||
global _log_fds
|
||||
if {![info exists _log_fds($platform,$run_script)]} {
|
||||
set new_fd [open [log_file $platform $run_script] "WRONLY CREAT TRUNC"]
|
||||
set _log_fds($platform,$run_script) $new_fd
|
||||
}
|
||||
return $_log_fds($platform,$run_script)
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Close file descriptor used for log output of test case
|
||||
#
|
||||
proc close_log_fd { platform run_script } {
|
||||
global _log_fds
|
||||
if {[info exists _log_fds($platform,$run_script)]} {
|
||||
close $_log_fds($platform,$run_script)
|
||||
unset _log_fds($platform,$run_script)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Execute single run script for specified platform
|
||||
#
|
||||
# \return true if run script succeeded
|
||||
#
|
||||
proc execute_run_script { platform run_script } {
|
||||
|
||||
set return_value true
|
||||
set fd [log_fd $platform $run_script]
|
||||
|
||||
if {[catch {
|
||||
exec make -C [build_dir $platform] [file join run $run_script] >@ $fd
|
||||
}]} {
|
||||
set return_value false
|
||||
}
|
||||
|
||||
close_log_fd $platform $run_script
|
||||
return $return_value
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Clean build directory
|
||||
#
|
||||
# \return list of unexpected files remaining after 'make cleanall'
|
||||
#
|
||||
proc clean_build_dir { platform } {
|
||||
set fd [log_fd $platform cleanall]
|
||||
|
||||
# make returns the exit code 2 on error
|
||||
if {[catch {
|
||||
exec make -C [build_dir $platform] cleanall >@ $fd
|
||||
}] == 2} {
|
||||
close_log_fd $platform cleanall
|
||||
return [list "clean rule terminated abnormally"]
|
||||
}
|
||||
close_log_fd $platform cleanall
|
||||
|
||||
set remainings [split [exec sh -c "cd [build_dir $platform]; find . -mindepth 1"] "\n"]
|
||||
|
||||
set unexpected { }
|
||||
foreach r $remainings {
|
||||
if {$r == "./etc"} continue
|
||||
if {$r == "./Makefile"} continue
|
||||
if {[regexp {\.\/etc\/.*} $r dummy]} continue
|
||||
lappend unexpected "unexpected: $r"
|
||||
}
|
||||
return $unexpected
|
||||
}
|
||||
|
||||
|
||||
proc build_failed_because_of_missing_run_script { platform run_script } {
|
||||
|
||||
# we cannot inspect any logfile when --stdout was used
|
||||
if {[get_cmd_switch --stdout]} { return 0 }
|
||||
|
||||
# grep log output for the respective error message of the build system
|
||||
if {[catch {
|
||||
exec grep "^Error: No run script for" [log_file $platform $run_script]
|
||||
}]} { return 0 }
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Collect command-line arguments
|
||||
#
|
||||
|
||||
set platforms { }
|
||||
foreach_cmdline_arg p { global platforms; lappend platforms $p }
|
||||
|
||||
set run_scripts { }
|
||||
foreach_cmdline_arg r { global run_scripts; lappend run_scripts $r }
|
||||
|
||||
set test_dir [default_test_dir]
|
||||
foreach_cmdline_arg d { global test_dir; set test_dir $d }
|
||||
|
||||
set make_jobs 2
|
||||
foreach_cmdline_arg j { global make_jobs; set make_jobs $j }
|
||||
|
||||
# present help if explicitly requested
|
||||
if {[get_cmd_switch --help]} { help; exit 0 }
|
||||
|
||||
# present help if arguments do not suffice
|
||||
if {![llength $platforms]} {
|
||||
puts stderr "Error: invalid arguments"
|
||||
help
|
||||
exit -1
|
||||
}
|
||||
|
||||
# print information about the parameters
|
||||
puts "genode dir : [genode_dir]"
|
||||
puts "platforms : $platforms"
|
||||
puts "run scripts : $run_scripts"
|
||||
puts "test dir : $test_dir"
|
||||
puts "make -j : $make_jobs"
|
||||
|
||||
|
||||
#
|
||||
# We first create all build directory for all platforms to back out early if
|
||||
# any error occurs during the creation of build directories due to wrong
|
||||
# command-line arguments.
|
||||
#
|
||||
|
||||
if {[file exists $test_dir] && ![get_cmd_switch --force]} {
|
||||
puts stderr "Error: test directory $test_dir already exists"
|
||||
exit -3
|
||||
}
|
||||
|
||||
|
||||
if {[get_cmd_switch --force]} { wipe_test_dir }
|
||||
|
||||
|
||||
# create build directories
|
||||
foreach platform $platforms {
|
||||
|
||||
if {[catch {
|
||||
exec [genode_dir]/tool/create_builddir $platform BUILD_DIR=[build_dir $platform]
|
||||
}]} {
|
||||
fail "create_builddir for platform $platform failed" -1
|
||||
}
|
||||
|
||||
set build_conf [file join [build_dir $platform] etc build.conf]
|
||||
if {![file exists $build_conf]} {
|
||||
fail "build dir for $platform lacks 'etc/build.conf' file" -2
|
||||
}
|
||||
|
||||
# enable all repositories
|
||||
exec sed -i "/^#REPOSITORIES/s/^#//" $build_conf
|
||||
|
||||
# enable parallel build
|
||||
exec echo "MAKE += -j$make_jobs" >> $build_conf
|
||||
|
||||
# optionally enable ccache
|
||||
if {[get_cmd_switch --enable-ccache]} {
|
||||
set tools_conf [file join [build_dir $platform] etc tools.conf]
|
||||
exec echo "CUSTOM_CC = ccache \$(CROSS_DEV_PREFIX)gcc" >> $tools_conf
|
||||
exec echo "CUSTOM_CXX = ccache \$(CROSS_DEV_PREFIX)g++" >> $tools_conf
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Revisit each platform's build directory and execute all test cases
|
||||
#
|
||||
|
||||
|
||||
##
|
||||
# Print label identifying the specified test case to stderr
|
||||
#
|
||||
proc print_step_label { platform step } {
|
||||
puts -nonewline stderr "[format {%-20s} $platform:] [format {%-20s} $step] "
|
||||
}
|
||||
|
||||
|
||||
# default exit value used if all tests went successfully
|
||||
set exit_value 0
|
||||
|
||||
|
||||
# execute run scripts
|
||||
foreach platform $platforms {
|
||||
|
||||
puts stderr "\n--- platform $platform ---"
|
||||
|
||||
foreach run_script $run_scripts {
|
||||
print_step_label $platform $run_script
|
||||
if {[execute_run_script $platform $run_script]} {
|
||||
puts stderr "-> OK"
|
||||
} else {
|
||||
|
||||
if {[build_failed_because_of_missing_run_script $platform $run_script]} {
|
||||
puts stderr "-> UNAVAILABLE"
|
||||
} else {
|
||||
puts stderr "-> ERROR"
|
||||
set exit_value -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if {[get_cmd_switch --skip-clean-rules]} continue
|
||||
|
||||
# execute and validate cleanall rule
|
||||
print_step_label $platform cleanall
|
||||
set pollution [clean_build_dir $platform]
|
||||
if {[llength $pollution] == 0} {
|
||||
puts stderr "-> OK"
|
||||
} else {
|
||||
puts stderr "-> ERROR"
|
||||
set exit_value -1
|
||||
foreach p $pollution { puts stderr " $p" }
|
||||
}
|
||||
}
|
||||
|
||||
proc concluding_message { } {
|
||||
global exit_value
|
||||
if {$exit_value == 0} { return "everything ok" }
|
||||
return "errors occurred"
|
||||
}
|
||||
|
||||
puts stderr "--- done ([concluding_message]) ---"
|
||||
|
||||
cleanup
|
||||
|
||||
exit $exit_value
|
||||
1770
tool/beautify
Executable file
1770
tool/beautify
Executable file
File diff suppressed because it is too large
Load Diff
BIN
tool/boot/chain.c32
Normal file
BIN
tool/boot/chain.c32
Normal file
Binary file not shown.
BIN
tool/boot/isolinux.bin
Normal file
BIN
tool/boot/isolinux.bin
Normal file
Binary file not shown.
5
tool/boot/isolinux.cfg
Normal file
5
tool/boot/isolinux.cfg
Normal file
@@ -0,0 +1,5 @@
|
||||
DEFAULT grub
|
||||
|
||||
LABEL grub
|
||||
KERNEL chain.c32
|
||||
APPEND grub=/boot/grub/stage2_eltorito
|
||||
BIN
tool/boot/stage2_eltorito
Normal file
BIN
tool/boot/stage2_eltorito
Normal file
Binary file not shown.
280
tool/builddir/build.mk
Normal file
280
tool/builddir/build.mk
Normal file
@@ -0,0 +1,280 @@
|
||||
#
|
||||
# \brief Front end to the Genode build system
|
||||
# \author Norman Feske
|
||||
# \date 2011-08-04
|
||||
#
|
||||
|
||||
#
|
||||
# The operation of the build system can be tuned using the following variables,
|
||||
# which can be specified at the command line or supplied via the
|
||||
# 'etc/build.conf' file.
|
||||
#
|
||||
# BASE_DIR - this directory points to Genode's 'base' repository
|
||||
# REPOSITORIES - list of directories incorporared into the build process
|
||||
# VERBOSE - variable that controls the verboseness of the build process
|
||||
#
|
||||
# By default, compiler messages are not displayed. If you are
|
||||
# interested in these messages set this variable to nothing.
|
||||
# ('VERBOSE=')
|
||||
#
|
||||
# VERBOSE_MK - variable that controls the verboseness of make invocations
|
||||
# VERBOSE_DIR - variable that controls the verboseness of changing directories
|
||||
#
|
||||
# Using this variable, you can enable the make messages printed
|
||||
# when changing directories. To enable the messages, set the
|
||||
# variable to nothing.
|
||||
#
|
||||
# LIB_CACHE_DIR - location of the library build cache
|
||||
#
|
||||
# This variable defines the place for the library build cache.
|
||||
# Normally, the libcache is located at 'var/libcache' and
|
||||
# there is no need to change it.
|
||||
#
|
||||
|
||||
##
|
||||
## Define global configuration variables
|
||||
##
|
||||
|
||||
-include etc/build.conf
|
||||
|
||||
PWD := $(shell pwd)
|
||||
BUILD_BASE_DIR := $(PWD)
|
||||
INSTALL_DIR := $(PWD)/bin
|
||||
|
||||
export BASE_DIR ?= ../base
|
||||
export REPOSITORIES ?= $(BASE_DIR:%base=%base-linux) $(BASE_DIR)
|
||||
export VERBOSE ?= @
|
||||
export VERBOSE_DIR ?= --no-print-directory
|
||||
export VERBOSE_MK ?= @
|
||||
export LIB_CACHE_DIR ?= $(BUILD_BASE_DIR)/var/libcache
|
||||
export LIB_PROGRESS_LOG ?= $(BUILD_BASE_DIR)/progress.log
|
||||
export LIB_DEP_FILE ?= var/libdeps
|
||||
export ECHO ?= echo -e
|
||||
|
||||
#
|
||||
# Convert user-defined directories to absolute directories
|
||||
#
|
||||
# The 'echo' shell command expands '~' characters to the home directory,
|
||||
# 'realpath' converts relative path names to absolute.
|
||||
#
|
||||
REPOSITORIES := $(realpath $(shell echo $(REPOSITORIES)))
|
||||
BASE_DIR := $(realpath $(shell echo $(BASE_DIR)))
|
||||
|
||||
#
|
||||
# Configure shell program before executing any shell commands. On Ubuntu the
|
||||
# standard shell is dash, which breaks colored output via its built-in echo
|
||||
# command.
|
||||
#
|
||||
export SHELL := $(shell which bash)
|
||||
|
||||
select_from_repositories = $(firstword $(foreach REP,$(REPOSITORIES),$(wildcard $(REP)/$(1))))
|
||||
|
||||
include $(BASE_DIR)/mk/global.mk
|
||||
|
||||
#
|
||||
# Some compilers do not support the compiler arguments that we use with 'gcc'
|
||||
# and, consequently, spit errors. Hence, we have to check if the compiler
|
||||
# arguments are supported and drop them in the other case. We cache the result
|
||||
# of the check in the CC_OPT_CHECKCC variable. The caching improves the build
|
||||
# performance by 5 to 10 percent.
|
||||
#
|
||||
checkcc = $(shell if $(CUSTOM_CC) $(1) -o /dev/null -xc - <<< 'int main(void){return 0;}' &> /dev/null; then echo "$(1)" ; fi ;)
|
||||
|
||||
CC_OPT_CHECKCC = $(call checkcc, -static)
|
||||
CC_OPT_CHECKCC += $(call checkcc, -fno-stack-protector)
|
||||
|
||||
export CC_OPT_CHECKCC
|
||||
|
||||
export LIBGCC_INC_DIR = $(shell dirname `$(CUSTOM_CXX_LIB) -print-libgcc-file-name`)/include
|
||||
|
||||
#
|
||||
# Find out about the target directories to build
|
||||
#
|
||||
DST_DIRS = $(filter-out all clean bin cleanall again run/%,$(MAKECMDGOALS))
|
||||
|
||||
ifeq ($(MAKECMDGOALS),)
|
||||
DST_DIRS = .
|
||||
endif
|
||||
|
||||
#
|
||||
# Default rule: build all directories specified as make arguments
|
||||
#
|
||||
all $(DST_DIRS): gen_deps_and_build_targets
|
||||
@true
|
||||
|
||||
#
|
||||
# Helper to find targets in repositories
|
||||
# The sed command is there to replace /./ by /. This happens when DST_DIRS = .
|
||||
#
|
||||
find_src_target_mk = $(GNU_FIND) $$i/src/$(@:.visit=) -name target.mk 2>/dev/null | sed "s/\/\.\//\//g"
|
||||
find_all_src_target_mk = for i in $(REPOSITORIES); do $(find_src_target_mk); done
|
||||
|
||||
-include $(call select_from_repositories,etc/specs.conf)
|
||||
-include $(BUILD_BASE_DIR)/etc/specs.conf
|
||||
export SPEC_FILES := $(foreach SPEC,$(SPECS),$(call select_from_repositories,mk/spec-$(SPEC).mk))
|
||||
include $(SPEC_FILES)
|
||||
export SPECS
|
||||
|
||||
##
|
||||
## First stage: generate library dependencies
|
||||
##
|
||||
|
||||
#
|
||||
# Reset library-build log and library-dependency file
|
||||
#
|
||||
# The 'progress' file contains the names of the already processed libraries
|
||||
# of the current build process. Before considering to process any library,
|
||||
# the build system checks if the library is already present in the 'progress'
|
||||
# file and, if yes, skips it.
|
||||
#
|
||||
.PHONY: init_progress_log
|
||||
init_progress_log:
|
||||
@echo "#" > $(LIB_PROGRESS_LOG)
|
||||
@echo "# Library build progress log - generated by dep_prg.mk and dep_lib.mk" >> $(LIB_PROGRESS_LOG)
|
||||
@echo "#" >> $(LIB_PROGRESS_LOG)
|
||||
|
||||
.PHONY: init_libdep_file
|
||||
init_libdep_file:
|
||||
@echo "#" > $(LIB_DEP_FILE)
|
||||
@echo "# Library dependencies for build '$(DST_DIRS)'" >> $(LIB_DEP_FILE)
|
||||
@echo "#" >> $(LIB_DEP_FILE)
|
||||
@echo "" >> $(LIB_DEP_FILE)
|
||||
@echo "export SPEC_FILES := \\" >> $(LIB_DEP_FILE)
|
||||
@for i in $(SPEC_FILES); do \
|
||||
echo " $$i \\" >> $(LIB_DEP_FILE); done
|
||||
@echo "" >> $(LIB_DEP_FILE)
|
||||
@echo "LIB_CACHE_DIR = $(LIB_CACHE_DIR)" >> $(LIB_DEP_FILE)
|
||||
@echo "BASE_DIR = $(realpath $(BASE_DIR))" >> $(LIB_DEP_FILE)
|
||||
@echo "VERBOSE ?= $(VERBOSE)" >> $(LIB_DEP_FILE)
|
||||
@echo "VERBOSE_MK ?= $(VERBOSE_MK)" >> $(LIB_DEP_FILE)
|
||||
@echo "VERBOSE_DIR ?= $(VERBOSE_DIR)" >> $(LIB_DEP_FILE)
|
||||
@echo "INSTALL_DIR ?= $(INSTALL_DIR)" >> $(LIB_DEP_FILE)
|
||||
@echo "SHELL ?= $(SHELL)" >> $(LIB_DEP_FILE)
|
||||
@echo "MKDIR ?= mkdir" >> $(LIB_DEP_FILE)
|
||||
@echo "" >> $(LIB_DEP_FILE)
|
||||
@echo "all:" >> $(LIB_DEP_FILE)
|
||||
@echo " @true # prevent nothing-to-be-done message" >> $(LIB_DEP_FILE)
|
||||
@echo "" >> $(LIB_DEP_FILE)
|
||||
|
||||
#
|
||||
# We check if any target.mk files exist in the specified src directory. If
|
||||
# there exist any target.mk files, we revisit each repository and create
|
||||
# corresponding rules in the library-dependency file.
|
||||
#
|
||||
# This stage is executed serially.
|
||||
#
|
||||
|
||||
$(dir $(LIB_DEP_FILE)):
|
||||
@mkdir -p $@
|
||||
|
||||
VISIT_DST_DIRS = $(addsuffix .visit,$(DST_DIRS))
|
||||
|
||||
.PHONY: $(VISIT_DST_DIRS)
|
||||
.NOTPARALLEL: $(VISIT_DST_DIRS)
|
||||
$(VISIT_DST_DIRS): $(dir $(LIB_DEP_FILE)) init_libdep_file init_progress_log
|
||||
@echo "checking library dependencies for $(@:.visit=)..."
|
||||
@test "`$(find_all_src_target_mk)`" != "" ||\
|
||||
(echo Error: non-existing target $(@:.visit=); false)
|
||||
$(VERBOSE_MK)set -e; for i in $(REPOSITORIES); do \
|
||||
for j in `$(find_src_target_mk)`; do \
|
||||
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_prg.mk \
|
||||
REP_DIR=$$i TARGET_MK=$$j \
|
||||
BUILD_BASE_DIR=$(BUILD_BASE_DIR) \
|
||||
SHELL=$(SHELL) \
|
||||
DARK_COL="$(DARK_COL)" DEFAULT_COL="$(DEFAULT_COL)"; done; done
|
||||
|
||||
.PHONY: $(LIB_DEP_FILE)
|
||||
$(LIB_DEP_FILE): $(VISIT_DST_DIRS)
|
||||
|
||||
##
|
||||
## Second stage: build targets based on the result of the first stage
|
||||
##
|
||||
|
||||
$(INSTALL_DIR):
|
||||
$(VERBOSE)mkdir -p $@
|
||||
|
||||
.PHONY: gen_deps_and_build_targets
|
||||
gen_deps_and_build_targets: $(INSTALL_DIR) $(LIB_DEP_FILE)
|
||||
@$(VERBOSE_MK)$(MAKE) $(VERBOSE_DIR) -f $(LIB_DEP_FILE) all
|
||||
|
||||
.PHONY: again
|
||||
again: $(INSTALL_DIR)
|
||||
@$(VERBOSE_MK)$(MAKE) $(VERBOSE_DIR) -f $(LIB_DEP_FILE) all
|
||||
|
||||
##
|
||||
## Rules for running automated test cases
|
||||
##
|
||||
|
||||
RUN_OPT ?=
|
||||
RUN_ENV := $(call select_from_repositories,run/env)
|
||||
|
||||
ifeq ($(RUN_ENV),)
|
||||
run: run_no_env
|
||||
endif
|
||||
|
||||
run_no_env:
|
||||
@echo "Error: There exists no execution environment this platform"
|
||||
@false
|
||||
|
||||
# helper for run/% rule
|
||||
RUN_SCRIPT = $(call select_from_repositories,run/$*.run)
|
||||
|
||||
#
|
||||
# Read tools configuration to obtain the cross-compiler prefix passed
|
||||
# to the run script.
|
||||
#
|
||||
-include $(call select_from_repositories,etc/tools.conf)
|
||||
|
||||
run/%: $(call select_from_repositories,run/%.run) $(RUN_ENV)
|
||||
$(VERBOSE)test -f "$(RUN_SCRIPT)" || (echo "Error: No run script for $*"; exit -1)
|
||||
$(VERBOSE)$(GENODE_DIR)/tool/run --genode-dir $(GENODE_DIR) \
|
||||
--name $* \
|
||||
--specs "$(SPECS)" \
|
||||
--repositories "$(REPOSITORIES)" \
|
||||
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
|
||||
--qemu-args "$(QEMU_OPT)" \
|
||||
--include $(RUN_ENV) $(RUN_OPT) \
|
||||
--include $(RUN_SCRIPT)
|
||||
|
||||
##
|
||||
## Clean rules
|
||||
##
|
||||
|
||||
#
|
||||
# For cleaning, visit each directory for that a corresponding target.mk
|
||||
# file exists in the source tree. For each such directory, we call
|
||||
# the single_target rule.
|
||||
#
|
||||
clean_targets:
|
||||
$(VERBOSE_MK)for d in `$(GNU_FIND) -mindepth 1 -type d | $(TAC) | sed "s/^..//"`; do \
|
||||
for r in $(REPOSITORIES); do \
|
||||
test -f $$r/src/$$d/target.mk && \
|
||||
$(MAKE) $(VERBOSE_DIR) clean \
|
||||
-C $$d \
|
||||
-f $(BASE_DIR)/mk/prg.mk \
|
||||
BUILD_BASE_DIR=$(BUILD_BASE_DIR) \
|
||||
PRG_REL_DIR=$$d \
|
||||
SHELL=$(SHELL) \
|
||||
REP_DIR=$$r || \
|
||||
true; \
|
||||
done; \
|
||||
done
|
||||
|
||||
clean_libcache:
|
||||
$(VERBOSE)rm -rf var/libcache
|
||||
|
||||
clean_run:
|
||||
$(VERBOSE)rm -rf var/run
|
||||
|
||||
clean_gen_files:
|
||||
$(VERBOSE)rm -f $(LIB_PROGRESS_LOG)
|
||||
$(VERBOSE)rm -f $(LIB_DEP_FILE)
|
||||
|
||||
clean_install_dir:
|
||||
$(VERBOSE)(test -d $(INSTALL_DIR) && find $(INSTALL_DIR) -type l -not -readable -delete) || true
|
||||
|
||||
clean_empty_dirs: clean_targets clean_libcache clean_run clean_gen_files clean_install_dir
|
||||
$(VERBOSE)$(GNU_FIND) . -depth -type d -empty -delete
|
||||
|
||||
clean cleanall: clean_empty_dirs
|
||||
|
||||
2
tool/builddir/etc/README
Normal file
2
tool/builddir/etc/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This directory contains templates for configuring build directories
|
||||
for different platforms. They are used by the 'create_builddir' tool.
|
||||
1
tool/builddir/etc/build.conf.codezero_vpb926
Normal file
1
tool/builddir/etc/build.conf.codezero_vpb926
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-codezero
|
||||
12
tool/builddir/etc/build.conf.drivers_x86
Normal file
12
tool/builddir/etc/build.conf.drivers_x86
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#
|
||||
# Drivers ported from the Linux kernel
|
||||
#
|
||||
# Not supported on the ARM architecture.
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/linux_drivers
|
||||
|
||||
#
|
||||
# Drivers ported from iPXE
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/dde_ipxe
|
||||
1
tool/builddir/etc/build.conf.fiasco_x86
Normal file
1
tool/builddir/etc/build.conf.fiasco_x86
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-fiasco
|
||||
1
tool/builddir/etc/build.conf.foc_pbxa9
Normal file
1
tool/builddir/etc/build.conf.foc_pbxa9
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-foc
|
||||
1
tool/builddir/etc/build.conf.foc_vea9x4
Normal file
1
tool/builddir/etc/build.conf.foc_vea9x4
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-foc
|
||||
1
tool/builddir/etc/build.conf.foc_x86_32
Normal file
1
tool/builddir/etc/build.conf.foc_x86_32
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-foc
|
||||
1
tool/builddir/etc/build.conf.foc_x86_64
Normal file
1
tool/builddir/etc/build.conf.foc_x86_64
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-foc
|
||||
42
tool/builddir/etc/build.conf.generic
Normal file
42
tool/builddir/etc/build.conf.generic
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
##
|
||||
## Repositories needed for the default demo scenario
|
||||
##
|
||||
|
||||
REPOSITORIES += $(GENODE_DIR)/base
|
||||
REPOSITORIES += $(GENODE_DIR)/os
|
||||
REPOSITORIES += $(GENODE_DIR)/demo
|
||||
|
||||
##
|
||||
## Optional repositories
|
||||
##
|
||||
|
||||
#
|
||||
# Ports of popular open-source libraries and the C library
|
||||
#
|
||||
# Make sure to execute 'make prepare' in 'libports' prior building.
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/libports
|
||||
|
||||
#
|
||||
# Qt4 tool kit
|
||||
#
|
||||
# The 'qt4' repository depends on 'libc' and 'libports'
|
||||
# Make sure to execute 'make prepare' in 'qt4' prior building.
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/qt4
|
||||
|
||||
#
|
||||
# Ports of popular 3rd-party applications
|
||||
#
|
||||
# The 'ports' repository depends on 'libc', 'libports', and 'qt4'.
|
||||
# Make sure to execute 'make prepare' in 'ports' prior building.
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/ports
|
||||
|
||||
#
|
||||
# High-level Genode-specific services and applications
|
||||
#
|
||||
# The 'gems' repository depends on 'libc', 'libports', and 'qt4'.
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/gems
|
||||
1
tool/builddir/etc/build.conf.linux_x86
Normal file
1
tool/builddir/etc/build.conf.linux_x86
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-linux
|
||||
2
tool/builddir/etc/build.conf.mb_ml507
Normal file
2
tool/builddir/etc/build.conf.mb_ml507
Normal file
@@ -0,0 +1,2 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-mb
|
||||
RUN_OPT += --qemu qemu-mb_s3a_starter_kit
|
||||
2
tool/builddir/etc/build.conf.mb_s3a_starter_kit
Normal file
2
tool/builddir/etc/build.conf.mb_s3a_starter_kit
Normal file
@@ -0,0 +1,2 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-mb
|
||||
RUN_OPT += --qemu qemu-mb_s3a_starter_kit
|
||||
6
tool/builddir/etc/build.conf.nova_x86
Normal file
6
tool/builddir/etc/build.conf.nova_x86
Normal file
@@ -0,0 +1,6 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-nova
|
||||
|
||||
#
|
||||
# The current NOVA kernel build is optimized for Intel Core Duo.
|
||||
#
|
||||
QEMU_OPT += -cpu coreduo
|
||||
1
tool/builddir/etc/build.conf.okl4_x86
Normal file
1
tool/builddir/etc/build.conf.okl4_x86
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-okl4
|
||||
1
tool/builddir/etc/build.conf.pistachio_x86
Normal file
1
tool/builddir/etc/build.conf.pistachio_x86
Normal file
@@ -0,0 +1 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/base-pistachio
|
||||
5
tool/builddir/etc/build.conf.ports-foc
Normal file
5
tool/builddir/etc/build.conf.ports-foc
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
#
|
||||
# Software ported specifically for Fiasco.OC, i.e., L4Linux
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/ports-foc
|
||||
5
tool/builddir/etc/build.conf.ports-okl4
Normal file
5
tool/builddir/etc/build.conf.ports-okl4
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
#
|
||||
# Software ported specifically for OKL4, i.e., OKLinux
|
||||
#
|
||||
#REPOSITORIES += $(GENODE_DIR)/ports-okl4
|
||||
10
tool/builddir/etc/build.conf.qemu_no_kvm
Normal file
10
tool/builddir/etc/build.conf.qemu_no_kvm
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#
|
||||
# Prevent Qemu from using KVM
|
||||
#
|
||||
# Qemu version that come with major Linux distributions (i.e., Ubuntu) enable
|
||||
# KVM by default. To use Qemu without KVM, Qemu must be started with the
|
||||
# '-no-kvm' argument. However, if your Qemu version does not support this
|
||||
# argument, comment-out this line.
|
||||
#
|
||||
QEMU_OPT += -no-kvm
|
||||
145
tool/create_builddir
Executable file
145
tool/create_builddir
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
#
|
||||
# \brief Prepare Genode build directory
|
||||
# \author Christian Helmuth, Norman Feske
|
||||
# \date 2008-08-14
|
||||
#
|
||||
|
||||
MAKEOVERRIDES =
|
||||
|
||||
PLATFORM = $(MAKECMDGOALS)
|
||||
|
||||
usage:
|
||||
@echo
|
||||
@echo "Tool for preparing Genode build directories"
|
||||
@echo
|
||||
@echo "usage:"
|
||||
@echo
|
||||
@echo " create_builddir <platform> BUILD_DIR=<build-dir>"
|
||||
@echo
|
||||
@echo " <platform> can be 'linux_x86', 'fiasco_x86', 'pistachio_x86',"
|
||||
@echo " 'okl4_x86', 'nova_x86', 'codezero_vpb926',"
|
||||
@echo " 'mb_s3a_starter_kit', foc_x86_32', 'foc_x86_64',"
|
||||
@echo " ''foc_pbxa9', or 'foc_vea9x4'"
|
||||
@echo " 'or 'foc_pbxa9'"
|
||||
@echo " "
|
||||
@echo " <build-dir> is the location of the build directory to create"
|
||||
@echo
|
||||
|
||||
#
|
||||
# Determine Genode base directory based on the known location of the
|
||||
# 'create_builddir' tool within the Genode source tree
|
||||
#
|
||||
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/..)
|
||||
|
||||
ifeq ($(BUILD_DIR),)
|
||||
$(PLATFORM):: usage
|
||||
@echo "Error: BUILD_DIR not defined." ; false
|
||||
endif
|
||||
|
||||
#
|
||||
# Convert GENODE_DIR to an absolute directory because the user
|
||||
# may have specified a '~'-relative location or a pwd-relative
|
||||
# location.
|
||||
#
|
||||
GENODE_ABS_DIR := $(realpath $(shell echo $(GENODE_DIR)))
|
||||
|
||||
#
|
||||
# Generic build-directory preparation rules
|
||||
#
|
||||
BUILD_CONF = $(GENODE_ABS_DIR)/tool/builddir/etc/build.conf
|
||||
BUILD_CONF_PLATFORM = $(BUILD_CONF).$(PLATFORM)
|
||||
|
||||
$(BUILD_DIR)/etc:
|
||||
@mkdir -p $@
|
||||
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@echo "GENODE_DIR = $(GENODE_ABS_DIR)" > $@
|
||||
@echo 'BASE_DIR = $$(GENODE_DIR)/base' >> $@
|
||||
|
||||
#
|
||||
# Supply -no-kvm argument to Qemu for kernels that are incompatible with KVM
|
||||
#
|
||||
ifeq ($(filter-out foc_x86_32 foc_x86_64 okl4_x86 nova_x86 pistachio_x86,$(PLATFORM)),)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).qemu_no_kvm >> $@
|
||||
endif
|
||||
|
||||
#
|
||||
# Add 'base-<platform>' and generic repositories
|
||||
#
|
||||
$(BUILD_DIR)/etc/build.conf:: $(BUILD_CONF_PLATFORM)
|
||||
@echo >> $@
|
||||
@echo "##" >> $@
|
||||
@echo "## Kernel-specific base repository" >> $@
|
||||
@echo "##" >> $@
|
||||
@echo >> $@
|
||||
@cat $< >> $@
|
||||
@cat $(BUILD_CONF).generic >> $@
|
||||
|
||||
#
|
||||
# Add 'ports-okl4' repository to OKL4 build directory
|
||||
#
|
||||
ifeq ($(PLATFORM),okl4_x86)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).ports-okl4 >> $@
|
||||
endif
|
||||
|
||||
$(BUILD_DIR)/Makefile:
|
||||
@ln -sf $(GENODE_ABS_DIR)/tool/builddir/build.mk $@
|
||||
|
||||
#
|
||||
# Add 'ports-foc' repository to Fiasco.OC build directory
|
||||
#
|
||||
ifeq ($(filter-out foc_x86_32 foc_pbxa9,$(PLATFORM)),)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).ports-foc >> $@
|
||||
endif
|
||||
|
||||
#
|
||||
# Add x86 drivers repositories to x86 build directories
|
||||
#
|
||||
ifeq ($(filter-out foc_x86_32 okl4_x86 nova_x86 pistachio_x86 fiasco_x86,$(PLATFORM)),)
|
||||
$(BUILD_DIR)/etc/build.conf::
|
||||
@cat $(BUILD_CONF).drivers_x86 >> $@
|
||||
endif
|
||||
|
||||
#
|
||||
# Generic platform dependencies
|
||||
#
|
||||
$(PLATFORM):: $(BUILD_DIR)/etc
|
||||
$(PLATFORM):: $(BUILD_DIR)/etc/build.conf
|
||||
$(PLATFORM):: $(BUILD_DIR)/Makefile
|
||||
|
||||
#
|
||||
# Platform-specific dependencies
|
||||
#
|
||||
codezero_vpb926::
|
||||
@echo "SPECS += codezero_platform_vpb926" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_x86_32::
|
||||
@echo "SPECS = genode foc_x86_32" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_x86_64::
|
||||
@echo "SPECS = genode foc_x86_64" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_pbxa9::
|
||||
@echo "SPECS = genode foc_pbxa9" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_vea9x4::
|
||||
@echo "SPECS = genode foc_vea9x4" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
codezero_vpb926::
|
||||
@echo "CODEZERO_DIR = $(GENODE_DIR)/base-codezero/contrib" > $(BUILD_DIR)/etc/codezero.conf
|
||||
|
||||
mb_s3a_starter_kit::
|
||||
@echo "SPECS = genode mb_s3a_starter_kit" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
mb_ml507::
|
||||
@echo "SPECS = genode mb_ml507" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
$(PLATFORM)::
|
||||
@echo "successfully created build directory at $(BUILD_DIR)"
|
||||
|
||||
.PHONY: $(PLATFORM)
|
||||
70
tool/create_iso
Executable file
70
tool/create_iso
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/make -f
|
||||
#
|
||||
# \brief ISO image creation tool
|
||||
# \author Christian Helmuth
|
||||
# \date 2009-02-05
|
||||
|
||||
ISO ?= genode
|
||||
ISODIR = $(abspath $(ISO))
|
||||
ISOIMG = $(abspath $(ISO).iso)
|
||||
|
||||
default help:
|
||||
@echo "--- available commands ---"
|
||||
@echo "iso - create ISO image of directory \"$(ISO)\""
|
||||
@echo "tiny.iso - create tiny ISO image of directory \"$(ISO)\""
|
||||
@echo "compress - create bzip2 compressed ISO image"
|
||||
@echo "clean - cleanup everything"
|
||||
@echo
|
||||
@echo "--- configuration options ---"
|
||||
@echo "ISO=<name> Overwrites basename of cd image file."
|
||||
@echo
|
||||
@echo "Please, place your binaries and config files in appropriate subdirectories in"
|
||||
@echo " $(ISODIR)"
|
||||
@echo "and adapt"
|
||||
@echo " $(ISODIR)/boot/grub/menu.lst"
|
||||
@echo "to your configuration's needs. A sample directory tree can be found in"
|
||||
@echo "tool/boot/genode."
|
||||
|
||||
#
|
||||
# Function to generate bootable ISO images
|
||||
#
|
||||
# parameter 1 filename of ISO image
|
||||
# parameter 2 path of directory containing file tree for the ISO image
|
||||
#
|
||||
gen_iso_image = genisoimage -f -l -R -hide-rr-moved -jcharset utf8 \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-b boot/isolinux/isolinux.bin \
|
||||
-o $(1) $(2)
|
||||
|
||||
$(ISOIMG) iso:
|
||||
@$(call gen_iso_image, $(ISOIMG) $(ISODIR))
|
||||
@which isohybrid > /dev/null && isohybrid $(ISOIMG)
|
||||
|
||||
STRIP_FILES = $(wildcard genode/*) $(wildcard pistachio/*)
|
||||
|
||||
#
|
||||
# Compact all files in a directory using strip and gzip
|
||||
#
|
||||
# parameter 1 directory containing the files to strip and gzip
|
||||
#
|
||||
compact_files = for f in `find $(1) -type f`; do \
|
||||
strip $$f -o strip.tmp; \
|
||||
gzip -c strip.tmp > $$f; \
|
||||
done; rm -f strip.tmp
|
||||
|
||||
tiny.iso:
|
||||
@rm -rf $(@:.iso=.dir)
|
||||
@cp -Lrp $(ISODIR) $(@:.iso=.dir)
|
||||
@$(call compact_files, $(@:.iso=.dir)/fiasco)
|
||||
@$(call compact_files, $(@:.iso=.dir)/pistachio)
|
||||
@$(call compact_files, $(@:.iso=.dir)/genode)
|
||||
@$(call gen_iso_image, $@ $(@:.iso=.dir))
|
||||
@rm -rf $(@:.iso=.dir)
|
||||
|
||||
compress: $(ISOIMG)
|
||||
@bzip2 -f -c $< > $).bz2
|
||||
|
||||
clean:
|
||||
@rm -rf tiny.dir tiny.iso $(ISOIMG)
|
||||
|
||||
.PHONY: $(ISOIMG) tiny.iso clean
|
||||
119
tool/fix_include_ifndef
Executable file
119
tool/fix_include_ifndef
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/tclsh
|
||||
|
||||
# read include file
|
||||
set include_pathname [lindex $argv 0]
|
||||
if {[catch {
|
||||
set source [exec cat $include_pathname]
|
||||
}]} {
|
||||
puts stderr ""
|
||||
puts stderr "Assign correct ifndef-define name to header file."
|
||||
puts stderr "The name is derived from the location of the"
|
||||
puts stderr "header file relative to directory from which"
|
||||
puts stderr "this program is executed."
|
||||
puts stderr ""
|
||||
puts stderr "\n usage: fix_include_ifndef <include_file>\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
puts stderr "Fixing ifndef header for $include_pathname"
|
||||
|
||||
# convert pathname to ifndef string
|
||||
regsub {^./} $include_pathname "" ifndef_name
|
||||
set ifndef_name [string toupper $ifndef_name]
|
||||
regsub -all {/} $ifndef_name {__} ifndef_name
|
||||
regsub -all {\.} $ifndef_name {_} ifndef_name
|
||||
regsub -all {\-} $ifndef_name {_} ifndef_name
|
||||
set ifndef_name "_$ifndef_name\_"
|
||||
|
||||
set lines [split $source "\n"]
|
||||
set state comment_header_begin
|
||||
set i 0
|
||||
set output ""
|
||||
|
||||
proc out {txtline} {
|
||||
global output
|
||||
append output "$txtline\n"
|
||||
}
|
||||
|
||||
foreach line $lines {
|
||||
incr i
|
||||
|
||||
if {$state == "comment_header_begin"} {
|
||||
if {[regexp {^/*} $line]} {
|
||||
set state comment_header
|
||||
out $line
|
||||
continue
|
||||
} else {
|
||||
puts stderr "Error (line $i): missing comment header"
|
||||
exit -1;
|
||||
}
|
||||
}
|
||||
|
||||
if {$state == "comment_header"} {
|
||||
if {[regexp {^ \*/} $line]} {
|
||||
set state empty_line_after_comment_header
|
||||
out $line
|
||||
continue;
|
||||
}
|
||||
if {[regexp {^ \*[^/]*} $line]} {
|
||||
out $line
|
||||
continue
|
||||
}
|
||||
puts "Error (line $i): non-complient comment header"
|
||||
exit -1;
|
||||
}
|
||||
|
||||
if {$state == "empty_line_after_comment_header"} {
|
||||
if {![regexp {^$} $line]} {
|
||||
puts "Error (line $i): no empty line after comment header"
|
||||
exit -1;
|
||||
}
|
||||
set state ifndef
|
||||
out $line
|
||||
continue
|
||||
}
|
||||
|
||||
if {$state == "ifndef"} {
|
||||
if {![regexp {^#ifndef} $line]} {
|
||||
puts "Error (line $i): expected \"#ifndef\""
|
||||
exit -1;
|
||||
}
|
||||
|
||||
regsub {^.*$} $line "#ifndef $ifndef_name" line
|
||||
out $line
|
||||
set state define
|
||||
continue
|
||||
}
|
||||
|
||||
if {$state == "define"} {
|
||||
if {![regexp {^#define} $line]} {
|
||||
puts "Error (line $i): expected \"#define\""
|
||||
exit -1;
|
||||
}
|
||||
|
||||
regsub {^.*$} $line "#define $ifndef_name" line
|
||||
out $line
|
||||
set state source_main
|
||||
continue
|
||||
}
|
||||
|
||||
out $line
|
||||
}
|
||||
|
||||
# remove empty lines at the end of the header file
|
||||
while {[regexp "\n$" $output]} {
|
||||
regsub "\n$" $output "" output
|
||||
}
|
||||
|
||||
if {![regexp "\n#endif\[^\n\]*\$" $output]} {
|
||||
puts stderr "Error: last line is no \"#endif\""
|
||||
exit -1
|
||||
}
|
||||
|
||||
regsub "\n#endif\[^\n\]*\$" $output "\n#endif /* $ifndef_name */" output
|
||||
|
||||
# write result back to include file
|
||||
set fh [open $include_pathname "w"]
|
||||
puts $fh $output
|
||||
close $fh
|
||||
|
||||
641
tool/libgcc_libc_stub.h
Normal file
641
tool/libgcc_libc_stub.h
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* \brief Stub for compiling GCC support libraries without libc
|
||||
* \author Norman Feske
|
||||
* \date 2011-08-31
|
||||
*
|
||||
* The target components of GCC tool chains (i.e. libsupc++, libgcc_eh, and
|
||||
* libstdc++) depend on the presence of libc includes. For this reason, a C
|
||||
* library for the target platform is normally regarded as a prerequisite for
|
||||
* building a complete tool chain. However, for low-level operating-system
|
||||
* code, this prerequisite is not satisfied.
|
||||
*
|
||||
* There are two traditional solutions to this problem. The first is to leave
|
||||
* out those target components from the tool chain and live without full C++
|
||||
* support (using '-fno-rtti' and '-fno-exceptions'). Because Genode relies on
|
||||
* such C++ features however, this is no option. The other traditional solution
|
||||
* is to use a tool chain compiled for a different target platform such as
|
||||
* Linux. However, this approach calls for subtle problems because the target
|
||||
* components are compiled against glibc and make certain presumptions about
|
||||
* the underlying OS environment. E.g., the 'libstdc++' library of a Linux tool
|
||||
* chain contains references to glibc's 'stderr' symbol, which does not exist
|
||||
* on Genode's libc derived from FreeBSD. More critical assumptions are related
|
||||
* to the mechanism used for thread-local storage.
|
||||
*
|
||||
* This header file overcomes these problems by providing all function
|
||||
* prototypes and type declarations that are mandatory for compiling GCC's
|
||||
* target components. Using this libc stub, all GCC target components can be
|
||||
* built without the need for additional libc support. Of course, for actually
|
||||
* using these target components, the target OS has to provide the
|
||||
* implementation of a small subset of functions declared herein. On Genode,
|
||||
* this subset is provided by the 'cxx' library.
|
||||
*
|
||||
* The code of the target components expects usual C header file names such as
|
||||
* 'stdio.h'. It does not include 'libgcc_libc_stub.h'. By creating symlinks
|
||||
* for all those file names pointing to this file, we ensure that this file is
|
||||
* always included on the first occurrence of the inclusion of any libc header
|
||||
* file. The set of symlinks pointing to this libc stub are created
|
||||
* automatically by the 'tool_chain' script.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LIBC_STUB_H_
|
||||
#define _LIBC_STUB_H_
|
||||
|
||||
/* used for vararg, comes with GCC */
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*****************
|
||||
** sys/types.h **
|
||||
*****************/
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
#ifndef ssize_t
|
||||
#define ssize_t long /* xxx 64bit */
|
||||
#endif
|
||||
|
||||
typedef unsigned long off_t; /* XXX 64bit */
|
||||
|
||||
#define pid_t int
|
||||
|
||||
typedef unsigned short mode_t; /* XXX 64bit */
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else
|
||||
#define NULL ((void *)0)
|
||||
#endif /* __cplusplus */
|
||||
#endif /* defined NULL */
|
||||
|
||||
typedef long clock_t; /* XXX not on 64bit */
|
||||
|
||||
#ifdef _LP64
|
||||
typedef signed char __int8_t;
|
||||
typedef signed short __int16_t;
|
||||
typedef signed int __int32_t;
|
||||
typedef signed long __int64_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef unsigned short __uint16_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
typedef unsigned long __uint64_t;
|
||||
#else /* _LP64 */
|
||||
typedef signed char __int8_t;
|
||||
typedef signed short __int16_t;
|
||||
typedef signed long __int32_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef unsigned short __uint16_t;
|
||||
typedef unsigned long __uint32_t;
|
||||
#ifndef __STRICT_ANSI__
|
||||
typedef signed long long __int64_t;
|
||||
typedef unsigned long long __uint64_t;
|
||||
#endif /* __STRICT_ANSI__ */
|
||||
#endif /* _LP64 */
|
||||
|
||||
typedef __int64_t intmax_t;
|
||||
typedef __int32_t int_fast8_t;
|
||||
typedef __int32_t int_fast16_t;
|
||||
typedef __int32_t int_fast32_t;
|
||||
typedef __int64_t int_fast64_t;
|
||||
typedef __int8_t int_least8_t;
|
||||
typedef __int16_t int_least16_t;
|
||||
typedef __int32_t int_least32_t;
|
||||
typedef __int64_t int_least64_t;
|
||||
typedef __uint64_t uintmax_t;
|
||||
|
||||
#ifdef _LP64
|
||||
typedef __int64_t time_t;
|
||||
typedef __int64_t intptr_t;
|
||||
typedef __uint64_t uintptr_t;
|
||||
#else
|
||||
typedef __int32_t time_t;
|
||||
typedef __int32_t intptr_t;
|
||||
typedef __uint32_t uintptr_t;
|
||||
#endif
|
||||
|
||||
typedef __uint32_t uint_fast8_t;
|
||||
typedef __uint32_t uint_fast16_t;
|
||||
typedef __uint32_t uint_fast32_t;
|
||||
typedef __uint64_t uint_fast64_t;
|
||||
typedef __uint8_t uint_least8_t;
|
||||
typedef __uint16_t uint_least16_t;
|
||||
typedef __uint32_t uint_least32_t;
|
||||
typedef __uint64_t uint_least64_t;
|
||||
|
||||
struct timeval {
|
||||
time_t tv_sec;
|
||||
long tv_usec; /* XXX 64bit */
|
||||
};
|
||||
|
||||
|
||||
/****************
|
||||
** sys/stat.h **
|
||||
****************/
|
||||
|
||||
struct stat
|
||||
{
|
||||
unsigned long st_dev;
|
||||
unsigned long st_ino;
|
||||
unsigned short st_mode;
|
||||
};
|
||||
|
||||
#define S_ISREG(m) (((m) & 0170000) == 0100000)
|
||||
|
||||
|
||||
/************
|
||||
** time.h **
|
||||
************/
|
||||
|
||||
struct tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
long tm_gmtoff;
|
||||
char *tm_zone;
|
||||
};
|
||||
|
||||
clock_t clock(void);
|
||||
double difftime(time_t time1, time_t time0);
|
||||
struct tm *localtime(const time_t *timep);
|
||||
char *asctime(const struct tm *tm);
|
||||
time_t mktime(struct tm *tm);
|
||||
char *ctime(const time_t *timep);
|
||||
struct tm *gmtime(const time_t *timep);
|
||||
time_t time(time_t *t);
|
||||
size_t strftime(char *s, size_t max, const char *format,
|
||||
const struct tm *tm);
|
||||
|
||||
|
||||
/**************
|
||||
** string.h **
|
||||
**************/
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
size_t strlen(const char *s);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strncpy(char *dest, const char *src, size_t n);
|
||||
void *memchr(const void *s, int c, size_t n);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
size_t strcspn(const char *s, const char *reject);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
size_t strspn(const char *s, const char *accept);
|
||||
char *strpbrk(const char *s, const char *accept);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strncat(char *dest, const char *src, size_t n);
|
||||
|
||||
/* for compiling 'libsupc++/del_opvnt.cc' */
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
int strcoll(const char *s1, const char *s2);
|
||||
char *strerror(int errnum);
|
||||
char *strtok(char *str, const char *delim);
|
||||
size_t strxfrm(char *dest, const char *src, size_t n);
|
||||
char *strrchr(const char *s, int c);
|
||||
|
||||
|
||||
/***************
|
||||
** strings.h **
|
||||
***************/
|
||||
|
||||
void bcopy(const void *src, void *dest, size_t n);
|
||||
void bzero(void *s, size_t n);
|
||||
|
||||
|
||||
/**************
|
||||
** stdlib.h **
|
||||
**************/
|
||||
|
||||
void free(void *ptr);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
void *malloc(size_t size);
|
||||
void *calloc(size_t nmemb, size_t size);
|
||||
void abort(void);
|
||||
void exit(int);
|
||||
int atoi(const char *nptr);
|
||||
void *alloca(size_t size);
|
||||
|
||||
/* for compiling 'libsupc++/del_op.cc' */
|
||||
typedef struct { int quot; int rem; } div_t;
|
||||
typedef struct { long quot; long rem; } ldiv_t;
|
||||
int abs(int j);
|
||||
long int labs(long int j);
|
||||
double atof(const char *nptr);
|
||||
long atol(const char *nptr);
|
||||
div_t div(int numerator, int denominator);
|
||||
ldiv_t ldiv(long numerator, long denominator);
|
||||
void qsort(void *base, size_t nmemb, size_t size,
|
||||
int(*compar)(const void *, const void *));
|
||||
int rand(void);
|
||||
void srand(unsigned int seed);
|
||||
int system(const char *command);
|
||||
|
||||
#ifdef _ANSIDECL_H
|
||||
/* special case provided specifically for compiling libiberty's 'strtod.c' */
|
||||
double strtod(char *nptr, char **endptr);
|
||||
#else
|
||||
double strtod(const char *nptr, char **endptr);
|
||||
#endif
|
||||
|
||||
long int strtol(const char *nptr, char **endptr, int base);
|
||||
unsigned long int strtoul(const char *nptr, char **endptr, int base);
|
||||
char *getenv(const char *name);
|
||||
int atexit(void (*function)(void));
|
||||
void *bsearch(const void *key, const void *base,
|
||||
size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *));
|
||||
|
||||
|
||||
/*************
|
||||
** stdio.h **
|
||||
*************/
|
||||
|
||||
typedef struct __sFILE { int dummy; } FILE;
|
||||
|
||||
extern FILE *__stderrp;
|
||||
extern FILE *__stdinp;
|
||||
extern FILE *__stdoutp;
|
||||
|
||||
#define stderr __stderrp
|
||||
#define stdin __stdinp
|
||||
#define stdout __stdoutp
|
||||
|
||||
/* must not be enum values */
|
||||
#define EOF (-1)
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
enum { _IONBF = 2 };
|
||||
|
||||
enum { BUFSIZ = 1024 };
|
||||
|
||||
FILE *fopen(const char *path, const char *mode);
|
||||
int fclose(FILE *fp);
|
||||
int fprintf(FILE *stream, const char *format, ...);
|
||||
int fputs(const char *s, FILE *stream);
|
||||
int sscanf(const char *str, const char *format, ...);
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
int ferror(FILE *stream);
|
||||
int sprintf(char *str, const char *format, ...);
|
||||
FILE *fdopen(int fd, const char *mode);
|
||||
int fileno(FILE *);
|
||||
|
||||
/* for compiling 'libsupc++/vterminate.cc' */
|
||||
typedef off_t fpos_t;
|
||||
void clearerr(FILE *stream);
|
||||
int feof(FILE *stream);
|
||||
int ferror(FILE *stream);
|
||||
int fflush(FILE *stream);
|
||||
char *fgets(char *s, int size, FILE *stream);
|
||||
int fgetc(FILE *stream);
|
||||
int fgetpos(FILE *stream, fpos_t *pos);
|
||||
int fsetpos(FILE *stream, fpos_t *pos);
|
||||
long ftell(FILE *stream);
|
||||
int fseek(FILE *stream, long offset, int whence);
|
||||
void rewind(FILE *stream);
|
||||
int fputc(int c, FILE *stream);
|
||||
int putchar(int c);
|
||||
int puts(const char *s);
|
||||
int putc(int c, FILE *stream);
|
||||
int rename(const char *oldpath, const char *newpath);
|
||||
int remove(const char *pathname);
|
||||
int vprintf(const char *format, va_list ap);
|
||||
int vfprintf(FILE *stream, const char *format, va_list ap);
|
||||
int vsprintf(char *str, const char *format, va_list ap);
|
||||
FILE *freopen(const char *path, const char *mode, FILE *stream);
|
||||
int fscanf(FILE *stream, const char *format, ...);
|
||||
int scanf(const char *format, ...);
|
||||
int getc(FILE *stream);
|
||||
int getchar(void);
|
||||
char *gets(char *s);
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
void perror(const char *s);
|
||||
int printf(const char *format, ...);
|
||||
void setbuf(FILE *stream, char *buf);
|
||||
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
|
||||
FILE *tmpfile(void);
|
||||
char *tmpnam(char *s);
|
||||
int ungetc(int c, FILE *stream);
|
||||
|
||||
|
||||
/**************
|
||||
** unistd.h **
|
||||
**************/
|
||||
|
||||
int close(int fd);
|
||||
ssize_t read(int fd, void *buf, size_t count);
|
||||
ssize_t write(int fd, const void *buf, size_t count);
|
||||
int execv(const char *path, char *const argv[]);
|
||||
int execvp(const char *file, char *const argv[]);
|
||||
pid_t fork(void);
|
||||
int unlink(const char *pathname);
|
||||
void _exit(int status);
|
||||
int link(const char *oldpath, const char *newpath);
|
||||
pid_t getpid(void);
|
||||
int pipe(int pipefd[2]);
|
||||
int dup2(int oldfd, int newfd);
|
||||
pid_t wait(int *status);
|
||||
unsigned int sleep(unsigned int seconds);
|
||||
off_t lseek(int fd, off_t offset, int whence);
|
||||
|
||||
|
||||
/*************
|
||||
** errno.h **
|
||||
*************/
|
||||
|
||||
#define errno (* __error())
|
||||
|
||||
int *__error(void);
|
||||
|
||||
/**
|
||||
* Error codes corresponding to those of FreeBSD
|
||||
*/
|
||||
enum {
|
||||
EPERM = 1,
|
||||
ENOENT = 2,
|
||||
ESRCH = 3,
|
||||
EINTR = 4,
|
||||
EIO = 5,
|
||||
ENXIO = 6,
|
||||
E2BIG = 7,
|
||||
ENOEXEC = 8,
|
||||
EBADF = 9,
|
||||
ECHILD = 10,
|
||||
EXDEV = 18,
|
||||
EDEADLK = 11,
|
||||
ENOMEM = 12,
|
||||
EACCES = 13,
|
||||
EFAULT = 14,
|
||||
EBUSY = 16,
|
||||
EEXIST = 17,
|
||||
ENODEV = 19,
|
||||
ENOTDIR = 20,
|
||||
EISDIR = 21,
|
||||
EINVAL = 22,
|
||||
ENFILE = 23,
|
||||
EMFILE = 24,
|
||||
ENOTTY = 25,
|
||||
EFBIG = 27,
|
||||
ENOSPC = 28,
|
||||
ESPIPE = 29,
|
||||
EROFS = 30,
|
||||
EPIPE = 32,
|
||||
EDOM = 33,
|
||||
ERANGE = 34,
|
||||
EAGAIN = 35,
|
||||
EWOULDBLOCK = EAGAIN,
|
||||
EINPROGRESS = 36,
|
||||
EALREADY = 37,
|
||||
ENOTSOCK = 38,
|
||||
EDESTADDRREQ = 39,
|
||||
EMLINK = 31,
|
||||
EMSGSIZE = 40,
|
||||
EPROTOTYPE = 41,
|
||||
ENOPROTOOPT = 42,
|
||||
EPROTONOSUPPORT = 43,
|
||||
EOPNOTSUPP = 45,
|
||||
EAFNOSUPPORT = 47,
|
||||
EADDRINUSE = 48,
|
||||
EADDRNOTAVAIL = 49,
|
||||
ENETDOWN = 50,
|
||||
ENETUNREACH = 51,
|
||||
ENETRESET = 52,
|
||||
ECONNABORTED = 53,
|
||||
ECONNRESET = 54,
|
||||
ENOBUFS = 55,
|
||||
EISCONN = 56,
|
||||
ENOTCONN = 57,
|
||||
ETIMEDOUT = 60,
|
||||
ECONNREFUSED = 61,
|
||||
ELOOP = 62,
|
||||
ENAMETOOLONG = 63,
|
||||
EHOSTUNREACH = 65,
|
||||
ENOTEMPTY = 66,
|
||||
ENOLCK = 77,
|
||||
ENOSYS = 78,
|
||||
ENOMSG = 83,
|
||||
EILSEQ = 86
|
||||
};
|
||||
|
||||
|
||||
/*************
|
||||
** fcntl.h **
|
||||
*************/
|
||||
|
||||
enum {
|
||||
O_RDONLY = 0x0000,
|
||||
O_WRONLY = 0x0001,
|
||||
O_RDWR = 0x0002,
|
||||
O_CREAT = 0x0200,
|
||||
O_TRUNC = 0x0400,
|
||||
O_EXCL = 0x0800
|
||||
};
|
||||
|
||||
enum { F_SETFD = 2 };
|
||||
|
||||
enum { FD_CLOEXEC = 1 };
|
||||
|
||||
int open(const char *pathname, int flags, ...);
|
||||
int fcntl(int fd, int cmd, ... /* arg */ );
|
||||
|
||||
|
||||
/**************
|
||||
** signal.h **
|
||||
**************/
|
||||
|
||||
enum { SIGTERM = 15 };
|
||||
|
||||
int kill(pid_t pid, int sig);
|
||||
|
||||
|
||||
/*************
|
||||
** ctype.h **
|
||||
*************/
|
||||
|
||||
int isalnum(int c);
|
||||
int isalpha(int c);
|
||||
int isascii(int c);
|
||||
int isblank(int c);
|
||||
int iscntrl(int c);
|
||||
int isdigit(int c);
|
||||
int isgraph(int c);
|
||||
int islower(int c);
|
||||
int isprint(int c);
|
||||
int ispunct(int c);
|
||||
int isspace(int c);
|
||||
int isupper(int c);
|
||||
int isxdigit(int c);
|
||||
|
||||
int toupper(int c);
|
||||
int tolower(int c);
|
||||
|
||||
|
||||
/**************
|
||||
** locale.h **
|
||||
**************/
|
||||
|
||||
struct lconv;
|
||||
char *setlocale(int category, const char *locale);
|
||||
struct lconv *localeconv(void);
|
||||
|
||||
enum {
|
||||
LC_ALL = 0,
|
||||
LC_COLLATE = 1,
|
||||
LC_CTYPE = 2,
|
||||
LC_MONETARY = 3,
|
||||
LC_NUMERIC = 4,
|
||||
LC_TIME = 5
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** math.h **
|
||||
************/
|
||||
|
||||
double acos(double x);
|
||||
double asin(double x);
|
||||
double atan(double x);
|
||||
double atan2(double y, double x);
|
||||
double ceil(double x);
|
||||
double cos(double x);
|
||||
double cosh(double x);
|
||||
double exp(double x);
|
||||
double fabs(double x);
|
||||
double floor(double x);
|
||||
double fmod(double x, double y);
|
||||
double frexp(double x, int *exp);
|
||||
double ldexp(double x, int exp);
|
||||
double log(double x);
|
||||
double log10(double x);
|
||||
double modf(double x, double *iptr);
|
||||
double pow(double x, double y);
|
||||
double sin(double x);
|
||||
double sinh(double x);
|
||||
double sqrt(double x);
|
||||
double tan(double x);
|
||||
double tanh(double x);
|
||||
|
||||
|
||||
/**************
|
||||
** assert.h **
|
||||
**************/
|
||||
|
||||
#define assert(e) ((void)0)
|
||||
|
||||
|
||||
/***********
|
||||
** elf.h **
|
||||
***********/
|
||||
|
||||
/*
|
||||
* The following defines and types are solely needed to compile libgcc's
|
||||
* 'unwind-dw2-fde-glibc.c' in libc mode. This is needed because Genode's
|
||||
* dynamic linker relies on the the "new" exception mechanism, which is not
|
||||
* compiled-in when compiling libgcc with the 'inhibit_libc' flag.
|
||||
*
|
||||
* The following types are loosely based on glibc's 'link.h' and 'elf.h'.
|
||||
*/
|
||||
|
||||
typedef __uint32_t Elf64_Word;
|
||||
typedef __uint64_t Elf64_Addr;
|
||||
typedef __uint64_t Elf64_Xword;
|
||||
typedef __uint64_t Elf64_Off;
|
||||
typedef __uint16_t Elf64_Half;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef __uint32_t Elf32_Word;
|
||||
typedef __uint32_t Elf32_Addr;
|
||||
typedef __uint64_t Elf32_Xword;
|
||||
typedef __uint32_t Elf32_Off;
|
||||
typedef __uint16_t Elf32_Half;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_LOOS 0x60000000
|
||||
|
||||
|
||||
/************
|
||||
** link.h **
|
||||
************/
|
||||
|
||||
/* definitions according to glibc */
|
||||
|
||||
#ifdef _LP64
|
||||
#define ElfW(type) Elf64_##type
|
||||
#else
|
||||
#define ElfW(type) Elf32_##type
|
||||
#endif /* _LP64 */
|
||||
|
||||
struct dl_phdr_info
|
||||
{
|
||||
ElfW(Addr) dlpi_addr;
|
||||
const char *dlpi_name;
|
||||
const ElfW(Phdr) *dlpi_phdr;
|
||||
ElfW(Half) dlpi_phnum;
|
||||
unsigned long long int dlpi_adds;
|
||||
unsigned long long int dlpi_subs;
|
||||
size_t dlpi_tls_modid;
|
||||
void *dlpi_tls_data;
|
||||
};
|
||||
|
||||
extern int dl_iterate_phdr(int (*__callback) (struct dl_phdr_info *,
|
||||
size_t, void *), void *__data);
|
||||
|
||||
|
||||
/****************
|
||||
** features.h **
|
||||
****************/
|
||||
|
||||
/* let check at the beginning of 'gcc/unwind-dw2-fde-glibc.c' pass */
|
||||
#define __GLIBC__ 99
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBC_STUB_H_ */
|
||||
|
||||
906
tool/parse_cxx
Executable file
906
tool/parse_cxx
Executable file
@@ -0,0 +1,906 @@
|
||||
#!/usr/bin/tclsh
|
||||
|
||||
#
|
||||
# \brief Regular-expression-based C++ parser
|
||||
# \author Norman Feske
|
||||
# \date 2007-08-15
|
||||
#
|
||||
|
||||
# check command line arguments
|
||||
set config_out_xml [regsub -- "-format +xml" $argv "" argv]
|
||||
set config_out_tokens [regsub -- "-format +tokens" $argv "" argv]
|
||||
set config_out_source [regsub -- "-format +source" $argv "" argv]
|
||||
set config_whitespace [regsub -- "-whitespace" $argv "" argv]
|
||||
|
||||
# read file
|
||||
set input_pathname [lindex $argv 0]
|
||||
if {[catch {
|
||||
|
||||
#
|
||||
# Create root node of the syntax tree
|
||||
#
|
||||
set txt(0) [exec cat $input_pathname]
|
||||
set typ(0) content
|
||||
set num 1
|
||||
}]} {
|
||||
foreach line {
|
||||
""
|
||||
"Parse C++ file and output syntax tree."
|
||||
""
|
||||
" usage: parse_cxx \[-whitespace\] \[-format {xml|tokens|source}\] <source_file>"
|
||||
""
|
||||
"The supported output formats are:"
|
||||
""
|
||||
" xml - XML-based representation"
|
||||
" tokens - List of tokens (parser-internal representation)"
|
||||
" source - Source as generated from syntax tree (for debugging)"
|
||||
""
|
||||
"If the '-whitespace' argument is specified, whitespaces get translated to tokens."
|
||||
""
|
||||
} { puts stderr $line }
|
||||
|
||||
exit -1;
|
||||
}
|
||||
|
||||
# do not stop parsing (this variable is only used for debugging)
|
||||
set stop 0
|
||||
|
||||
#
|
||||
# Detect occurence of magic characters that we
|
||||
# use to mark substitutions in the syntax tree.
|
||||
#
|
||||
if {[regexp {[<5B><><EFBFBD>]} $txt(0) magic_char]} {
|
||||
puts stderr "Error: Source code contains reserved character '$magic_char'."
|
||||
puts stderr " The following characters are reserved: '<27>', '<27>', '<27>'"
|
||||
exit -1;
|
||||
}
|
||||
|
||||
#
|
||||
# Replace all '&' characters from the original input
|
||||
# because they cause trouble with the regexp command.
|
||||
#
|
||||
regsub -all {&} $txt(0) "<22>" txt(0)
|
||||
|
||||
|
||||
##
|
||||
# Extract expression from content
|
||||
#
|
||||
# All expressions that occur in the token types 'typelist'
|
||||
# and that match the 'subexpr' criterion get replaced in
|
||||
# their original token by a reference tag and form a new
|
||||
# token of the type 'newtype'.
|
||||
#
|
||||
# The reference is coded as <20><token_type><token_id><3E>.
|
||||
# Since the reference has the type coded in, we can
|
||||
# match sub tokens of specific types via plain regular
|
||||
# expressions.
|
||||
##
|
||||
proc extract {newtype subexpr typelist} {
|
||||
global num txt typ stop
|
||||
set old_num $num
|
||||
|
||||
if {$stop} { return }
|
||||
|
||||
for {set i 0} {$i < $old_num} {incr i} {
|
||||
if {[lsearch $typelist $typ($i)] > -1} {
|
||||
while {[regexp $subexpr $txt($i) mid]} {
|
||||
|
||||
# new sub text #
|
||||
set typ($num) $newtype
|
||||
set txt($num) $mid
|
||||
|
||||
# substitute expression by a reference #
|
||||
regsub $subexpr $txt($i) "<22>$newtype$num<75>" txt($i)
|
||||
incr num
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Extract operations
|
||||
#
|
||||
# \param op_name name of operator
|
||||
# \param op_type type of operator, can be "binary", "pre", or "post"
|
||||
# \param op_dir direction of application, can be "ltr" (left to
|
||||
# right) or "trl" (right to left)
|
||||
##
|
||||
proc extract_op {newtype op_name op_type op_dir typelist} {
|
||||
global num txt typ stop
|
||||
set old_num $num
|
||||
|
||||
if {$stop} { return }
|
||||
|
||||
# Extracting operators is context-sensitive. In particular,
|
||||
# unary operators must not be applied if they have an
|
||||
# operand as neighbor. Hence, we construct a pattern with
|
||||
# three subpatterns, one for the leading context, one for
|
||||
# the new operand sub token, and one for the trailing context.
|
||||
|
||||
if {$op_dir == "ltr"} {
|
||||
set lpattern ""
|
||||
} else {
|
||||
set lpattern ".*"
|
||||
}
|
||||
|
||||
set repl_left {\1}
|
||||
if {$op_type == "pre"} {
|
||||
set pattern "(^|$lpattern\(?:\[^i\]er|\[^e\]r|\[^r\\d\]\)\\d+<2B>\\s*)(<28>$op_name\\d+<2B>\\s*<2A>identifier\\d+<2B>)" }
|
||||
set repl_right {}
|
||||
if {$op_type == "post"} {
|
||||
set pattern "($lpattern)(<28>identifier\\d+<2B>\\s*<2A>$op_name\\d+<2B>\\s*)((<28>(\[^i\]|i\[^d\]|id\[^e\]))|;|\$)" }
|
||||
set repl_right {\3}
|
||||
if {$op_type == "binary"} {
|
||||
set pattern "($lpattern)(<28>identifier\\d+<2B>\\s*<2A>$op_name\\d+<2B>\\s*<2A>identifier\\d+<2B>)"
|
||||
set repl_right {}
|
||||
}
|
||||
|
||||
for {set i 0} {$i < $old_num} {incr i} {
|
||||
if {[lsearch $typelist $typ($i)] > -1} {
|
||||
|
||||
while {[regexp $pattern $txt($i) dummy lcontext match rcontext]} {
|
||||
|
||||
# new sub text #
|
||||
set typ($num) $newtype
|
||||
set txt($num) $match
|
||||
|
||||
set old_txt $txt($i)
|
||||
|
||||
# substitute expression by a reference #
|
||||
regsub $pattern $txt($i) "$repl_left<66>$newtype$num<75>$repl_right" txt($i)
|
||||
|
||||
incr num
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc extract_operations { from } {
|
||||
set operators { { doublecolon binary ltr }
|
||||
{ parenblk post ltr # function call }
|
||||
{ arrayindex post ltr }
|
||||
{ deref binary ltr }
|
||||
{ dot binary ltr }
|
||||
{ incr post ltr }
|
||||
{ decr post ltr }
|
||||
{ not pre rtl }
|
||||
{ tilde pre rtl }
|
||||
{ incr pre rtl }
|
||||
{ decr pre rtl }
|
||||
{ minus pre rtl }
|
||||
{ plus pre rtl }
|
||||
{ star pre rtl # deref }
|
||||
{ amper pre rtl # addrof }
|
||||
{ keysizeof pre rtl }
|
||||
{ parenblk pre rtl # cast }
|
||||
{ star binary ltr }
|
||||
{ div binary ltr }
|
||||
{ mod binary ltr }
|
||||
{ plus binary ltr }
|
||||
{ minus binary ltr }
|
||||
{ lshift binary ltr }
|
||||
{ rshift binary ltr }
|
||||
{ less binary ltr }
|
||||
{ lessequal binary ltr }
|
||||
{ greater binary ltr }
|
||||
{ greaterequal binary ltr }
|
||||
{ equal binary ltr }
|
||||
{ notequal binary ltr }
|
||||
{ amper binary ltr # bitand }
|
||||
{ xor binary ltr }
|
||||
{ bitor binary ltr }
|
||||
{ and binary ltr }
|
||||
{ or binary ltr }
|
||||
{ cond binary ltr }
|
||||
{ assign binary rtl }
|
||||
{ assignopplus binary rtl }
|
||||
{ assignopminus binary rtl }
|
||||
{ assignopmult binary rtl }
|
||||
{ assignopdiv binary rtl }
|
||||
{ assignopmod binary rtl }
|
||||
{ assignopbitand binary rtl }
|
||||
{ assignopbitxor binary rtl }
|
||||
{ assignopbitor binary rtl }
|
||||
{ assignoplshift binary rtl }
|
||||
{ assignoprshift binary rtl }
|
||||
{ keythrow pre rtl }
|
||||
{ comma binary ltr }
|
||||
}
|
||||
|
||||
foreach op $operators {
|
||||
set op_name [lindex $op 0]
|
||||
set op_type [lindex $op 1]
|
||||
set op_dir [lindex $op 2]
|
||||
extract_op identifier $op_name $op_type $op_dir $from
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc extract_enum_operations { from } {
|
||||
set operators { { doublecolon binary ltr }
|
||||
{ parenblk post ltr # function call }
|
||||
{ not pre rtl }
|
||||
{ tilde pre rtl }
|
||||
{ minus pre rtl }
|
||||
{ plus pre rtl }
|
||||
{ amper pre rtl # addrof }
|
||||
{ keysizeof pre rtl }
|
||||
{ star binary ltr }
|
||||
{ div binary ltr }
|
||||
{ mod binary ltr }
|
||||
{ plus binary ltr }
|
||||
{ minus binary ltr }
|
||||
{ lshift binary ltr }
|
||||
{ rshift binary ltr }
|
||||
{ less binary ltr }
|
||||
{ lessequal binary ltr }
|
||||
{ greater binary ltr }
|
||||
{ greaterequal binary ltr }
|
||||
{ equal binary ltr }
|
||||
{ notequal binary ltr }
|
||||
{ amper binary ltr # bitand }
|
||||
{ xor binary ltr }
|
||||
{ bitor binary ltr }
|
||||
{ and binary ltr }
|
||||
{ or binary ltr }
|
||||
{ cond binary ltr }
|
||||
}
|
||||
|
||||
foreach op $operators {
|
||||
set op_name [lindex $op 0]
|
||||
set op_type [lindex $op 1]
|
||||
set op_dir [lindex $op 2]
|
||||
extract_op identifier $op_name $op_type $op_dir $from
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Refine types of sub tokens
|
||||
#
|
||||
# This function changes the type of sub tokens of the specified
|
||||
# environment token to the specified replacement type. It is
|
||||
# used to specialize token types depending on their environment.
|
||||
# For example, for turning blocks within classes into specialized
|
||||
# declaration blocks, for which other rules apply than for
|
||||
# function-body blocks.
|
||||
##
|
||||
proc refine_sub_tokens {env_type sub_type repl_sub_type} {
|
||||
global num txt typ stop
|
||||
|
||||
if {$stop} { return }
|
||||
|
||||
# iterate through token list in search of env-typed tokens
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
if {$typ($i) == $env_type} {
|
||||
|
||||
set env $txt($i)
|
||||
while {[regexp "<22>$sub_type\(\\d+)<29>" $env dummy sub_token_idx]} {
|
||||
set typ($sub_token_idx) $repl_sub_type
|
||||
regsub "<22>$sub_type\(\\d+)<29>" $env "<22>$repl_sub_type$sub_token_idx<64>" env
|
||||
}
|
||||
|
||||
# update environment token
|
||||
set txt($i) $env
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#####################################################
|
||||
## Rules for splitting the input into its elements ##
|
||||
#####################################################
|
||||
|
||||
#
|
||||
# Starting with only the root token (content0) of the syntax tree
|
||||
# containing the whole source code as one string, we extract
|
||||
# typed sub tokens to partition the string into parts of distinct
|
||||
# meanings (token types). In the process of subsequently
|
||||
# applying extraction rules to specific token types, a syntax
|
||||
# tree is formed.
|
||||
#
|
||||
|
||||
# extract line comments
|
||||
extract lcomment {/\*[^\n]*?\*/} content
|
||||
|
||||
# extract multi-line comments
|
||||
extract mlcomment {/\*.*?\*/} content
|
||||
|
||||
extract quotedchar {'(.|\\.)'} content
|
||||
|
||||
# extract strings
|
||||
#
|
||||
# Strings may contain quoted '"' characters.
|
||||
#
|
||||
extract string {\"([^\"]|\")*?\"} content
|
||||
|
||||
# extract C++-style comments
|
||||
extract cxxcomment {\/\/[^\n]*} content
|
||||
|
||||
# extract preprocessor directives
|
||||
#
|
||||
# Preprocessor macros may span over multiple lines if a
|
||||
# backslash is supplied at the end of each line.
|
||||
#
|
||||
extract preproc {#([^\n]|\\\n)*} content
|
||||
|
||||
extract preprefix {#} preproc
|
||||
|
||||
# extract keywords
|
||||
foreach keyword {
|
||||
private public protected unsigned extern
|
||||
while for if else switch do return typedef
|
||||
static_cast reinterpret_cast dynamic_cast
|
||||
using namespace class struct union enum template
|
||||
const inline static virtual friend explicit
|
||||
volatile case default operator new throw
|
||||
try catch continue sizeof asm
|
||||
GENODE_RPC GENODE_RPC_THROW
|
||||
GENODE_RPC_INTERFACE GENODE_RPC_INTERFACE_INHERIT
|
||||
GENODE_TYPE_LIST
|
||||
} {
|
||||
set keytag $keyword
|
||||
regsub -all {_} $keytag "" keytag
|
||||
set keytag [string tolower $keytag]
|
||||
extract "key$keytag" "\\m$keyword\\M" content
|
||||
}
|
||||
|
||||
# extract extern "C"
|
||||
extract "keyexternc" {<7B>keyextern\d+<2B>\s*<2A>string\d+<2B>} content
|
||||
|
||||
# fold parenthesis and blocks
|
||||
extract parenblk {\([^()]*?\)} {content parenblk}
|
||||
extract block {\{[^{}]*?\}} {content parenblk block}
|
||||
extract openbrace "\{" block
|
||||
extract closebrace "\}" block
|
||||
extract openparen {\(} parenblk
|
||||
extract closeparen {\)} parenblk
|
||||
|
||||
extract externcblk {<7B>keyexternc\d+<2B>\s*<2A>block\d+<2B>} content
|
||||
|
||||
# extract template argument blocks
|
||||
extract tplargs {<[^<>{}]*>$} {content block parenblk}
|
||||
extract tplargs {<[^<>{}]*>(?=[^>])} {content block parenblk}
|
||||
|
||||
# extract special characters
|
||||
extract equal {==} {content block parenblk}
|
||||
extract assignopplus {\+=} {content block parenblk}
|
||||
extract assignopminus {\-=} {content block parenblk}
|
||||
extract assignopmult {\*=} {content block parenblk}
|
||||
extract assignopdiv {\/=} {content block parenblk}
|
||||
extract assignopmod {%=} {content block parenblk}
|
||||
extract assignopbitor {\|=} {content block parenblk}
|
||||
extract assignopbitand {<7B>=} {content block parenblk}
|
||||
extract assignopbitxor {\^=} {content block parenblk}
|
||||
extract assignopneq {\!=} {content block parenblk}
|
||||
extract assignoplshift {<<=} {content block parenblk}
|
||||
extract assignoprshift {>>=} {content block parenblk}
|
||||
extract incr {\+\+} {content block parenblk}
|
||||
extract decr {\-\-} {content block parenblk}
|
||||
extract doublecolon {::} {content block parenblk}
|
||||
extract or {\|\|} {content block parenblk}
|
||||
extract bitor {\|} {content block parenblk}
|
||||
extract and {<7B><>} {content block parenblk}
|
||||
extract amper {<7B>} {content block parenblk}
|
||||
extract plus {\+} {content block parenblk}
|
||||
extract div {\/} {content block parenblk}
|
||||
extract star {\*} {content block parenblk}
|
||||
extract notequal {\!=} {content block parenblk}
|
||||
extract not {\!} {content block parenblk}
|
||||
extract deref {\->} {content block parenblk}
|
||||
extract dot {\.} {content block parenblk}
|
||||
extract tilde {~} {content block parenblk}
|
||||
extract lshift {<<} {content block parenblk}
|
||||
extract rshift {>>} {content block parenblk}
|
||||
extract greaterequal {>=} {content block parenblk}
|
||||
extract lessequal {<=} {content block parenblk}
|
||||
extract greater {>} {content block parenblk}
|
||||
extract less {<} {content block parenblk}
|
||||
extract minus {\-} {content block parenblk}
|
||||
extract mod {%} {content block parenblk}
|
||||
extract xor {\^} {content block parenblk}
|
||||
extract question {\?} {content block parenblk}
|
||||
extract comma {,} {content block parenblk}
|
||||
extract assign {=} {content block parenblk}
|
||||
|
||||
extract attribute {__attribute__\s*<2A>parenblk\d+<2B>} {content block parenblk}
|
||||
|
||||
# extract identifiers
|
||||
extract identifier {([\w_][\w\d_]*)+(?=[^<5E>]*(<28>|$))} {content parenblk block}
|
||||
|
||||
extract identifier {<7B>quotedchar\d+<2B>} {content parenblk block}
|
||||
|
||||
# merge template arguments with the predecessing identifier
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>tplargs\d+<2B>} {content block parenblk}
|
||||
|
||||
# extract using namespace
|
||||
extract using {<7B>keyusing\d+<2B>\s*<2A>keynamespace\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
|
||||
|
||||
# extract casted identifiers and thereby potentially creating new valid assignments
|
||||
extract identifier {<7B>key(static|dynamic|reinterpret)cast\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>parenblk\d+<2B>} {block}
|
||||
|
||||
#
|
||||
# XXX the C++ precedence rules are not fully implemented
|
||||
#
|
||||
|
||||
# extract namespaced identifiers
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
|
||||
|
||||
# extract identifiers in the root namespace
|
||||
extract identifier {<7B>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
|
||||
|
||||
extract whilecond {<7B>keywhile\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
extract forcond {<7B>keyfor\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
extract ifcond {<7B>keyif\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
extract switchcond {<7B>keyswitch\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
extract catchcond {<7B>keycatch\d+<2B>\s*<2A>parenblk\d+<2B>} block
|
||||
|
||||
# extract forward declarations of structs and classes
|
||||
extract classdecl {<7B>keyclass\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
|
||||
extract structdecl {<7B>keystruct\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
|
||||
|
||||
# extract classes
|
||||
extract class {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyclass\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
|
||||
extract struct {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keystruct\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
|
||||
extract union {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyunion\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
|
||||
extract enum {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyenum\d+<2B>\s*[^;]*;} {content block}
|
||||
|
||||
extract inherit {:.*?(?=\s*<2A>block\d+<2B>)} {class struct union}
|
||||
|
||||
# partition block types into more expressive sub types
|
||||
refine_sub_tokens class block classblock
|
||||
refine_sub_tokens struct block classblock
|
||||
refine_sub_tokens union block classblock
|
||||
refine_sub_tokens enum block enumblock
|
||||
|
||||
extract_enum_operations enumblock
|
||||
|
||||
#enumvalue {<7B>identifier\d+<2B>[^,]*?(?=<3D>comma\d+<2B>)} enumblock
|
||||
extract enumentry {<7B>identifier\d+<2B>\s*<2A>assign\d+<2B>\s*<2A>identifier\d+<2B>} enumblock
|
||||
extract enumvalue {<7B>identifier\d+<2B>$} enumentry
|
||||
extract enumentry {<7B>identifier\d+<2B>} enumblock
|
||||
|
||||
# extract template classes
|
||||
extract tplclassdecl {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>classdecl\d+<2B>} {content block classblock}
|
||||
extract tplstructdecl {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>structdecl\d+<2B>} {content block classblock}
|
||||
|
||||
extract tplclass {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>class\d+<2B>} {content block classblock}
|
||||
extract tplstruct {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>struct\d+<2B>} {content block classblock}
|
||||
|
||||
refine_sub_tokens tplclassdecl classdecl class;
|
||||
refine_sub_tokens tplstructdecl structdecl class;
|
||||
|
||||
extract arrayindex {\[[^\]]*\]} {content classblock block arrayindex}
|
||||
|
||||
# detect case labels within switch statements and protection labels
|
||||
extract caselabel {<7B>keycase\d+<2B>[^:]+:} {block}
|
||||
extract caselabel {<7B>keydefault\d+<2B>:} {block}
|
||||
foreach keyword { private public protected } {
|
||||
set label label
|
||||
extract "$keyword$label" "<22>key$keyword\\d+<2B>:" {classblock} }
|
||||
|
||||
extract identifier {<7B>identifier\d+<2B>+\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} {content classblock}
|
||||
|
||||
# extract class initialize list
|
||||
extract initializer {:\s*<2A>identifier\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>comma\d+<2B>\s*<2A>identifier\d+<2B>\s*<2A>parenblk\d+<2B>)*} {content classblock}
|
||||
extract colon {:} {initializer inherit}
|
||||
|
||||
# extract asm blocks
|
||||
extract asm {<7B>keyasm\d+<2B>\s*(<28>keyvolatile\d+<2B>)?\s*<2A>parenblk\d+<2B>} {content block}
|
||||
|
||||
# extract Genode-specific RPC declaration macros
|
||||
set genode_macros { genoderpc genoderpcthrow genoderpcinterface genoderpcinterfaceinherit genodetypelist }
|
||||
foreach key $genode_macros {
|
||||
extract $key "<22>key$key\\d+<2B>\\s*<2A>parenblk\\d+<2B>\\s*" { classblock parenblk } }
|
||||
|
||||
foreach key $genode_macros {
|
||||
refine_sub_tokens $key parenblk macroargblk }
|
||||
|
||||
# extract functions
|
||||
extract operatorfunction {<7B>keyoperator\d+<2B>\s*<2A>[^<5E>]+\d+<2B>\s*<2A>parenblk\d+<2B>} {content classblock}
|
||||
extract funcptr {<7B>parenblk\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block identifier parenblk}
|
||||
extract function {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block initializer}
|
||||
|
||||
extract destfunction {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {content classblock}
|
||||
extract identifier {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>} destfunction
|
||||
|
||||
extract identifier {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {parenblk block identifier initializer}
|
||||
extract identifier {<7B>parenblk\d+<2B>} {parenblk block}
|
||||
#extract_operations parenblk
|
||||
|
||||
# extract arrays
|
||||
extract array {(<28>identifier\d+<2B>\s*)(<28>arrayindex\d+<2B>\s*)+} {content classblock block}
|
||||
extract identifier {<7B>array\d+<2B>} {content classblock block}
|
||||
|
||||
# extract assignments
|
||||
extract identifier {(?=(\s*|;))(<28>star\d+<2B>\s*)*<2A>identifier\d+<2B>\s*<2A>assign\w*\d+<2B>[^;]*} block
|
||||
|
||||
# extract throw statements
|
||||
extract identifier {(?=(\s*|;))<29>keythrow\d+<2B>\s*[^;]*} block
|
||||
|
||||
# extract stream operators
|
||||
#extract lhidentifier {(?=(\s*|;))[^;]*?<3F>(lshift|rshift)\d+<2B>[^;]*} block
|
||||
|
||||
# extract uses of the new operator
|
||||
extract identifier {<7B>keynew\d+<2B>\s*(<28>parenblk\d+<2B>\s*)?<3F>function\d+<2B>} block
|
||||
|
||||
# extract return statements
|
||||
extract return {<7B>keyreturn\d+<2B>[^;]*} {block}
|
||||
|
||||
# extract modifiers
|
||||
extract modifier {(<28>key(extern|externc|const|static|inline|virtual|volatile)\d+<2B>\s*)+} {content classblock block}
|
||||
|
||||
# extract function declarations
|
||||
extract funcdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)*<2A>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)*(<28>assign\d+<2B>\s*<2A>identifier\d+<2B>)?\s*;} {content block classblock}
|
||||
|
||||
# extract function implementations
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<3F>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>operatorfunction\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
|
||||
# extract function implementations
|
||||
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<3F>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
|
||||
|
||||
# extract template functions
|
||||
extract tplfunc {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>funcimpl\d+<2B>} {content block classblock}
|
||||
|
||||
# extract template functions declarations
|
||||
extract tplfuncdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>funcdecl\d+<2B>} {content block classblock}
|
||||
|
||||
# extract destructor implementations
|
||||
extract destimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>modifier\d+<2B>\s*)?<3F>tilde\d+<2B><>function\d+<2B>\s*<2A>block\d+<2B>[;\t ]*} {content classblock}
|
||||
refine_sub_tokens destimpl destfunction function
|
||||
|
||||
# extract constructor implementations
|
||||
extract constimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyexplicit)\d+<2B>\s*)*<2A>function\d+<2B>\s*(<28>initializer\d+<2B>\s*)?\s*<2A>block\d+<2B>[;\t ]*} {content classblock}
|
||||
|
||||
# extract destructor declarations
|
||||
extract destdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>modifier\d+<2B>\s*)?<3F>tilde\d+<2B><>function\d+<2B>\s*(<28>assign\d+<2B>\s+<2B>identifier\d+<2B>)?\s*;} {classblock}
|
||||
|
||||
# extract constructor declarations
|
||||
extract constdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>keyexplicit\d+<2B>[ \t]*)?<3F>function\d+<2B>\s*(<28>assign\d+<2B>\s+<2B>identifier\d+<2B>)?\s*;} {classblock}
|
||||
|
||||
# extract friendship declarations
|
||||
extract frienddecl {<7B>keyfriend\d+<2B>\s*<2A>classdecl\d+<2B>} {classblock}
|
||||
|
||||
# classify function signatures and their containing argument-parenthesis blocks
|
||||
foreach env_type [list destdecl constdecl destimpl constimpl funcimpl funcdecl] {
|
||||
refine_sub_tokens $env_type function funcsignature }
|
||||
refine_sub_tokens funcsignature parenblk argparenblk
|
||||
|
||||
extract_operations parenblk
|
||||
extract modifier {(<28>key(const|volatile)\d+<2B>\s*)+} {argparenblk}
|
||||
|
||||
# extract pure-virtual assignments
|
||||
extract virtassign {<7B>assign\d+<2B>\s+<2B>identifier\d+<2B>} funcdecl
|
||||
|
||||
# extract return values
|
||||
extract retval {(<28>keyunsigned\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} {funcdecl funcimpl}
|
||||
extract identifier {<7B>keyunsigned\d+<2B>\s*(<28>identifier\d+<2B>)?} {retval}
|
||||
|
||||
# extract single argument declarations within argument-parenthesis blocks
|
||||
extract argdecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*<2A>identifier\d+<2B>} {argparenblk tplargs}
|
||||
|
||||
extract argname {<7B>identifier\d+<2B>$} {argdecl}
|
||||
extract argtype {^(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*} {argdecl}
|
||||
|
||||
# extract argument-declaration types
|
||||
extract argdecltype {^<5E>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} argdecl
|
||||
|
||||
# extract typedefs
|
||||
extract typedef {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytypedef\d+<2B>(\s*<2A>identifier\d+<2B>)+\s*;} {content classblock block}
|
||||
extract typename {<7B>identifier\d+<2B>(?=;)} typedef
|
||||
|
||||
# extract function pointers
|
||||
extract vardecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)((\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*(<28>funcptr\d+<2B>)\s*(:\s*<2A>identifier\d+<2B>)?\s*(<28>assign\d+<2B>[^;]*?)?\s*(<28>comma\d+<2B>)?\s*)+;} {content classblock block}
|
||||
|
||||
# extract variable declarations (type + any number of comma-separated variables + optional tailing comment)
|
||||
extract vardecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)((\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*(<28>(identifier|array)\d+<2B>)\s*(:\s*<2A>identifier\d+<2B>)?\s*(<28>assign\d+<2B>[^;]*?)?\s*(<28>comma\d+<2B>)?\s*)+;} {content classblock block}
|
||||
|
||||
# extract commented variable declaration
|
||||
extract commentedvardecl {<7B>vardecl\d+<2B>\s*<2A>m?lcomment\d+<2B>(\s*<2A>lcomment\d<>)*} {content classblock block}
|
||||
|
||||
# extract valid declaration sequences
|
||||
set elem "(mlcomment|lcomment|vardecl|array|commentedvardecl|typedef|funcimpl|funcdecl|enum|class|struct|union|constimpl|constdecl|destimpl|destdecl|tplfunc|tplfuncdecl|tplstruct|tplstructdecl|tplclass|tplclassdecl|frienddecl|classdecl|structdecl)"
|
||||
extract declseq "<22>$elem\\d+<2B>(\\s*<2A>$elem\\d+<2B>)*" {classblock}
|
||||
|
||||
# group protection scopes with corresponding declaration sequences
|
||||
foreach keyword { private public protected } {
|
||||
set label label
|
||||
extract $keyword "<22>$keyword$label\\d+<2B>\\s*<2A>declseq\\d+<2B>" {classblock} }
|
||||
|
||||
# extract protection-scope labels
|
||||
extract label {<7B>key(private|public|protected)\d+<2B>:} {private public protected}
|
||||
|
||||
# extract name spaces
|
||||
extract namespace {<7B>keynamespace\d+<2B>\s*<2A>identifier\d+<2B>\s*<2A>block\d+<2B>} {content block}
|
||||
refine_sub_tokens namespace block namespaceblock
|
||||
|
||||
#
|
||||
# The remaining block tokens are code blocks. So we can
|
||||
# apply code-specific rules to them.
|
||||
#
|
||||
|
||||
extract identifier {<7B>function\d+<2B>} block
|
||||
|
||||
extract_operations {block identifier}
|
||||
|
||||
# extract statements from remaining code blocks
|
||||
extract statement {<7B>asm\d+<2B>;} block
|
||||
extract statement {<7B>identifier\d+<2B>;} block
|
||||
extract statement {<7B>return\d+<2B>;} {block}
|
||||
extract statement {<7B>keycontinue\d+<2B>\s*;} block
|
||||
|
||||
# extract try-catch statements
|
||||
extract statement {<7B>keytry\d+<2B>\s*<2A>block\d+<2B>(\s*<2A>catchcond\d+<2B>\s*<2A>block\d+<2B>)+} {block}
|
||||
|
||||
# wrap blocks into statements
|
||||
extract statement {<7B>block\d+<2B>} {block statement}
|
||||
|
||||
# empty statements (all normal semicolons should be encapsulated in statements now)
|
||||
extract statement {;} {block}
|
||||
|
||||
# turn control structures into statements
|
||||
set pattern_ifelse {(<28>ifcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>keyelse\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>)}
|
||||
set pattern_if {(<28>ifcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>(?!(\s|<7C>m?lcomment\d+<2B>)*<2A>keyelse))}
|
||||
set pattern_for {(<28>(while|for|switch)cond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>)}
|
||||
extract statement "($pattern_ifelse|$pattern_if|$pattern_for)" {block statement}
|
||||
|
||||
# extract control-structure types
|
||||
extract ifelse $pattern_ifelse {statement}
|
||||
extract if $pattern_if {statement}
|
||||
extract for {<7B>forcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*(<28>statement\d+<2B>|;)} {statement}
|
||||
extract while {<7B>whilecond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*(<28>statement\d+<2B>|;)} {statement}
|
||||
extract switch {<7B>switchcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>} {statement}
|
||||
|
||||
# turn control-flow element into statements
|
||||
foreach type { ifelse if while for switch try } {
|
||||
extract statement "<22>$type\\d+<2B>" block }
|
||||
|
||||
# extract valid code sequences
|
||||
set elem "(mlcomment|vardecl|statement|lcomment)"
|
||||
extract codeseq "<22>$elem\\d+<2B>(\\s*<2A>$elem\\d+<2B>)*" {block}
|
||||
|
||||
#
|
||||
# Extract line breaks, spaces, and tabs from all types
|
||||
#
|
||||
|
||||
if {$config_whitespace} {
|
||||
set all_types ""
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
if {[lsearch $all_types $typ($i)] == -1} {
|
||||
lappend all_types $typ($i) }}
|
||||
|
||||
extract line {\n} $all_types
|
||||
extract align { +(?= )} $all_types
|
||||
extract space { } $all_types
|
||||
extract tab {\t} $all_types
|
||||
}
|
||||
|
||||
|
||||
###############################
|
||||
## Back-end helper functions ##
|
||||
###############################
|
||||
|
||||
##
|
||||
# Return name of reference token with specified index
|
||||
##
|
||||
proc token_by_idx {idx} {
|
||||
global typ;
|
||||
return "$typ($idx)$idx"
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return index of specified reference token
|
||||
##
|
||||
proc idx_of_token {token} {
|
||||
regexp {[0-9]+} $token idx
|
||||
return $idx
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return type of specified reference token
|
||||
##
|
||||
proc type_of_token {token} {
|
||||
regexp {[a-z]+} $token type
|
||||
return $type
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return marker for reference token
|
||||
##
|
||||
proc marker {token} {
|
||||
return "<22>$token<65>"
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return text referenced by token
|
||||
##
|
||||
proc token_text {token} {
|
||||
global txt
|
||||
return $txt([idx_of_token $token])
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Assign a line number to each reference token
|
||||
#
|
||||
# To be able to provide error messages including line numbers, we
|
||||
# determine the line number for each reference token and store it
|
||||
# as an attribute.
|
||||
#
|
||||
# The result of the function is stored in the global 'ln' array.
|
||||
##
|
||||
proc assign_line_numbers {{token content0}} {
|
||||
global ln curr_ln config_whitespace
|
||||
|
||||
if {$token == "content0"} { set curr_ln 1 }
|
||||
|
||||
# assign current line number to current token
|
||||
set ln([idx_of_token $token]) $curr_ln
|
||||
|
||||
# count occurrences of line breaks
|
||||
if {[type_of_token $token] == "line"} { incr curr_ln }
|
||||
if {!$config_whitespace && ($token == "\n")} { incr curr_ln }
|
||||
|
||||
# count lines for all sub-tokens
|
||||
set tex [token_text $token]
|
||||
while {$tex != ""} {
|
||||
|
||||
# count and eat raw line breaks (needed if 'whitespace' option is disabled)
|
||||
if {[regexp {^\n} $tex dummy]} {
|
||||
if {!$config_whitespace} { incr curr_ln }
|
||||
regsub {\n} $tex "" tex
|
||||
}
|
||||
|
||||
# ignore plain text
|
||||
if {[regexp {^[^<5E>\n]+} $tex plain]} {
|
||||
regsub {^[^<5E>\n]+} $tex "" tex }
|
||||
|
||||
# traverse into token
|
||||
if {[regexp {^<5E>(.+?)<29>} $tex dummy token]} {
|
||||
assign_line_numbers $token
|
||||
regsub {<7B>(.+?)<29>} $tex "" tex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Look up line number of specified reference token
|
||||
##
|
||||
proc line_number {token} {
|
||||
global ln
|
||||
return $ln([idx_of_token $token])
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Output tokens as valid Tcl List
|
||||
#
|
||||
# The result of this function can be used directly
|
||||
# as input by another Tcl script.
|
||||
##
|
||||
proc dump_tokens { } {
|
||||
global num typ txt
|
||||
set tokens [list]
|
||||
|
||||
for {set i 0} {($i < $num)} {incr i} {
|
||||
set token [token_by_idx $i]
|
||||
set text $txt($i)
|
||||
|
||||
lappend tokens [list $token [line_number $token] $text]
|
||||
}
|
||||
puts $tokens
|
||||
}
|
||||
|
||||
|
||||
##########################
|
||||
## Source-code back end ##
|
||||
##########################
|
||||
|
||||
##
|
||||
# Output syntax tree as source code
|
||||
#
|
||||
# This constructs the source code from the syntax tree. It is
|
||||
# useful to check the result against the input to make sure that
|
||||
# no information gets lost during the parsing procedure.
|
||||
##
|
||||
proc dump_source { } {
|
||||
global num typ txt
|
||||
|
||||
set output $txt(0)
|
||||
|
||||
while {[regexp {<7B>(.+?)<29>} $output dummy token]} {
|
||||
regsub $dummy $output [token_text $token] output
|
||||
}
|
||||
|
||||
# revert character substitutions of '&'
|
||||
regsub -all {<7B>} $output "\\\&" output
|
||||
|
||||
puts $output
|
||||
}
|
||||
|
||||
|
||||
##################
|
||||
## XML back end ##
|
||||
##################
|
||||
|
||||
proc dump_xml_subtree {token} {
|
||||
global dump_xml_indent line
|
||||
|
||||
set type [type_of_token $token]
|
||||
set tex [token_text $token]
|
||||
set line [line_number $token]
|
||||
|
||||
# shorten frequent leaf nodes
|
||||
if {$type == "line"} {
|
||||
puts "$dump_xml_indent<linebreak line=\"$line\"/>"
|
||||
} elseif {$type == "tab"} {
|
||||
puts "$dump_xml_indent<tab line=\"$line\"/>"
|
||||
} elseif {$type == "space"} {
|
||||
puts "$dump_xml_indent<space line=\"$line\"/>"
|
||||
} elseif {$type == "align"} {
|
||||
puts "$dump_xml_indent<align line=\"$line\">$tex</align>"
|
||||
} else {
|
||||
|
||||
puts "$dump_xml_indent<$type line=\"$line\">"
|
||||
set dump_xml_indent " $dump_xml_indent"
|
||||
|
||||
while {$tex != ""} {
|
||||
|
||||
# consume plain text
|
||||
if {[regexp {^[^<5E>]+} $tex plain]} {
|
||||
|
||||
# perform character substitutions for xml compliance
|
||||
regsub -all {<7B>} $plain "\\\&" plain
|
||||
regsub -all {<} $plain "\\\<" plain
|
||||
regsub -all {>} $plain "\\\>" plain
|
||||
regsub -all "\"" $plain "\\\"" plain
|
||||
regsub -all "'" $plain "\\\'" plain
|
||||
|
||||
puts "$dump_xml_indent<plain line=\"$line\">$plain</plain>"
|
||||
regsub {^[^<5E>]+} $tex "" tex
|
||||
}
|
||||
|
||||
# consume token
|
||||
if {[regexp {<7B>(.+?)<29>} $tex dummy token]} {
|
||||
dump_xml_subtree $token
|
||||
regsub {<7B>(.+?)<29>} $tex "" tex
|
||||
}
|
||||
}
|
||||
|
||||
regsub " " $dump_xml_indent "" dump_xml_indent
|
||||
puts "$dump_xml_indent</$type>"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Output syntax tree as xml
|
||||
##
|
||||
proc dump_xml { } {
|
||||
|
||||
# reset indentation level
|
||||
global dump_xml_indent
|
||||
set dump_xml_indent ""
|
||||
|
||||
# output subtree beginning with the root node
|
||||
dump_xml_subtree content0
|
||||
}
|
||||
|
||||
|
||||
##################
|
||||
## Main program ##
|
||||
##################
|
||||
|
||||
assign_line_numbers
|
||||
|
||||
if {$config_out_tokens} { dump_tokens }
|
||||
if {$config_out_xml} { dump_xml }
|
||||
if {$config_out_source} { dump_source }
|
||||
484
tool/run
Executable file
484
tool/run
Executable file
@@ -0,0 +1,484 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
#
|
||||
# \brief Framework for running automated tests
|
||||
# \author Norman Feske
|
||||
# \date 2010-03-16
|
||||
#
|
||||
# Usage: run --name <run_name> --include <run_script> ...
|
||||
#
|
||||
# The '--name' argument is used for as name for the boot-image and
|
||||
# temporary directories. The files includes via the '--include'
|
||||
# argument provide platform-specific additions/refinements to the
|
||||
# test framework as well as the actual test steps.
|
||||
#
|
||||
|
||||
|
||||
##
|
||||
# Remove leading and trailing whitespace from string
|
||||
#
|
||||
proc strip_whitespace {string} {
|
||||
regsub -all {^\s+} $string "" string
|
||||
regsub -all {\s+$} $string "" string
|
||||
return $string
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Check if the specified spec requirement is satisfied
|
||||
#
|
||||
proc assert_spec {spec} {
|
||||
global specs
|
||||
if {[lsearch $specs $spec] == -1} {
|
||||
puts stderr "Test requires '$spec'"
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Build genode targets specified as space-separated strings
|
||||
#
|
||||
# If the build process fails, this procedure will exit the program with
|
||||
# the error code -4.
|
||||
#
|
||||
proc build {targets} {
|
||||
|
||||
if {[get_cmd_switch --skip-build]} return
|
||||
|
||||
regsub -all {\s\s+} $targets " " targets
|
||||
puts "building targets: $targets"
|
||||
set timeout 10000
|
||||
set pid [eval "spawn make $targets"]
|
||||
expect { eof { } }
|
||||
if {[lindex [wait $pid] end] != 0} {
|
||||
puts "Error: Genode build failed"
|
||||
exit -4
|
||||
}
|
||||
puts "genode build completed"
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Create a fresh boot directory
|
||||
#
|
||||
proc create_boot_directory { } { }
|
||||
|
||||
|
||||
##
|
||||
# Append string to variable only if 'condition' is satisfied
|
||||
#
|
||||
proc append_if {condition var string} {
|
||||
global $var
|
||||
if {$condition} { append $var $string }
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Append element to list only if 'condition' is satisfied
|
||||
#
|
||||
proc lappend_if {condition var string} {
|
||||
global $var
|
||||
if {$condition} { lappend $var $string }
|
||||
}
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Install content of specfied variable as init config file
|
||||
#
|
||||
proc install_config {config} {
|
||||
set fh [open "[run_dir]/genode/config" "WRONLY CREAT TRUNC"]
|
||||
puts $fh $config
|
||||
close $fh
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Integrate specified binaries into boot image
|
||||
#
|
||||
# \param binaries space-separated list of file names located within the
|
||||
# '<build-dir>/bin/' directory
|
||||
#
|
||||
# This function should be implemented by a platform-specific file
|
||||
# included via the '--include' argument.
|
||||
#
|
||||
proc build_boot_image {binaries} { }
|
||||
|
||||
|
||||
##
|
||||
# Execute Genode
|
||||
#
|
||||
# \param wait_for_re regular expression that matches the test completion
|
||||
# \param timeout_value timeout in seconds
|
||||
# \global output contains the core output (modified)
|
||||
#
|
||||
# If the function is called without any argument, Genode is executed in
|
||||
# interactive mode.
|
||||
#
|
||||
# If the test execution times out, this procedure will exit the program with
|
||||
# the error code -2.
|
||||
#
|
||||
# This function must be implemented by the platform-specific test environment.
|
||||
# If not implemented, the program exits with the error code -3.
|
||||
#
|
||||
proc run_genode_until {{wait_for_re forever} {timeout_value 0}} {
|
||||
puts stderr "Error: 'run_genode_until' is not implemented for this platform"
|
||||
exit -3
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Filter output based on the specified pattern
|
||||
#
|
||||
# Only those lines that match the pattern are preserved.
|
||||
#
|
||||
proc grep_output {pattern} {
|
||||
global output
|
||||
regsub -all {[\r\n]+} $output "\n" output
|
||||
set output_list [split $output "\n"]
|
||||
set filtered ""
|
||||
foreach line $output_list {
|
||||
if {[regexp $pattern $line]} {
|
||||
append filtered "$line\n"
|
||||
}
|
||||
}
|
||||
set output $filtered
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Unify known variations that appear in the test output
|
||||
#
|
||||
# \global output test output (modified)
|
||||
#
|
||||
proc unify_output {pattern replacement} {
|
||||
global output
|
||||
regsub -all $pattern $output $replacement output
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Compare output against expected output line by line
|
||||
#
|
||||
# \param good expected test output
|
||||
# \global output test output
|
||||
#
|
||||
# This procedure will exit the program with the error code -1 if the
|
||||
# comparison fails.
|
||||
#
|
||||
proc compare_output_to { good } {
|
||||
global output
|
||||
set output_list [split [strip_whitespace $output] "\n"]
|
||||
set good_list [split [strip_whitespace $good] "\n"]
|
||||
|
||||
set i 0
|
||||
set mismatch_cnt 0
|
||||
foreach good_line $good_list {
|
||||
set output_line [strip_whitespace [lindex $output_list $i]]
|
||||
set good_line [strip_whitespace $good_line]
|
||||
|
||||
if {$output_line != $good_line} {
|
||||
puts ""
|
||||
puts stderr "Line $i of output is unexpected"
|
||||
puts stderr " expected: '$good_line'"
|
||||
puts stderr " got: '$output_line'"
|
||||
incr mismatch_cnt
|
||||
}
|
||||
incr i
|
||||
}
|
||||
|
||||
if {$mismatch_cnt > 0} {
|
||||
puts "Error: Test failed, $mismatch_cnt unexpected lines of output"
|
||||
exit -1
|
||||
} else {
|
||||
puts "Test succeeded"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return true if command-line switch was specified
|
||||
#
|
||||
proc get_cmd_switch { arg_name } {
|
||||
global argv
|
||||
return [expr [lsearch $argv $arg_name] >= 0]
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return command-line argument value
|
||||
#
|
||||
# If a argument name is specified multiple times, a
|
||||
# list of argument values is returned.
|
||||
#
|
||||
proc get_cmd_arg { arg_name default_value } {
|
||||
global argv
|
||||
|
||||
# find argument name in argv list
|
||||
set arg_idx_list [lsearch -all $argv $arg_name]
|
||||
|
||||
if {[llength $arg_idx_list] == 0} { return $default_value }
|
||||
|
||||
set result {}
|
||||
foreach arg_idx $arg_idx_list {
|
||||
set next_idx [expr $arg_idx + 1]
|
||||
|
||||
# stop if argv ends with the argument name
|
||||
if {$next_idx >= [llength $argv]} continue
|
||||
|
||||
# return list element following the argument name
|
||||
lappend result [lindex $argv $next_idx]
|
||||
}
|
||||
|
||||
# if argument occurred only once, return its value
|
||||
if {[llength $result] == 1} { return [lindex $result 0] }
|
||||
|
||||
# if argument occurred multiple times, contain list of arguments
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Read command-line arguments
|
||||
#
|
||||
|
||||
set run_name [get_cmd_arg --name "noname"]
|
||||
set genode_dir [get_cmd_arg --genode-dir ""]
|
||||
set cross_dev_prefix [get_cmd_arg --cross-dev-prefix ""]
|
||||
set specs [get_cmd_arg --specs ""]
|
||||
set repositories [get_cmd_arg --repositories ""]
|
||||
set qemu_args [get_cmd_arg --qemu-args ""]
|
||||
|
||||
#
|
||||
# Enable run scripts to extend 'qemu_arg' via 'append' without bothering
|
||||
# about the required whitespace in front of the custom arguments.
|
||||
#
|
||||
append qemu_args " "
|
||||
|
||||
# accessor functions for command-line arguments
|
||||
proc run_name { } { global run_name; return $run_name }
|
||||
proc run_dir { } { global run_name; return var/run/$run_name }
|
||||
proc genode_dir { } { global genode_dir; return $genode_dir }
|
||||
proc cross_dev_prefix { } { global cross_dev_prefix; return $cross_dev_prefix }
|
||||
|
||||
# set expect match-buffer size
|
||||
match_max -d 20000
|
||||
|
||||
##
|
||||
# Return true if spec value is set for the build
|
||||
#
|
||||
proc have_spec {spec} { global specs; return [expr [lsearch $specs $spec] != -1] }
|
||||
|
||||
|
||||
##
|
||||
# Return true if specified program is installed
|
||||
#
|
||||
proc have_installed {program} {
|
||||
if {[catch { exec which $program }]} { return false; }
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return true if specified program is installed on the host platform
|
||||
#
|
||||
proc requires_installation_of {program} {
|
||||
if {![have_installed $program]} {
|
||||
puts "Run script aborted because $program is not installed"; exit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return first repository containing the given path
|
||||
#
|
||||
proc repository_contains {path} {
|
||||
global repositories;
|
||||
foreach i $repositories {
|
||||
if {[file exists $i/$path]} { return $i }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Utilities for performing steps that are the same on several platforms
|
||||
##
|
||||
|
||||
##
|
||||
# Read kernel location from build-directory configuration
|
||||
#
|
||||
# If config file does not exist or if there is no 'KERNEL' declaration in the
|
||||
# config file, the function returns 'default_location'. If the config file
|
||||
# points to a non-existing kernel image, the function aborts with the exit
|
||||
# value -6.
|
||||
#
|
||||
proc kernel_location_from_config_file { config_file default_location } {
|
||||
global _kernel
|
||||
|
||||
if {![info exists _kernel]} {
|
||||
if {[file exists $config_file]} {
|
||||
set _kernel [exec sed -n "/^KERNEL/s/^.*=\\s*//p" $config_file]
|
||||
|
||||
# check if the regular expression matched
|
||||
if {$_kernel != ""} {
|
||||
if {[file exists $_kernel]} {
|
||||
return $_kernel
|
||||
} else {
|
||||
puts stderr "Error: kernel specified in '$config_file' does not exist"
|
||||
exit -6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# try to fall back to version hosted with the Genode build directory
|
||||
set _kernel $default_location
|
||||
}
|
||||
return $_kernel
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Install files needed to create a bootable ISO image
|
||||
#
|
||||
# The ISO boot concept uses isolinux to load GRUB, which in turn loads Genode.
|
||||
# This way we can make use of isolinux' support for booting ISO images from a
|
||||
# USB stick.
|
||||
#
|
||||
proc install_iso_bootloader_to_run_dir { } {
|
||||
|
||||
exec mkdir -p [run_dir]/boot/isolinux
|
||||
exec cp [genode_dir]/tool/boot/chain.c32 [run_dir]/boot/isolinux
|
||||
exec cp [genode_dir]/tool/boot/isolinux.bin [run_dir]/boot/isolinux
|
||||
exec cp [genode_dir]/tool/boot/isolinux.cfg [run_dir]/boot/isolinux
|
||||
|
||||
exec mkdir -p [run_dir]/boot/grub
|
||||
exec cp [genode_dir]/tool/boot/stage2_eltorito [run_dir]/boot/grub
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Copy the specified binaries from the 'bin/' directory to the run
|
||||
# directory and try to strip executables.
|
||||
#
|
||||
proc copy_and_strip_genode_binaries_to_run_dir { binaries } {
|
||||
|
||||
foreach binary $binaries {
|
||||
exec cp bin/$binary [run_dir]/genode
|
||||
catch {
|
||||
exec [cross_dev_prefix]strip [run_dir]/genode/$binary || true }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Create ISO image with the content of the run directory
|
||||
#
|
||||
proc create_iso_image_from_run_dir { } {
|
||||
|
||||
puts "creating ISO image..."
|
||||
exec rm -f "[run_dir].iso"
|
||||
|
||||
#
|
||||
# The 'create_iso' tool returns a non-zero return code even if
|
||||
# successful. So we ignore the return code here.
|
||||
#
|
||||
catch { exec [genode_dir]/tool/create_iso iso ISO=[run_dir] }
|
||||
if {![file exists "[run_dir].iso"]} {
|
||||
puts stderr "Error: ISO image creation failed"
|
||||
exit -5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Execute scenario using Qemu
|
||||
#
|
||||
proc spawn_qemu { wait_for_re timeout_value } {
|
||||
global output
|
||||
global qemu_args
|
||||
global qemu
|
||||
global spawn_id
|
||||
set qemu "qemu"
|
||||
|
||||
# use special qemu versions for non x86_32 architectures
|
||||
if {[have_spec x86_64]} { set qemu "qemu-system-x86_64" }
|
||||
if {[have_spec arm]} { set qemu "qemu-system-arm" }
|
||||
|
||||
#
|
||||
# Only the x86_64 variant of Qemu provides the emulation of hardware
|
||||
# virtualization features used by NOVA. So let's always stick to this
|
||||
# varient of Qemu when working with NOVA even when operating in 32bit.
|
||||
#
|
||||
if {[have_spec nova]} { set qemu "qemu-system-x86_64" }
|
||||
|
||||
#
|
||||
# Redirect serial output to stdio, but only in graphics mode and no
|
||||
# explicit configuration of serial interfaces is specified in the run
|
||||
# script. The 'mon' prefix enables the access to the qemu console.
|
||||
#
|
||||
if {![regexp -- {-nographic} $qemu_args dummy] &&
|
||||
![regexp -- {-serial} $qemu_args dummy]} {
|
||||
append qemu_args " -serial mon:stdio " }
|
||||
|
||||
# tweak emulated platform for specific platforms
|
||||
if {[have_spec platform_pbxa9]} { append qemu_args " -M realview-pbx-a9 -m 256 " }
|
||||
if {[have_spec platform_vpb926]} { append qemu_args " -M versatilepb -m 128 " }
|
||||
if {[have_spec platform_vea9x4]} { append qemu_args " -M vexpress-a9 -cpu cortex-a9 -m 256 " }
|
||||
|
||||
# on x86, we supply the boot image as ISO image
|
||||
if {[have_spec x86]} { append qemu_args " -cdrom [run_dir].iso " }
|
||||
|
||||
# on ARM, we supply the boot image as kernel
|
||||
if {[have_spec arm]} { append qemu_args " -kernel [run_dir]/image.elf " }
|
||||
|
||||
set timeout $timeout_value
|
||||
set pid [eval "spawn $qemu $qemu_args"]
|
||||
if {$wait_for_re == "forever"} { interact $pid }
|
||||
expect {
|
||||
-re $wait_for_re { }
|
||||
timeout { puts stderr "Error: Test execution timed out"; exit -2 }
|
||||
}
|
||||
set output $expect_out(buffer)
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Determine terminal program
|
||||
#
|
||||
proc terminal { } {
|
||||
global env
|
||||
if {[info exists env(COLORTERM)]} {
|
||||
return $env(COLORTERM)
|
||||
}
|
||||
return $env(TERM)
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Determine GDB executable installed at the host
|
||||
#
|
||||
proc gdb { } {
|
||||
if {[have_installed "[cross_dev_prefix]gdb"]} {
|
||||
return "[cross_dev_prefix]gdb" }
|
||||
|
||||
if {[have_installed gdb]} {
|
||||
return "gdb" }
|
||||
|
||||
requires_installation_of gdb
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Execution of run scripts
|
||||
##
|
||||
|
||||
#
|
||||
# Read and execute files specified as '--include' arguments
|
||||
#
|
||||
|
||||
foreach include_name [get_cmd_arg --include ""] {
|
||||
puts "using run script $include_name"
|
||||
source $include_name
|
||||
}
|
||||
|
||||
579
tool/tool_chain
Executable file
579
tool/tool_chain
Executable file
@@ -0,0 +1,579 @@
|
||||
#!/usr/bin/make -f
|
||||
#
|
||||
# \brief Tool-chain creation tool for the Genode OS Framework
|
||||
# \author Norman Feske
|
||||
# \date 2009-02-03
|
||||
#
|
||||
|
||||
help:
|
||||
$(ECHO)
|
||||
$(ECHO) "Build tool chain for the Genode OS Framework"
|
||||
$(ECHO)
|
||||
$(ECHO) "The tool chain consists of GCC $(GCC_VERSION) and binutils $(BINUTILS_VERSION)"
|
||||
$(ECHO) "and will be created at '$(LOCAL_INSTALL_LOCATION)'."
|
||||
$(ECHO)
|
||||
$(ECHO) "--- available commands ---"
|
||||
$(ECHO) "x86 - create tool chain for x86"
|
||||
$(ECHO) "arm - create tool chain for arm"
|
||||
$(ECHO) "clean - clean everything except downloaded archives"
|
||||
$(ECHO) "cleanall - clean everything including downloaded archives"
|
||||
$(ECHO) "install - copy tool chain to '$(INSTALL_LOCATION)'"
|
||||
$(ECHO)
|
||||
|
||||
#
|
||||
# User interface
|
||||
#
|
||||
|
||||
SUPPORTED_PLATFORMS := x86 microblaze arm
|
||||
|
||||
PLATFORM := $(firstword $(filter $(SUPPORTED_PLATFORMS),$(MAKECMDGOALS)))
|
||||
|
||||
$(SUPPORTED_PLATFORMS): install
|
||||
|
||||
#
|
||||
# Enable parallel build for 2nd-level $(MAKE) by default
|
||||
#
|
||||
|
||||
MAKE_OPT ?= -j4
|
||||
|
||||
#
|
||||
# Determine Genode base directory based on the known location of the
|
||||
# 'create_builddir' tool within the Genode source tree
|
||||
#
|
||||
|
||||
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/..)
|
||||
|
||||
#
|
||||
# Download locations
|
||||
#
|
||||
|
||||
DOWNLOAD_MIRROR ?= ftp://ftp.fu-berlin.de
|
||||
GCC_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gcc
|
||||
BINUTILS_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/binutils
|
||||
GDB_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gdb
|
||||
GMP_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gmp
|
||||
MPFR_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/mpfr
|
||||
MPC_DOWNLOAD_URL ?= http://www.multiprecision.org/mpc/download
|
||||
|
||||
|
||||
#
|
||||
# Tool versions and install location
|
||||
#
|
||||
|
||||
GCC_VERSION = 4.6.1
|
||||
BINUTILS_VERSION = 2.21.1
|
||||
GDB_VERSION = 7.3.1
|
||||
GMP_VERSION = 5.0.2
|
||||
MPFR_VERSION = 3.1.0
|
||||
MPC_VERSION = 0.9
|
||||
INSTALL_LOCATION = /usr/local/genode-gcc
|
||||
DOWNLOAD_DIR = download
|
||||
CONTRIB_DIR = contrib
|
||||
|
||||
BINUTILS_DOWNLOAD_TBZ2 = binutils-$(BINUTILS_VERSION).tar.bz2
|
||||
|
||||
# download file name differs from dir name found within the archive
|
||||
ifeq ($(BINUTILS_VERSION),2.21.1)
|
||||
BINUTILS_DOWNLOAD_TBZ2 = binutils-$(BINUTILS_VERSION)a.tar.bz2
|
||||
endif
|
||||
|
||||
#
|
||||
# Utilities
|
||||
#
|
||||
|
||||
SHELL = bash
|
||||
BRIGHT_COL = \033[01;33m
|
||||
DEFAULT_COL = \033[0m
|
||||
ECHO = @echo -e
|
||||
VERBOSE = @
|
||||
|
||||
AUTOCONF_gcc_4.4.5 = autoconf2.59
|
||||
AUTOCONF_gcc_4.6.1 = autoconf2.64
|
||||
|
||||
AUTOCONF = $(AUTOCONF_gcc_$(GCC_VERSION))
|
||||
|
||||
ifeq ($(AUTOCONF),)
|
||||
$(error Unknown autoconf version for GCC $(GCC_VERSION).)
|
||||
endif
|
||||
|
||||
ifeq ($(shell which $(AUTOCONF)),)
|
||||
$(error Need to have $(AUTOCONF) installed.)
|
||||
endif
|
||||
|
||||
ifeq ($(shell which autogen)),)
|
||||
$(error Need to have autogen installed.)
|
||||
endif
|
||||
|
||||
#
|
||||
# Libc stub
|
||||
#
|
||||
|
||||
LIBC_GEN_SYMLINKS = \
|
||||
stdint.h memory.h string.h stdlib.h unistd.h errno.h wchar.h \
|
||||
ctype.h strings.h wctype.h math.h stdio.h dlfcn.h inttypes.h \
|
||||
malloc.h signal.h fcntl.h assert.h locale.h setjmp.h time.h \
|
||||
link.h gnu-versions.h elf.h
|
||||
|
||||
LIBC_GEN_SYS_SYMLINKS = types.h stat.h sem.h
|
||||
|
||||
LIBC_DIR = $(shell pwd)/build/libc/include
|
||||
LIBC_STUB_H = $(GENODE_DIR)/tool/libgcc_libc_stub.h
|
||||
|
||||
LIBC = $(addprefix $(LIBC_DIR)/,$(LIBC_GEN_SYMLINKS)) \
|
||||
$(addprefix $(LIBC_DIR)/sys/,$(LIBC_GEN_SYS_SYMLINKS))
|
||||
|
||||
$(LIBC_DIR) $(LIBC_DIR)/sys:
|
||||
$(VERBOSE)mkdir -p $@
|
||||
|
||||
$(addprefix $(LIBC_DIR)/,$(LIBC_GEN_SYMLINKS)): $(LIBC_DIR)
|
||||
$(VERBOSE)ln -sf $(LIBC_STUB_H) $@
|
||||
|
||||
$(addprefix $(LIBC_DIR)/sys/,$(LIBC_GEN_SYS_SYMLINKS)): $(LIBC_DIR)/sys
|
||||
$(VERBOSE)ln -sf $(LIBC_STUB_H) $@
|
||||
|
||||
#
|
||||
# 'configure' parameters for binutils, gcc and gdb
|
||||
#
|
||||
|
||||
LOCAL_INSTALL_LOCATION = $(shell pwd)/build/install
|
||||
|
||||
#
|
||||
# Local install location for gmp, mpfr, and mpc libraries. These libraries are
|
||||
# requried at build time of gcc. We install them locally before invoking the
|
||||
# gcc build. Because the libs do not need to be included in the tool-chain
|
||||
# package (they are statically linked against gcc), we install them to a
|
||||
# different install location as gcc.
|
||||
#
|
||||
LOCAL_LIB_INSTALL_LOCATION = $(shell pwd)/build/lib-install
|
||||
|
||||
TARGET_NAME_x86 = x86_64-elf
|
||||
TARGET_NAME_microblaze = microblaze-elf
|
||||
TARGET_NAME_arm = arm-elf-eabi
|
||||
|
||||
ifneq ($(VERBOSE),)
|
||||
CONFIG_QUIET = --quiet
|
||||
MAKEFLAGS += --quiet
|
||||
export MAKEFLAGS
|
||||
endif
|
||||
|
||||
COMMON_CONFIG = $(CONFIG_QUIET) \
|
||||
--prefix=$(LOCAL_INSTALL_LOCATION) \
|
||||
--program-prefix=genode-$(PLATFORM)- \
|
||||
--target=$(TARGET_NAME_$(PLATFORM)) \
|
||||
--program-transform-name="s/$(TARGET_NAME_$(PLATFORM))/$(PLATFORM)/"
|
||||
|
||||
BINUTILS_CONFIG += $(COMMON_CONFIG) --disable-werror
|
||||
|
||||
#
|
||||
# Prevent GNU assembler from treating '/' as the start of a comment. In
|
||||
# 'gas/config/tc-i386.c', the policy of handling '/' is defined. For Linux, '/'
|
||||
# is treated as division, which we expect. To apply this needed policy for our
|
||||
# plain 'elf' version gas, we supply the definition of 'TE_LINUX' by hand.
|
||||
# Fortunately, this define is not used outside of gas.
|
||||
#
|
||||
BINUTILS_CONFIG += CFLAGS=-DTE_LINUX
|
||||
|
||||
#
|
||||
# Add platform-specific binutils configure arguments
|
||||
#
|
||||
BINUTILS_CONFIG += $(BINUTILS_CONFIG_$(PLATFORM))
|
||||
|
||||
#
|
||||
# Dummy libc symbols to resolve unresolved references when linking
|
||||
# 'libgcc_s.so'. Even though, this library is not used on Genode, we want the
|
||||
# link command to succeed to complete the build process.
|
||||
#
|
||||
DUMMY_LIBC_SYMS = strlen free memcpy malloc memset abort dl_iterate_phdr
|
||||
LD_PREFIX = -Wl,
|
||||
LD_DEFSYM_DUMMY_LIBC = $(addprefix $(LD_PREFIX)--defsym=,$(addsuffix =0,$(DUMMY_LIBC_SYMS)))
|
||||
|
||||
GCC_CONFIG += $(COMMON_CONFIG) \
|
||||
--with-gnu-as --with-gnu-ld --disable-tls --disable-threads \
|
||||
--disable-libstdcxx-pch \
|
||||
--enable-shared \
|
||||
--with-gmp=$(LOCAL_LIB_INSTALL_LOCATION) \
|
||||
--with-mpfr=$(LOCAL_LIB_INSTALL_LOCATION) \
|
||||
--with-mpc=$(LOCAL_LIB_INSTALL_LOCATION) \
|
||||
CPPFLAGS_FOR_TARGET=-I$(LIBC_DIR) \
|
||||
CFLAGS_FOR_TARGET="-I$(LIBC_DIR) -nostdlib $(LD_DEFSYM_DUMMY_LIBC) -fPIC"
|
||||
|
||||
GCC_CONFIG += $(GCC_CONFIG_$(PLATFORM))
|
||||
|
||||
#
|
||||
# Configure options passed to gcc
|
||||
#
|
||||
# The 't-linux' tmake file is needed to let the tool chain use 'unwind-dw2-fde-glibc',
|
||||
# needed for the exception handling on Genode in the presence of shared libraries.
|
||||
#
|
||||
HOST_CONFIG_ARGS = $(CONFIG_QUIET) \
|
||||
host_xm_include_list=$(LINK_SPEC_H_$(PLATFORM)) \
|
||||
tmake_file='t-slibgcc-elf-ver t-slibgcc-nolc-override t-linux'
|
||||
|
||||
# passed to target components such as libgcc, libstdc++
|
||||
TARGET_CONFIG_ARGS = $(CONFIG_QUIET) \
|
||||
extra_parts='crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o'
|
||||
|
||||
# compile libsupc++ as position-independent code
|
||||
TARGET_CONFIG_ARGS += LIBSUPCXX_PICFLAGS='-prefer-pic'
|
||||
|
||||
GCC_INSTALL_RULE = install-strip
|
||||
ifeq ($(GCC_VERSION),4.4.5)
|
||||
GCC_INSTALL_RULE = install
|
||||
endif
|
||||
|
||||
#
|
||||
# Default linker script
|
||||
#
|
||||
# Needed only to make target-configure happy.
|
||||
#
|
||||
|
||||
LD_SCRIPT_microblaze = $(LOCAL_INSTALL_LOCATION)/$(TARGET_NAME_microblaze)/lib/xilinx.ld
|
||||
|
||||
$(LD_SCRIPT_$(PLATFORM)):
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)touch $@
|
||||
|
||||
#
|
||||
# Link spec
|
||||
#
|
||||
# The 'LINK_SPEC' define comprises the rules of how the GCC frontend invokes
|
||||
# the linker.
|
||||
#
|
||||
|
||||
LINK_SPEC_H_x86 = $(shell pwd)/build/$(PLATFORM)/link_spec.h
|
||||
|
||||
$(LINK_SPEC_H_x86):
|
||||
$(VERBOSE)echo "#define LINK_SPEC \"%{!m32:-m elf_x86_64} %{m32:-m elf_i386} %{shared:-shared} %{!static:--eh-frame-hdr}\"" > $@
|
||||
|
||||
$(LINK_SPEC_H_arm):
|
||||
$(VERBOSE)echo "#define LINK_SPEC \"%(shared:-shared) %{!static:--eh-frame-hdr}\"" > $@
|
||||
|
||||
#
|
||||
# Platform-specific multilib support
|
||||
#
|
||||
|
||||
MAKE_OPT_x86 := MULTILIB_OPTIONS="m64/m32" MULTILIB_DIRNAMES="64 32"
|
||||
MAKE_OPT += $(MAKE_OPT_$(PLATFORM))
|
||||
|
||||
#
|
||||
# Build rules and dependencies between build steps
|
||||
#
|
||||
# We use the binaries 'objdump' and 'g++' as representatives for expressing
|
||||
# dependencies. All other programs will be generated as side effect.
|
||||
#
|
||||
|
||||
BINUTILS_BINARIES = build/$(PLATFORM)/binutils/binutils/objdump
|
||||
BINUTILS_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-objdump
|
||||
GCC_BINARIES = build/$(PLATFORM)/gcc/gcc/g++
|
||||
GCC_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-g++
|
||||
GDB_BINARIES = build/$(PLATFORM)/gdb/gdb/gdb
|
||||
GDB_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-gdb
|
||||
|
||||
build_all: $(GCC_INSTALLED_BINARIES) $(GDB_INSTALLED_BINARIES)
|
||||
|
||||
$(DOWNLOAD_DIR):
|
||||
$(VERBOSE)mkdir -p $@
|
||||
|
||||
$(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2): $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading binutils...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(BINUTILS_DOWNLOAD_URL)/$(BINUTILS_DOWNLOAD_TBZ2) && touch $@
|
||||
|
||||
$(DOWNLOAD_DIR)/gcc-core-$(GCC_VERSION).tar.bz2: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading gcc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GCC_DOWNLOAD_URL)/gcc-$(GCC_VERSION)/gcc-core-$(GCC_VERSION).tar.bz2 && touch $@
|
||||
|
||||
$(DOWNLOAD_DIR)/gcc-g++-$(GCC_VERSION).tar.bz2: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading g++...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GCC_DOWNLOAD_URL)/gcc-$(GCC_VERSION)/gcc-g++-$(GCC_VERSION).tar.bz2 && touch $@
|
||||
|
||||
$(DOWNLOAD_DIR)/gmp-$(GMP_VERSION).tar.bz2: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading gmp...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GMP_DOWNLOAD_URL)/gmp-$(GMP_VERSION).tar.bz2 && touch $@
|
||||
|
||||
$(DOWNLOAD_DIR)/mpfr-$(MPFR_VERSION).tar.bz2: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading mpfr...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(MPFR_DOWNLOAD_URL)/mpfr-$(MPFR_VERSION).tar.bz2 && touch $@
|
||||
|
||||
$(DOWNLOAD_DIR)/mpc-$(MPC_VERSION).tar.gz: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading mpc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(MPC_DOWNLOAD_URL)/mpc-$(MPC_VERSION).tar.gz && touch $@
|
||||
|
||||
$(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure: $(DOWNLOAD_DIR)/gmp-$(GMP_VERSION).tar.bz2
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking gmp...$(DEFAULT_COL)"
|
||||
$(VERBOSE)tar xfj $< -C $(CONTRIB_DIR)
|
||||
|
||||
$(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure: $(DOWNLOAD_DIR)/mpfr-$(MPFR_VERSION).tar.bz2
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking mpfr...$(DEFAULT_COL)"
|
||||
$(VERBOSE)tar xfj $< -C $(CONTRIB_DIR)
|
||||
|
||||
$(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure: $(DOWNLOAD_DIR)/mpc-$(MPC_VERSION).tar.gz
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking mpc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)tar xfz $< -C $(CONTRIB_DIR)
|
||||
|
||||
$(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure: $(addprefix $(DOWNLOAD_DIR)/,gcc-core-$(GCC_VERSION).tar.bz2 gcc-g++-$(GCC_VERSION).tar.bz2)
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking gcc and g++...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
|
||||
$(VERBOSE)for i in $^ ; do tar xfj $$i -C $(CONTRIB_DIR) ;done
|
||||
$(VERBOSE)touch $@
|
||||
$(ECHO) "$(BRIGHT_COL)patching gcc build system...$(DEFAULT_COL)"
|
||||
@#
|
||||
@# Enable support for passing custom 'tmake_file' and 'extra_parts' to the
|
||||
@# GCC configure process uncommenting the default initialization of the
|
||||
@# respective variables. The 'extra_parts' variable is used to carry the
|
||||
@# the information about which crtN files are to be created.
|
||||
@#
|
||||
@# The 't-386elf' file must the treated to prevent it from defining the
|
||||
@# 'EXTRA_PARTS' variable. If defined, the 'libgcc' Makefile would prepare
|
||||
@# it against our custom list of 'extra_parts' and consequently fail.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/^tmake_file=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
|
||||
$(VERBOSE)sed -i "/^extra_parts=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
|
||||
$(VERBOSE)sed -i "/^extra_parts=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libgcc/config.host
|
||||
$(VERBOSE)sed -i "/^EXTRA_PARTS=/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/i386/t-i386elf
|
||||
$(VERBOSE)sed -i "/^EXTRA_MULTILIB_PARTS *=/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/arm/t-arm-elf
|
||||
@#
|
||||
@# Let 'config.gcc' expand our already populated 'tmake_file' variable rather
|
||||
@# than making a hard assignment. This is needed for the ARM platform because
|
||||
@# the target 'arm-elf-eabi' actually matches the pattern 'arm-*-*-eabi' in
|
||||
@# the 'config.gcc' file.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/tmake_file=\"arm/s/=\"/=\"\$${tmake_file} /" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
|
||||
@#
|
||||
@# Enable LINK_SPEC customization via configure arguments
|
||||
@#
|
||||
@# We add a hook for sneaking our custom LINK_SPEC definition into the GCC
|
||||
@# configure process by uncommentig the 'host_xm_include_list'. This enables us
|
||||
@# to supply a custom header file to be included into 'gcc/config.h' defining
|
||||
@# the 'LINK_SPEC' macro. This macro expresses the policy of how the GCC
|
||||
@# frontend invokes 'ld' on multiarch platforms. I.e., on x86, we need to pass
|
||||
@# '-melf_i386' to 'ld' when building in '-m32' mode.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/^host_xm_include_list=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/configure.ac
|
||||
@#
|
||||
@# Make sure to disable the 'inhibit_libc' flag, which is evaluated when
|
||||
@# compiling libgcc. When libc is inhibited, the 'unwind-dw2-fde-glibc.c'
|
||||
@# is not using the "new" glibc exception handling mechanism. However,
|
||||
@# Genode's dynamic linker relies on this mechanism.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/inhibit_libc=true/s/true/false # was true/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/configure.ac
|
||||
@#
|
||||
@# Accept prepopulation of 'host_configargs' and 'target_configargs' as
|
||||
@# configure argument (only needed for gcc-4.4.5, fixed with later versions)
|
||||
@#
|
||||
$(VERBOSE)sed -i "/host_configargs=.--cache-file/s/=./=\"\$$host_configargs /" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
|
||||
$(VERBOSE)sed -i "/target_configargs=..baseargs/s/=.*/=\"\$$target_configargs \$${baseargs}\"/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
|
||||
@#
|
||||
@# Allow customization of CPPFLAGS_FOR_TARGET, not supported by the original
|
||||
@# GCC config and build system.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/^CXXFLAGS_FOR_TARGET =/s/^/CPPFLAGS_FOR_TARGET = @CPPFLAGS_FOR_TARGET@\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
|
||||
$(VERBOSE)sed -i "/AC_SUBST(CFLAGS_FOR_TARGET)/s/^/AC_SUBST(CPPFLAGS_FOR_TARGET)\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
|
||||
@#
|
||||
@# Fix the handling of CPP_FOR_TARGET. Without the fix, the configure script
|
||||
@# of libgcc tries to use the normal 'cpp' for executing preprocessor tests,
|
||||
@# which produces bogus results.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/CC=.*XGCC.*export CC/s/^/ CPP=\"\$$(CPP_FOR_TARGET) \$$(XGCC_FLAGS_FOR_TARGET) \$$\$$TFLAGS\"; export CPP; \\\\\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
|
||||
$(VERBOSE)sed -i "/^CC_FOR_TARGET=/s/^/CPP_FOR_TARGET=\$$(STAGE_CC_WRAPPER) @CPP_FOR_TARGET@\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
|
||||
$(VERBOSE)sed -i "/CC=.*XGCC.*TFLAGS....$$/s/^/ 'CPP=\$$\$$(CPP_FOR_TARGET) \$$\$$(XGCC_FLAGS_FOR_TARGET) \$$\$$(TFLAGS)' \\\\\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
|
||||
$(VERBOSE)sed -i "/flag= CC_FOR_TARGET/s/^/flags_to_pass = { flag= CPP_FOR_TARGET ; };\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.def
|
||||
$(VERBOSE)sed -i "/^GCC_TARGET_TOOL.cc,/s/^/GCC_TARGET_TOOL(cpp, CPP_FOR_TARGET, CPP, \[gcc\/cpp -B\$$\$$r\/\$$(HOST_SUBDIR)\/gcc\/\])\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
|
||||
@#
|
||||
@# Ensure -fno-short-enums as default.
|
||||
@#
|
||||
$(VERBOSE)sed -i "s/return TARGET_AAPCS_BASED && arm_abi != ARM_ABI_AAPCS_LINUX/return false/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/arm/arm.c
|
||||
@#
|
||||
@# Remove sanity check for host/target combination in configure script of
|
||||
@# libstdc++. An alternative fix would be the addition of a new host or
|
||||
@# the use of an existing one. However, adding a new host would require
|
||||
@# us to maintain a larger patch to the GCC build system, and using an
|
||||
@# existing host comes with all the (possibly unwanted) policies associated
|
||||
@# with the respective host platform. We want to stick with the bare-bone
|
||||
@# compiler as much as possible.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/No support for this host.target combination/d" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3/crossconfig.m4
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3; $(AUTOCONF)
|
||||
@#
|
||||
@# Allow passing of PICFLAGS to the configure script of libstdc++.
|
||||
@# Without this change, libsupc++ would be compiled w/o PICFLAGS, resulting
|
||||
@# in text relocations. Because for base tool chains, no 'dynamic_linker'
|
||||
@# is defined (see 'libtool.m4'), 'dynamic_linker' is set to 'no', which
|
||||
@# results in 'can_build_shared = no', which, in turn , results
|
||||
@# in 'enable_shared = no', which, in turn, sets 'LIBSUPCXX_PICFLAGS' to
|
||||
@# nothing rather then '-prefer-pic'.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/LIBSUPCXX_PICFLAGS=$$/s/LIB/__LIB/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3/configure.ac
|
||||
@#
|
||||
@# Re-generate configure scripts
|
||||
@#
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION); autogen Makefile.def
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libgcc; $(AUTOCONF)
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3; $(AUTOCONF)
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc; $(AUTOCONF)
|
||||
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION); $(AUTOCONF)
|
||||
@#
|
||||
@# Fix a bug in gcc 4.6.1 that causes compile errors when building Qt4 for ARM
|
||||
@# More detailed description at and solution from http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02245.html
|
||||
@#
|
||||
ifeq ($(GCC_VERSION),4.6.1)
|
||||
$(ECHO) "$(BRIGHT_COL)patching gcc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)sed -i "/|| (volatilep && flag_strict_volatile_bitfields > 0/s/)/ \&\& (bitpos % GET_MODE_ALIGNMENT (mode) != 0))/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/expr.c
|
||||
endif
|
||||
|
||||
$(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure: $(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2)
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking binutils...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
|
||||
$(VERBOSE)tar xfj $^ -C $(CONTRIB_DIR) && touch $@
|
||||
|
||||
build/$(PLATFORM)/binutils/Makefile: $(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure
|
||||
$(ECHO) "$(BRIGHT_COL)configuring binutils...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); ../../../$(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure $(BINUTILS_CONFIG)
|
||||
|
||||
$(BINUTILS_BINARIES): build/$(PLATFORM)/binutils/Makefile
|
||||
$(ECHO) "$(BRIGHT_COL)builing binutils...$(DEFAULT_COL)"
|
||||
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
|
||||
|
||||
$(BINUTILS_INSTALLED_BINARIES): $(BINUTILS_BINARIES)
|
||||
$(ECHO) "$(BRIGHT_COL)installing binutils...$(DEFAULT_COL)"
|
||||
$(VERBOSE)for i in binutils gas ld intl opcodes; do \
|
||||
$(MAKE) -C build/$(PLATFORM)/binutils/$$i install-strip; done
|
||||
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/binutils/libiberty install
|
||||
|
||||
COMMON_LIB_CONFIG = --prefix=$(LOCAL_LIB_INSTALL_LOCATION) \
|
||||
--disable-shared --enable-static
|
||||
|
||||
GMP_CONFIG = $(COMMON_LIB_CONFIG)
|
||||
MPFR_CONFIG = $(COMMON_LIB_CONFIG) --with-gmp=$(LOCAL_LIB_INSTALL_LOCATION)
|
||||
MPC_CONFIG = $(COMMON_LIB_CONFIG) --with-gmp=$(LOCAL_LIB_INSTALL_LOCATION) \
|
||||
--with-mpfr=$(LOCAL_LIB_INSTALL_LOCATION)
|
||||
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a: build/gmp/Makefile
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a: build/mpfr/Makefile
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpc.a: build/mpc/Makefile
|
||||
|
||||
# rule to build libgmp, libmpfr, and libmpc
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/lib%.a:
|
||||
$(ECHO) "$(BRIGHT_COL)building lib$*...$(DEFAULT_COL)"
|
||||
$(VERBOSE)make -C build/$* all install
|
||||
|
||||
build/gmp/Makefile: $(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure
|
||||
|
||||
build/gmp/Makefile:
|
||||
$(ECHO) "$(BRIGHT_COL)configuring libgmp...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); \
|
||||
../../$(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure $(GMP_CONFIG)
|
||||
|
||||
build/mpfr/Makefile: $(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a
|
||||
|
||||
build/mpfr/Makefile:
|
||||
$(ECHO) "$(BRIGHT_COL)configuring libmpfr...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); \
|
||||
../../$(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure $(MPFR_CONFIG)
|
||||
|
||||
build/mpc/Makefile: $(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a
|
||||
|
||||
build/mpc/Makefile:
|
||||
$(ECHO) "$(BRIGHT_COL)configuring libmpc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); \
|
||||
../../$(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure $(MPC_CONFIG)
|
||||
|
||||
build/$(PLATFORM)/gcc/Makefile: $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure \
|
||||
$(BINUTILS_INSTALLED_BINARIES) \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a \
|
||||
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpc.a
|
||||
|
||||
build/$(PLATFORM)/gcc/Makefile:
|
||||
$(ECHO) "$(BRIGHT_COL)configuring gcc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); \
|
||||
host_configargs="$(HOST_CONFIG_ARGS)" \
|
||||
target_configargs="$(TARGET_CONFIG_ARGS)" \
|
||||
../../../$(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure $(GCC_CONFIG)
|
||||
|
||||
$(GCC_BINARIES): build/$(PLATFORM)/gcc/Makefile \
|
||||
$(LINK_SPEC_H_$(PLATFORM)) \
|
||||
$(LD_SCRIPT_$(PLATFORM)) \
|
||||
$(LIBC)
|
||||
|
||||
$(GCC_BINARIES): build/$(PLATFORM)/gcc/Makefile
|
||||
$(ECHO) "$(BRIGHT_COL)builing gcc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
|
||||
|
||||
$(GCC_INSTALLED_BINARIES): $(GCC_BINARIES)
|
||||
$(ECHO) "$(BRIGHT_COL)installing gcc...$(DEFAULT_COL)"
|
||||
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/gcc $(GCC_INSTALL_RULE)
|
||||
|
||||
$(DOWNLOAD_DIR)/gdb-$(GDB_VERSION).tar.bz2: $(DOWNLOAD_DIR)
|
||||
$(ECHO) "$(BRIGHT_COL)downloading gdb...$(DEFAULT_COL)"
|
||||
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GDB_DOWNLOAD_URL)/gdb-$(GDB_VERSION).tar.bz2 && touch $@
|
||||
|
||||
$(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure: $(DOWNLOAD_DIR)/gdb-$(GDB_VERSION).tar.bz2
|
||||
$(ECHO) "$(BRIGHT_COL)unpacking gdb...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
|
||||
$(VERBOSE)tar xfj $^ -C $(CONTRIB_DIR) && touch $@
|
||||
$(ECHO) "$(BRIGHT_COL)patching gdb...$(DEFAULT_COL)"
|
||||
@#
|
||||
@# Include 'solib.o' and 'solib-svr4.o' in arm*-*-* (non-OS) target configuration for shared library support
|
||||
@#
|
||||
$(VERBOSE)sed -i "s/gdb_target_obs=\"arm-tdep\.o\"$$/gdb_target_obs=\"arm-tdep.o solib.o solib-svr4.o\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/configure.tgt
|
||||
@#
|
||||
@# Add an x86_64-*-* (non-OS) target with shared library support
|
||||
@#
|
||||
$(VERBOSE)sed -i "/^xtensa\*-\*-linux\*/ s/^/x86_64-*-*)\n\tgdb_target_obs=\"amd64-tdep.o i386-tdep.o i387-tdep.o solib.o solib-svr4.o\"\n\t;;\n/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/configure.tgt
|
||||
@#
|
||||
@# Enable shared library support
|
||||
@#
|
||||
$(VERBOSE)sed -i "/^#include \"features\/i386\/amd64-avx\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/amd64-tdep.c
|
||||
$(VERBOSE)sed -i "/AMD64 generally uses/ s/^/ set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_lp64_fetch_link_map_offsets);\n\n/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/amd64-tdep.c
|
||||
$(VERBOSE)sed -i "/^#include \"features\/arm-with-m\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
|
||||
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_ilp32_fetch_link_map_offsets);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
|
||||
$(VERBOSE)sed -i "/^#include \"features\/i386\/i386-mmx\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/i386-tdep.c
|
||||
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_ilp32_fetch_link_map_offsets);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/i386-tdep.c
|
||||
@#
|
||||
@# Enable software single-stepping on ARM
|
||||
@#
|
||||
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_gdbarch_software_single_step(gdbarch, arm_software_single_step);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
|
||||
|
||||
build/$(PLATFORM)/gdb/Makefile: $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure
|
||||
$(ECHO) "$(BRIGHT_COL)configuring gdb...$(DEFAULT_COL)"
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)cd $(dir $@); \
|
||||
../../../$(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure $(COMMON_CONFIG)
|
||||
|
||||
$(GDB_BINARIES): build/$(PLATFORM)/gdb/Makefile
|
||||
$(ECHO) "$(BRIGHT_COL)builing gdb...$(DEFAULT_COL)"
|
||||
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
|
||||
|
||||
$(GDB_INSTALLED_BINARIES): $(GDB_BINARIES)
|
||||
$(ECHO) "$(BRIGHT_COL)installing gdb...$(DEFAULT_COL)"
|
||||
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/gdb install
|
||||
|
||||
#
|
||||
# Clean rules
|
||||
#
|
||||
|
||||
clean:
|
||||
rm -rf $(addprefix $(CONTRIB_DIR)/,binutils-$(BINUTILS_VERSION) gcc-$(GCC_VERSION))
|
||||
rm -rf build
|
||||
|
||||
cleanall: clean
|
||||
rm -rf $(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2)
|
||||
rm -rf $(DOWNLOAD_DIR)/gcc-core-$(GCC_VERSION).tar.bz2
|
||||
rm -rf $(DOWNLOAD_DIR)/gcc-g++-$(GCC_VERSION).tar.bz2
|
||||
|
||||
#
|
||||
# Install rules
|
||||
#
|
||||
|
||||
install: build_all
|
||||
$(ECHO) "$(BRIGHT_COL)installing tool chain to '$(INSTALL_LOCATION)'...$(DEFAULT_COL)"
|
||||
$(VERBOSE)sudo cp -a --remove-destination --no-target-directory $(LOCAL_INSTALL_LOCATION) $(INSTALL_LOCATION)
|
||||
|
||||
Reference in New Issue
Block a user