-
-
Save earl/180d761ce5d27e411a6f to your computer and use it in GitHub Desktop.
A stand-alone Rebol 3 build script, for building Rebol 3 (only of the Ren/C flavour, for now). Save into `src/tools/build.reb` and run as `rebol3 src/tools/build.reb`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
REBOL [author: abolka date: 2015-07-22 tabs: none] | |
;; Current LAUNCH uses a broken system/options/boot (see CC#1892) to start | |
;; another process of the interpreter currently running. To give it a fighting | |
;; chance, we change to the working directory the user started the currently | |
;; running interpreter from. This should, primarily, improve things for when | |
;; the interpreter was started via a relative path (such as `./r3` or | |
;; `make/r3`). | |
change-dir system/options/path | |
;; Command-line arguments | |
args: protect/deep context [ | |
project-dir: none | |
build-dir: none | |
target-id: none | |
quiet?: false | |
;; Due to a bug in Rebol's command-line argument parsing (CC#2227) the | |
;; common option syntax convention with hyphens (such as "-q" and | |
;; "--quiet") doesn't currently work reliably. As a workaround, we also | |
;; allow ancient-Windows-style option syntax ("/q" and "/quiet"). | |
use [shortopt longopt unknown] [ | |
shortopt: charset {-/} | |
longopt: [#"/" | "--"] | |
parse any [system/options/args []] [ | |
any [ | |
into [shortopt {b} end | longopt {build-dir} end] | |
set build-dir string! | |
(build-dir: to-file build-dir) | |
| | |
into [shortopt {p} end | longopt {project-dir} end] | |
set project-dir string! | |
(project-dir: to-file project-dir) | |
| | |
into [shortopt {q} end | longopt {quiet} end] | |
(quiet?: true) | |
| | |
into [shortopt {t} end | longopt {target-id} end] | |
set target-id string! | |
| | |
set unknown skip ( | |
print rejoin [ | |
{Unknown option: "} unknown {". Aborting.} | |
] | |
quit/return 1 | |
) | |
] | |
] | |
] | |
;; Unless an explicit project root was provided, assume this script is | |
;; stored in src/tools/ relative to the desired project root. | |
if all [ | |
none? project-dir | |
%{} = find/last/tail system/script/path %src/tools/ | |
] [ | |
project-dir: clean-path/dir system/script/path/(%../..) | |
] | |
unless project-dir [ | |
print trim/lines { | |
Please either store this script in %src/tools/ in your Rebol | |
project tree or provide a `project-dir` command-line option. | |
} | |
quit/return 1 | |
] | |
] | |
;; Local build environment configuration constants | |
build: protect/deep context [ | |
project-dir: args/project-dir | |
source-dir: project-dir/(%src/) | |
include-dirs: reduce [ | |
source-dir/(%include/) | |
source-dir/(%codecs/) | |
] | |
tool-dir: source-dir/(%tools/) | |
build-dir: dirize any [args/build-dir project-dir/(%make/)] | |
object-dir: build-dir/(%objs/) | |
exe-file: build-dir/(%r3) | |
commands: context [ | |
cc: any [get-env {CC} %gcc] ;; TODO Split for argv, eg CC="ccache gcc"? | |
ld: any [get-env {LD} :cc] | |
] | |
] | |
;; Set up target-specific configuration constants | |
do build/tool-dir/(%common.r) ;; Needed by %systems.r | |
do build/tool-dir/(%systems.r) | |
config: config-system/guess args/target-id | |
files: context load build/tool-dir/(%file-base.r) | |
;; Local helpers | |
print-verbose: func [value [any-type!]] [ | |
unless args/quiet? [ | |
print :value | |
] | |
:value | |
] | |
to-def: func [word] [replace/all uppercase to-string word {-} {_}] | |
to-obj: func [src] [second split-path replace to-file src %.c %.o] | |
select-flags: func [ | |
{Given a FLAGS object! (associating flag names with flag values), and a | |
NAMES block! of flag names, returns a block! of values associated with the | |
named flags. No value is retained for flags not found or associated with a | |
NONE! value.} | |
flags [object!] | |
names [block!] | |
] [ | |
exclude map-each name names [select flags name] [#] | |
] | |
check-call: func [argv /local rc] [ | |
if not zero? rc: call/wait print-verbose argv [ | |
print [ | |
{!!! BUILD FAILED!} newline | |
{--- Failed call: } newline | |
argv newline | |
{--- Exit code: } rc | |
] | |
quit/return rc | |
] | |
] | |
;; Target-specific overrides | |
target-defines: map-each def [os-base os-name] [join {-DTO_} to-def config/:def] | |
target-files: files/(to-word join {os-} config/os-base) | |
; TODO if flag? +SC [remove find target-files 'host-readline.c] | |
; TODO if flag? EXE [append build/exe-file %.exe] | |
;; BUILD! | |
print {=== Preparing build environment} | |
make-dir/deep build/object-dir | |
print {=== Cleaning build output} | |
foreach f read build/object-dir [ | |
if %.o = suffix? f [ | |
delete build/object-dir/:f | |
] | |
] | |
print {=== Generating code} | |
launch/wait build/tool-dir/(%make-headers.r) | |
launch/wait/args build/tool-dir/(%make-boot.r) mold config/id | |
launch/wait build/tool-dir/(%make-host-init.r) | |
launch/wait build/tool-dir/(%make-os-ext.r) | |
launch/wait build/tool-dir/(%core-ext.r) | |
launch/wait build/tool-dir/(%make-host-ext.r) | |
launch/wait build/tool-dir/(%make-reb-lib.r) | |
print {=== Compiling core} | |
core-flags: select-flags make compiler-flags [] config/build-flags | |
core-files: compose [(files/core)] | |
remove-each item core-files [item = '+] ;; Not strictly neceesary, atm. | |
foreach srcfile core-files [ | |
check-call compose [ | |
(build/commands/cc) | |
{-c} | |
(build/source-dir/(%core)/:srcfile) | |
(target-defines) | |
{-DREB_API} | |
(core-flags) | |
(map-each path build/include-dirs [join {-I} path]) | |
{-o} | |
(build/object-dir/(to-obj srcfile)) | |
] | |
] | |
print {=== Compiling host} | |
host-flags: select-flags make compiler-flags [PIC: NCM: none] config/build-flags | |
host-files: compose [(files/os) (target-files)] | |
remove-each item host-files [item = '+] | |
foreach srcfile host-files [ | |
check-call compose [ | |
(build/commands/cc) | |
{-c} | |
(build/source-dir/(%os)/:srcfile) | |
(target-defines) | |
{-DREB_EXE} | |
{-DREB_CORE} | |
(host-flags) | |
(compiler-flags/F64) | |
(map-each path build/include-dirs [join {-I} path]) | |
{-o} | |
(build/object-dir/(to-obj srcfile)) | |
] | |
] | |
print {=== Linking executable} | |
link-flags: select-flags make linker-flags [] config/build-flags | |
link-files: compose [(core-files) (host-files)] | |
check-call compose [ | |
(build/commands/ld) | |
{-o} | |
(build/exe-file) | |
(map-each srcfile link-files [build/object-dir/(to-obj srcfile)]) | |
(link-flags) | |
] | |
print {=== BUILD SUCCEEDED!} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment