diff --git a/Makefile b/Makefile index af94ad8..4991382 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,15 @@ -all: debug +all: release .PHONY: debug debug: - @./tool build debug orca + @./tool build -d --portmidi orca .PHONY: release release: - @./tool build release orca + @./tool build --portmidi orca + @echo "Executable program saved as: build/orca" >&2 + @echo "To run it, simply execute it:" >&2 + @echo "$$ build/orca" >&2 .PHONY: clean clean: diff --git a/tool b/tool index 85e3089..e71de5d 100755 --- a/tool +++ b/tool @@ -3,38 +3,50 @@ set -eu -o pipefail print_usage() { cat < [options] [arguments] +Example: + tool build --portmidi orca Commands: - build - Compile orca. - Configs: debug, release + build + Compiles the livecoding environment or the CLI tool. Targets: orca, cli - Output: build// + Output: build/ clean Removes build/ info Prints information about the detected build environment. Options: - -v Print important commands as they're executed. - -c Use a specific compiler binary. - Default: \$CC, or cc - -d Enable compiler safeguards like -fstack-protector. - You should probably do this if you plan to give the - compiled binary to other people. - --static Build static binary. - --pie Enable PIE (ASLR). - Note: --pie and --static cannot be mixed. - -s Print statistics about compile time and binary size. - -h or --help Print this message and exit. + -c Use a specific compiler binary. Default: \$CC, or cc + -d Build with debug features. Output changed to: + build/debug/ + --harden Enable compiler safeguards like -fstack-protector. + You should probably do this if you plan to give the + compiled binary to other people. + --static Build static binary. + --pie Enable PIE (ASLR). + Note: --pie and --static cannot be mixed. + -s Print statistics about compile time and binary size. + -v Print important commands as they're executed. + -h or --help Print this message and exit. Optional Features: - --portmidi Enable hardware MIDI output support with PortMIDI. - Default: not enabled - Note: PortMIDI has memory leaks and bugs. - --nomouse Disables mouse clicks. - Default: not enabled (mouse enabled). + --portmidi Enable or disable hardware MIDI output support with + --no-portmidi PortMIDI. Note: PortMIDI has memory leaks and bugs. + Default: disabled. + --mouse Enable or disable mouse features in the livecoding + --no-mouse environment. + Default: enabled. EOF } +if [[ -z "${1:-}" ]]; then + echo "Error: Command required" >&2 + print_usage >&2 + exit 1 +fi + +cmd=$1 +shift + os= case $(uname -s | awk '{print tolower($0)}') in linux*) os=linux;; @@ -53,16 +65,20 @@ pie_enabled=0 static_enabled=0 portmidi_enabled=0 mouse_disabled=0 +config_mode=release while getopts c:dhsv-: opt_val; do case "$opt_val" in -) case "$OPTARG" in + harden) protections_enabled=1;; help) print_usage; exit 0;; static) static_enabled=1;; pie) pie_enabled=1;; portmidi) portmidi_enabled=1;; - nomouse) mouse_disabled=1;; + no-portmidi|noportmidi) portmidi_enabled=0;; + mouse) mouse_disabled=0;; + no-mouse|nomouse) mouse_disabled=1;; *) echo "Unknown long option --$OPTARG" >&2 print_usage >&2 @@ -71,7 +87,7 @@ while getopts c:dhsv-: opt_val; do esac ;; c) cc_exe="$OPTARG";; - d) protections_enabled=1;; + d) config_mode=debug;; h) print_usage; exit 0;; s) stats_enabled=1;; v) verbose=1;; @@ -202,7 +218,6 @@ try_make_dir() { build_dir=build build_target() { - local build_subdir local cc_flags=() local libraries=() local source_files=() @@ -228,9 +243,8 @@ build_target() { if [[ $static_enabled = 1 ]]; then add cc_flags -static fi - case "$1" in + case $config_mode in debug) - build_subdir=debug add cc_flags -DDEBUG -ggdb # cygwin gcc doesn't seem to have this stuff, just elide for now if [[ $os != cygwin ]]; then @@ -249,7 +263,6 @@ build_target() { fi ;; release) - build_subdir=release add cc_flags -DNDEBUG -O2 -g0 if [[ $protections_enabled != 1 ]]; then add cc_flags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fno-stack-protector @@ -262,7 +275,7 @@ build_target() { add cc_flags -flto -s fi ;; - *) fatal "Unknown build config \"$1\"";; + *) fatal "Unknown build config \"$config_mode\"";; esac case $arch in @@ -287,7 +300,7 @@ build_target() { esac add source_files gbuffer.c field.c bank.c sim.c - case "$2" in + case $1 in cli) add source_files cli_main.c out_exe=cli @@ -339,7 +352,7 @@ build_target() { if [[ $portmidi_enabled = 1 ]]; then add libraries -lportmidi add cc_flags -DFEAT_PORTMIDI - if [[ $1 = debug ]]; then + if [[ $config_mode = debug ]]; then echo -e "Warning: The PortMIDI library contains bugs.\\nIt may trigger address sanitizer in debug builds.\\nThese are not bugs in orca." >&2 fi fi @@ -347,10 +360,17 @@ build_target() { add cc_flags -DFEAT_NOMOUSE fi ;; + *) + echo -e "Unknown build target '$1'\\nValid targets: orca, cli" >&2 + exit 1 + ;; esac try_make_dir "$build_dir" - try_make_dir "$build_dir/$build_subdir" - local out_path=$build_dir/$build_subdir/$out_exe + if [[ $config_mode = debug ]]; then + build_dir=$build_dir/debug + try_make_dir "$build_dir" + fi + local out_path=$build_dir/$out_exe # bash versions quirk: empty arrays might give error on expansion, use + # trick to avoid expanding second operand verbose_echo timed_stats "$cc_exe" "${cc_flags[@]}" -o "$out_path" "${source_files[@]}" ${libraries[@]+"${libraries[@]}"} @@ -379,34 +399,31 @@ EOF shift $((OPTIND - 1)) -if [[ -z "${1:-}" ]]; then - echo "Error: Command required" >&2 - print_usage >&2 - exit 1 -fi - -case "$1" in +case $cmd in info) if [[ "$#" -gt 1 ]]; then fatal "Too many arguments for 'info'" fi - print_info - exit 0 - ;; + print_info; exit 0;; build) - if [[ "$#" -lt 3 ]]; then + if [[ "$#" -lt 1 ]]; then fatal "Too few arguments for 'build'" fi - if [[ "$#" -gt 3 ]]; then - fatal "Too many arguments for 'build'" + if [[ "$#" -gt 1 ]]; then + echo "Too many arguments for 'build'" >&2 + echo "The syntax has changed. Updated usage examples:" >&2 + echo "./tool build --portmidi orca (release)" >&2 + echo "./tool build -d orca (debug)" >&2 + exit 1 fi - build_target "$2" "$3" + build_target "$1" ;; clean) if [[ -d "$build_dir" ]]; then verbose_echo rm -rf "$build_dir" fi ;; - *) fatal "Unrecognized command $1";; + help) print_usage; exit 0;; + *) fatal "Unrecognized command $cmd";; esac