initial commit - results from 3 days of jamming
commit
3ebb9804fa
|
@ -0,0 +1 @@
|
||||||
|
build/*
|
|
@ -0,0 +1 @@
|
||||||
|
local/*
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###### Parse Arguments ########################################################
|
||||||
|
command=$1
|
||||||
|
args=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
args+=(${!i})
|
||||||
|
done
|
||||||
|
|
||||||
|
###### Source the Core ########################################################
|
||||||
|
bld_path="$(dirname $(realpath "$0"))"
|
||||||
|
source "$bld_path/bld_core.sh"
|
||||||
|
|
||||||
|
###### Dispatch ###############################################################
|
||||||
|
if [ "$command" == "cmp" ]; then
|
||||||
|
bld_compile "${args[@]}"
|
||||||
|
elif [ "$command" == "lnk" ]; then
|
||||||
|
bld_link "${args[@]}"
|
||||||
|
elif [ "$command" == "lib" ]; then
|
||||||
|
bld_lib "${args[@]}"
|
||||||
|
elif [ "$command" == "unit" ]; then
|
||||||
|
bld_unit "${args[@]}"
|
||||||
|
else
|
||||||
|
echo "unknown command '$command'"
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,615 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###### Usage ##################################################################
|
||||||
|
# This script is meant to be invoked by the 'source' command. The variable
|
||||||
|
# bld_path should first be set to contain the path to the root folder of the
|
||||||
|
# bld system:
|
||||||
|
# bld_path="$(dirname $(realpath "$0"))"/<path-from-here-to-bld>
|
||||||
|
# source "$bld_path/bld_core.sh"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The following bld functions form the core "bld commands":
|
||||||
|
# bld_compile, bld_link, bld_lib, bld_unit
|
||||||
|
#
|
||||||
|
# And there are several more helper functions:
|
||||||
|
# bld_print_implicit_opts, bld_load_local_opts
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Signatures:
|
||||||
|
# bld_compile <source-file> <zero-or-more-options>
|
||||||
|
# bld_link <out-name> <one-or-more-source-files-objs-or-libs> -- <zero-or-more-options>
|
||||||
|
# bld_lib <out-name> <one-or-more-source-files-or-objs> -- <zero-or-more-options>
|
||||||
|
# bld_unit <source-file> <zero-or-more-options>
|
||||||
|
#
|
||||||
|
# bld_print_implicit_opts (no arguments)
|
||||||
|
# bld_load_local_opts (no arguments)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Shared notes for all:
|
||||||
|
# + Options are gathered from the command line, from the local context, and
|
||||||
|
# in the case of the commands bld_compile and bld_unit, from the source file.
|
||||||
|
# + Options in source files are specified between the strings //$ and //.
|
||||||
|
# Object files and library files should be specified with the extensions
|
||||||
|
# .obj and .lib respectively. The system automatically modifies the names to
|
||||||
|
# match the naming used by the selected context.
|
||||||
|
# + When the option "diagnostics" is included extra details will be printed
|
||||||
|
# from the bld commands. Showing the full list of options, invokation lines,
|
||||||
|
# and the build path.
|
||||||
|
#
|
||||||
|
# bld_compile:
|
||||||
|
# + Creates an object file from a single source file via the selected compiler.
|
||||||
|
#
|
||||||
|
# bld_link:
|
||||||
|
# + Creates executables and shared binaries from source files, object files,
|
||||||
|
# and static libraries. First uses the bld_compile command on the source files.
|
||||||
|
# Uses the selected linker.
|
||||||
|
# + The output is a shared binary (.dll or .so) when the option "dll" is
|
||||||
|
# included.
|
||||||
|
#
|
||||||
|
# bld_lib:
|
||||||
|
# + Creates a static library from source files and object files. First uses
|
||||||
|
# the bld_compile command on the source files. Uses the OS to determine the
|
||||||
|
# correct archiver.
|
||||||
|
#
|
||||||
|
# bld_unit:
|
||||||
|
# + Creates an executable (or shared binary) from a single source file.
|
||||||
|
# This command essentially does a single bld_compile then bld_link. With
|
||||||
|
# two differences:
|
||||||
|
# 1. The options from the source file are visible to the bld_link.
|
||||||
|
# 2. The name of the executable is determined either from the first option
|
||||||
|
# in the list or from the source file name if there are no options.
|
||||||
|
#
|
||||||
|
# bld_print_implicit_opts:
|
||||||
|
# + Shows the implicit options loaded from the local parameters script.
|
||||||
|
#
|
||||||
|
# bld_load_local_opts:
|
||||||
|
# + It is possible and sometimes useful to modify the local parameters after
|
||||||
|
# they are loaded to create certain kinds of build scripts. This function
|
||||||
|
# resets the local parameters to their original states by rerunning the
|
||||||
|
# local parameters script.
|
||||||
|
|
||||||
|
|
||||||
|
###### Flags From Opts ########################################################
|
||||||
|
|
||||||
|
function bld_flags_from_opts {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local in_file=$1
|
||||||
|
local opts=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
|
||||||
|
###### load file ##########################################################
|
||||||
|
local flags_raw=()
|
||||||
|
IFS=$'\r\n' GLOBIGNORE='*' command eval 'flags_raw=($(cat $in_file))'
|
||||||
|
|
||||||
|
###### filter #############################################################
|
||||||
|
local flags=()
|
||||||
|
for ((i=0;i<${#flags_raw[@]};i+=1)); do
|
||||||
|
local flag=${flags_raw[i]}
|
||||||
|
|
||||||
|
###### skip blanks and comments #######################################
|
||||||
|
if [[ -z "${flag// }" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ "${flag:0:1}" == "#" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### parse line filters #############################################
|
||||||
|
local line_filters=()
|
||||||
|
while [[ $flag = *">"* ]]; do
|
||||||
|
line_filters+=("${flag%%>*}")
|
||||||
|
flag="${flag#*>}"
|
||||||
|
done
|
||||||
|
|
||||||
|
###### check filters ##################################################
|
||||||
|
local can_include=1
|
||||||
|
for ((j=0;j<${#line_filters[@]};j+=1)); do
|
||||||
|
can_include=0
|
||||||
|
for ((k=0;k<${#opts[@]};k+=1)); do
|
||||||
|
if [[ ${opts[k]} = ${line_filters[j]} ]]; then
|
||||||
|
can_include=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$can_include" = "0" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$can_include" = "1" ]]; then
|
||||||
|
flags+=("${flag}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${flags[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Opts From Src ##########################################################
|
||||||
|
|
||||||
|
function bld_opts_from_src {
|
||||||
|
###### split file into tokens #############################################
|
||||||
|
local in_file=$1
|
||||||
|
local tokens=($(grep "//\\$" $in_file))
|
||||||
|
|
||||||
|
###### parse ##############################################################
|
||||||
|
local in_params_range="0"
|
||||||
|
local params=()
|
||||||
|
for ((i=0; i<${#tokens[@]}; i+=1)); do
|
||||||
|
local string="${tokens[i]}"
|
||||||
|
if [[ "$in_params_range" == "0" ]]; then
|
||||||
|
if [[ "$string" == "//$" ]]; then
|
||||||
|
in_params_range="1"
|
||||||
|
fi
|
||||||
|
elif [[ "$in_params_range" == "1" ]]; then
|
||||||
|
if [[ "${string:0:2}" == "//" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
params+=($string)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${params[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Dedup ##################################################################
|
||||||
|
|
||||||
|
function bld_dedup {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local in=()
|
||||||
|
for ((i=1; i<=$#; i+=1)); do
|
||||||
|
in+=(${!i})
|
||||||
|
done
|
||||||
|
|
||||||
|
###### dedup ##############################################################
|
||||||
|
local out=()
|
||||||
|
for ((i=0; i<${#in[@]}; i+=1)); do
|
||||||
|
local string=${in[i]}
|
||||||
|
local is_dup="0"
|
||||||
|
for ((j=0; j<${#out[@]}; j+=1)); do
|
||||||
|
if [[ "$string" == "${out[j]}" ]]; then
|
||||||
|
is_dup="1"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$is_dup" == "0" ]]; then
|
||||||
|
out+=($string)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${out[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Has Opt ################################################################
|
||||||
|
|
||||||
|
function bld_has_opt {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local key_opt=$1
|
||||||
|
local opts=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
|
||||||
|
###### scan ###############################################################
|
||||||
|
local has_key=0
|
||||||
|
for ((i=0;i<${#opts[@]};i+=1)); do
|
||||||
|
local opt=${opts[i]}
|
||||||
|
if [[ "$opt" == "$key_opt" ]]; then
|
||||||
|
has_key=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $has_key
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Load Local Options #####################################################
|
||||||
|
|
||||||
|
function bld_load_local_opts {
|
||||||
|
###### os cracking ########################################################
|
||||||
|
os="undefined"
|
||||||
|
if [ "$OSTYPE" == "win32" ] ||
|
||||||
|
[ "$OSTYPE" == "msys" ]; then
|
||||||
|
os="windows"
|
||||||
|
elif [ "$OSTYPE" == "linux-gnu" ]; then
|
||||||
|
os="linux"
|
||||||
|
elif [ "$OSTYPE" == "darwin" ]; then
|
||||||
|
os="mac"
|
||||||
|
fi
|
||||||
|
###### load parameters from the local script ################################
|
||||||
|
if [ -f "$local_path/bld_params.sh" ]; then
|
||||||
|
source "$local_path/bld_params.sh"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Implicit Opts ##########################################################
|
||||||
|
|
||||||
|
function bld_implicit_opts {
|
||||||
|
echo $compiler $compile_mode $os $arch $linker $ctx_opts
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Print Implicit Options #################################################
|
||||||
|
|
||||||
|
function bld_print_implicit_opts {
|
||||||
|
local opts=($(bld_implicit_opts))
|
||||||
|
local bracketed=()
|
||||||
|
for ((i=0; i<=${#opts[@]}; i+=1)); do
|
||||||
|
local opt="${opts[i]}"
|
||||||
|
if [ "$opt" != "" ]; then
|
||||||
|
bracketed+=("[${opts[i]}]")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "${bracketed[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Compile ################################################################
|
||||||
|
|
||||||
|
function bld_compile {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local in_file=$1
|
||||||
|
local opts=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
if [ "$in_file" == "" ]; then
|
||||||
|
echo "compile: missing input file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### finish in file #####################################################
|
||||||
|
local final_in_file=$in_file
|
||||||
|
|
||||||
|
###### finish options #####################################################
|
||||||
|
local src_opts=($(bld_opts_from_src $final_in_file))
|
||||||
|
local impl_opts=($(bld_implicit_opts))
|
||||||
|
local all_opts=($(bld_dedup ${impl_opts[@]} ${opts[@]} ${src_opts[@]}))
|
||||||
|
|
||||||
|
###### diagnostics ########################################################
|
||||||
|
local diagnostics=$(bld_has_opt diagnostics ${all_opts[@]})
|
||||||
|
|
||||||
|
###### out file name ######################################################
|
||||||
|
local dot_ext_obj=$(bld_ext_obj)
|
||||||
|
local file_base=${final_in_file##*/}
|
||||||
|
local file_base_no_ext=${file_base%.*}
|
||||||
|
local out_file="$file_base_no_ext$dot_ext_obj"
|
||||||
|
|
||||||
|
###### get real flags #####################################################
|
||||||
|
local flags=$(bld_flags_from_opts $compiler_flags_path ${all_opts[@]})
|
||||||
|
|
||||||
|
###### move to output folder ##############################################
|
||||||
|
mkdir -p "$build_path"
|
||||||
|
cd $build_path
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo "build path: $build_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### delete existing object file ########################################
|
||||||
|
rm -f "$out_file_base.o"
|
||||||
|
rm -f "$out_file_base.obj"
|
||||||
|
|
||||||
|
###### final flags ########################################################
|
||||||
|
local final_flags="-c -I$src_path ${flags}"
|
||||||
|
|
||||||
|
|
||||||
|
###### compile ############################################################
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo "cmp $final_in_file -- ${all_opts[@]}"
|
||||||
|
echo $compiler "$final_in_file" $final_flags
|
||||||
|
fi
|
||||||
|
if [ "$compiler" == "clang" ]; then
|
||||||
|
echo "$file_base"
|
||||||
|
fi
|
||||||
|
$compiler "$final_in_file" $final_flags
|
||||||
|
|
||||||
|
# return of status from compiler is automatic here.
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Link ###################################################################
|
||||||
|
|
||||||
|
function bld_link {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local out_name=$1
|
||||||
|
local in_files=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
if [ "${!i}" == "--" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
in_files+=(${!i})
|
||||||
|
done
|
||||||
|
local opts=()
|
||||||
|
for ((i+=1; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
if [ "$out_name" == "" ]; then
|
||||||
|
echo "link: missing output name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "${#in_files}" == "0" ]; then
|
||||||
|
echo "link: missing input file(s)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### finish options #####################################################
|
||||||
|
local impl_opts=($(bld_implicit_opts))
|
||||||
|
local all_opts=($(bld_dedup ${opts[@]} ${impl_opts[@]}))
|
||||||
|
|
||||||
|
###### diagnostics ########################################################
|
||||||
|
local diagnostics=$(bld_has_opt diagnostics ${all_opts[@]})
|
||||||
|
|
||||||
|
###### sort in files ######################################################
|
||||||
|
local in_src=()
|
||||||
|
local in_obj=()
|
||||||
|
local in_lib=()
|
||||||
|
for ((i=0; i<${#in_files[@]}; i+=1)); do
|
||||||
|
local file="${in_files[i]}"
|
||||||
|
local ext="${file##*.}"
|
||||||
|
if [[ "$ext" == "c" || "$ext" == "cpp" ]]; then
|
||||||
|
in_src+=($file)
|
||||||
|
elif [[ "$ext" == "o" || "$ext" == "obj" ]]; then
|
||||||
|
in_obj+=($file)
|
||||||
|
elif [[ "$ext" == "lib" ]]; then
|
||||||
|
in_lib+=($file)
|
||||||
|
else
|
||||||
|
echo "WARNING: ignoring unrecognized file type $file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
###### auto correct object files ##########################################
|
||||||
|
local dot_ext_obj=$(bld_ext_obj)
|
||||||
|
for ((i=0; i<${#in_obj[@]}; i+=1)); do
|
||||||
|
local file_name="${in_obj[i]}"
|
||||||
|
local base_name="${file_name%.*}"
|
||||||
|
in_obj[$i]="$base_name$dot_ext_obj"
|
||||||
|
done
|
||||||
|
|
||||||
|
###### compile source files ###############################################
|
||||||
|
for ((i=0; i<${#in_src[@]}; i+=1)); do
|
||||||
|
bld_compile "${in_src[i]}" ${all_opts[@]}
|
||||||
|
local status=$?
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
return $status
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
###### intermediate object files ##########################################
|
||||||
|
local interm_obj=()
|
||||||
|
for ((i=0; i<${#in_src[@]}; i+=1)); do
|
||||||
|
local file_name="${in_src[i]}"
|
||||||
|
local base_name="${file_name##*/}"
|
||||||
|
local base_name_no_ext="${base_name%.*}"
|
||||||
|
interm_obj+=($base_name_no_ext$dot_ext_obj)
|
||||||
|
done
|
||||||
|
|
||||||
|
###### get real flags #####################################################
|
||||||
|
local flags=$(bld_flags_from_opts $linker_flags_path ${all_opts[@]})
|
||||||
|
|
||||||
|
###### out file name ######################################################
|
||||||
|
local dot_ext_out=""
|
||||||
|
local is_dll=$(bld_has_opt dll ${all_opts[@]})
|
||||||
|
if [ "$is_dll" == "0" ]; then
|
||||||
|
dot_ext_out=$(bld_ext_exe)
|
||||||
|
else
|
||||||
|
dot_ext_out=$(bld_ext_dll)
|
||||||
|
fi
|
||||||
|
out_file="$out_name$dot_ext_out"
|
||||||
|
|
||||||
|
###### move to output folder ##############################################
|
||||||
|
mkdir -p "$build_path"
|
||||||
|
cd $build_path
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo "build path: $build_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### final files to linker ##############################################
|
||||||
|
local final_in_files="${interm_obj[@]} ${in_obj[@]} ${in_lib[@]}"
|
||||||
|
|
||||||
|
###### set first diagnostic string ########################################
|
||||||
|
local first_diagnostic_string="lnk $final_in_files -- ${all_opts[@]}"
|
||||||
|
|
||||||
|
###### link ###############################################################
|
||||||
|
local status=0
|
||||||
|
local invokation=""
|
||||||
|
if [[ "$linker" == "link" || "$linker" == "lld-link" ]]; then
|
||||||
|
invokation="$linker -OUT:$out_file $flags $final_in_files"
|
||||||
|
elif [ "$linker" == "clang" ]; then
|
||||||
|
invokation="$linker -o \"$out_file\" $flags $final_in_files"
|
||||||
|
else
|
||||||
|
echo "ERROR: invokation not defined for this linker"
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
if [ "$invokation" != "" ]; then
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo $first_diagnostic_string
|
||||||
|
echo $invokation
|
||||||
|
fi
|
||||||
|
echo "$out_file"
|
||||||
|
$invokation
|
||||||
|
status=$?
|
||||||
|
fi
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Library ################################################################
|
||||||
|
|
||||||
|
function bld_lib {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local out_name=$1
|
||||||
|
local in_files=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
if [ "${!i}" == "--" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
in_files+=(${!i})
|
||||||
|
done
|
||||||
|
local opts=()
|
||||||
|
for ((i+=1; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
if [ "$out_name" == "" ]; then
|
||||||
|
echo "lib: missing output name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "${#in_files}" == "0" ]; then
|
||||||
|
echo "lib: missing input file(s)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### finish options #####################################################
|
||||||
|
local impl_opts=($(bld_implicit_opts))
|
||||||
|
local all_opts=($(bld_dedup ${opts[@]} ${impl_opts[@]}))
|
||||||
|
|
||||||
|
###### diagnostics ########################################################
|
||||||
|
local diagnostics=$(bld_has_opt diagnostics ${all_opts[@]})
|
||||||
|
|
||||||
|
###### sort in files ######################################################
|
||||||
|
local in_src=()
|
||||||
|
local in_obj=()
|
||||||
|
for ((i=0; i<${#in_files[@]}; i+=1)); do
|
||||||
|
local file="${in_files[i]}"
|
||||||
|
local ext="${file##*.}"
|
||||||
|
if [[ "$ext" == "c" || "$ext" == "cpp" ]]; then
|
||||||
|
in_src+=($file)
|
||||||
|
elif [[ "$ext" == "o" || "$ext" == "obj" ]]; then
|
||||||
|
in_obj+=($file)
|
||||||
|
else
|
||||||
|
echo "WARNING: ingnoring unrecgonized file type $file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
###### auto correct object files ##########################################
|
||||||
|
local dot_ext_obj=$(bld_ext_obj)
|
||||||
|
for ((i=0; i<${#in_obj[@]}; i+=1)); do
|
||||||
|
local file_name="${in_obj[i]}"
|
||||||
|
local base_name="${file_name%.*}"
|
||||||
|
in_obj[$i]=$base_name$dot_ext_obj
|
||||||
|
done
|
||||||
|
|
||||||
|
###### compile source files ###############################################
|
||||||
|
for ((i=0; i<${#in_src[@]}; i+=1)); do
|
||||||
|
bld_compile "${in_src[i]}" ${all_opts[@]}
|
||||||
|
local status=$?
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
return $status
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
###### intermediate object files ##########################################
|
||||||
|
local interm_obj=()
|
||||||
|
for ((i=0; i<${#in_src[@]}; i+=1)); do
|
||||||
|
local file_name="${in_src[i]}"
|
||||||
|
local base_name="${file_name##*/}"
|
||||||
|
local base_name_no_ext="${base_name%.*}"
|
||||||
|
interm_obj+=($base_name_no_ext$dot_ext_obj)
|
||||||
|
done
|
||||||
|
|
||||||
|
###### out file name ######################################################
|
||||||
|
local out_file=""
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
out_file="$out_name.lib"
|
||||||
|
elif [ "$os" == "linux" || "$os" == "mac" ]; then
|
||||||
|
out_file="lib$out_name.a"
|
||||||
|
else
|
||||||
|
echo "ERROR: static library output not defined for OS: $os"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### final library build input files ####################################
|
||||||
|
local final_in_files="${interm_obj[@]} ${in_obj[@]}"
|
||||||
|
|
||||||
|
###### move to output folder ##############################################
|
||||||
|
mkdir -p "$build_path"
|
||||||
|
cd $build_path
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo "build path: $build_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### set first diagnostic string ########################################
|
||||||
|
local first_diagnostic_string="lib $final_in_files -- ${all_opts[@]}"
|
||||||
|
|
||||||
|
###### build library ######################################################
|
||||||
|
local status=0
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
if [ "$diagnostics" == "1" ]; then
|
||||||
|
echo $first_diagnostic_string
|
||||||
|
echo lib -nologo -OUT:"$out_file" $final_in_files
|
||||||
|
fi
|
||||||
|
echo "$out_file"
|
||||||
|
lib -nologo -OUT:"$out_file" $final_in_files
|
||||||
|
status=$?
|
||||||
|
elif [ "$os" == "linux" || "$os" == "mac" ]; then
|
||||||
|
# TODO(allen): invoke ar here - make sure to delete the original .a first
|
||||||
|
# because ar does not (seem) to replace the output file, just append
|
||||||
|
echo "TODO: implement ar path in bld_core.sh:bld_lib"
|
||||||
|
status=1
|
||||||
|
else
|
||||||
|
echo "ERROR: static library invokation not defined for OS: $os"
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Unit ###################################################################
|
||||||
|
|
||||||
|
function bld_unit {
|
||||||
|
###### parse arguments ####################################################
|
||||||
|
local main_file=$1
|
||||||
|
local opts=()
|
||||||
|
for ((i=2; i<=$#; i+=1)); do
|
||||||
|
opts+=(${!i})
|
||||||
|
done
|
||||||
|
if [ "$main_file" == "" ]; then
|
||||||
|
echo "unit: missing main file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### set out name #######################################################
|
||||||
|
local out_name=""
|
||||||
|
if [ "${#opts}" == "0" ]; then
|
||||||
|
local file_base=${main_file##*/}
|
||||||
|
local file_base_no_ext=${file_base%.*}
|
||||||
|
out_name=$file_base_no_ext
|
||||||
|
else
|
||||||
|
out_name="${opts[0]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
###### finish options #####################################################
|
||||||
|
local src_opts=$(bld_opts_from_src $main_file)
|
||||||
|
local impl_opts=($(bld_implicit_opts))
|
||||||
|
local all_opts=($(bld_dedup $out_name ${opts[@]} ${src_opts[@]} ${impl_opts[@]}))
|
||||||
|
|
||||||
|
###### link ###############################################################
|
||||||
|
bld_link $out_name $main_file ${in_files[@]} -- ${all_opts[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Special Ifs ############################################################
|
||||||
|
|
||||||
|
function bld_ext_obj {
|
||||||
|
echo $(bld_flags_from_opts $file_extensions_path $compiler obj)
|
||||||
|
}
|
||||||
|
function bld_ext_exe {
|
||||||
|
echo $(bld_flags_from_opts $file_extensions_path $os exe)
|
||||||
|
}
|
||||||
|
function bld_ext_dll {
|
||||||
|
echo $(bld_flags_from_opts $file_extensions_path $os dll)
|
||||||
|
}
|
||||||
|
|
||||||
|
###### Get Paths ##############################################################
|
||||||
|
if [ ! -f "$bld_path/bld_core.sh" ]; then
|
||||||
|
echo bld_path set incorrectly
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
local_path="$bld_path/local"
|
||||||
|
|
||||||
|
###### Load Locals ############################################################
|
||||||
|
bld_load_local_opts
|
||||||
|
|
||||||
|
|
||||||
|
# NOTES - for future iterations of this system
|
||||||
|
# + The "source" approach creates problems for locating the bld path because
|
||||||
|
# when a script is "sourced" it inherits the $0 from the "caller". Two ideas:
|
||||||
|
# 1. There may be a way to fix this issue relating to passing parameters
|
||||||
|
# to the "sourced" script
|
||||||
|
# 2. Setup a locator script that can be called the normal way before sourcing
|
||||||
|
# the core to save the bld_path for the core to see
|
||||||
|
# + It would be nice to include an automatic slash fixer \ -> /
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bld_path=$(dirname "$0")
|
||||||
|
local_path="$bld_path/local"
|
||||||
|
mkdir -p "$local_path"
|
||||||
|
cp $bld_path/default.bld_params.sh $local_path/bld_params.sh
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
compiler="cl"
|
||||||
|
compile_mode="debug"
|
||||||
|
arch="x64"
|
||||||
|
linker="lld-link"
|
||||||
|
ctx_opts=""
|
||||||
|
|
||||||
|
cd $bld_path/../..
|
||||||
|
root_path=$PWD
|
||||||
|
|
||||||
|
build_path="$root_path/build"
|
||||||
|
src_path="$root_path/src"
|
||||||
|
compiler_flags_path="$root_path/bin/compiler_flags.txt"
|
||||||
|
linker_flags_path="$root_path/bin/linker_flags.txt"
|
||||||
|
file_extensions_path="$root_path/bin/file_extensions.txt"
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bld_path="$(dirname $(realpath "$0"))"/bld
|
||||||
|
source "$bld_path/bld_core.sh"
|
||||||
|
|
||||||
|
bld_print_implicit_opts
|
||||||
|
bld_unit $src_path/podcastoscope.cpp
|
|
@ -0,0 +1,20 @@
|
||||||
|
###### Include Paths ##########################################################
|
||||||
|
-I/c/mr4th/mr4th/src/
|
||||||
|
-I/c/mr4th/mr4th/src/dependencies
|
||||||
|
-I../src/dependencies
|
||||||
|
|
||||||
|
###### CL #####################################################################
|
||||||
|
cl>-FC
|
||||||
|
cl>-GR-
|
||||||
|
cl>-EHa
|
||||||
|
cl>-nologo
|
||||||
|
|
||||||
|
###### Clang ##################################################################
|
||||||
|
clang>-Wno-writable-strings
|
||||||
|
clang>-Wno-switch
|
||||||
|
|
||||||
|
###### Debug ##################################################################
|
||||||
|
debug>-DENABLE_ASSERT=1
|
||||||
|
release>-DENABLE_ASSERT=0
|
||||||
|
cl>debug>-Zi
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
obj>cl>.obj
|
||||||
|
obj>clang>.o
|
||||||
|
obj>gcc>.o
|
||||||
|
|
||||||
|
exe>windows>.exe
|
||||||
|
dll>windows>.dll
|
||||||
|
dll>linux>.so
|
||||||
|
dll>mac>.so
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
###### link ###################################################################
|
||||||
|
lld-link>-nologo
|
||||||
|
lld-link>-DEFAULTLIB:libcmt
|
||||||
|
lld-link>-OPT:REF
|
||||||
|
lld-link>-INCREMENTAL:NO
|
||||||
|
lld-link>-DEBUG
|
||||||
|
lld-link>x64>-MACHINE:X64
|
||||||
|
lld-link>console>-SUBSYSTEM:CONSOLE
|
||||||
|
lld-link>graphical>-SUBSYSTEM:WINDOWS
|
||||||
|
|
||||||
|
windows>Winmm.lib
|
||||||
|
windows>Userenv.lib
|
||||||
|
windows>Advapi32.lib
|
||||||
|
windows>graphical>User32.lib
|
||||||
|
windows>graphical>Gdi32.lib
|
||||||
|
|
||||||
|
freetype>libfreetype.lib
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
p1=C:/mr4th/podcast/avatars/allen.png
|
||||||
|
p2=C:/mr4th/podcast/test__anti_allen/test__allen.wav
|
||||||
|
p3=C:/mr4th/podcast/avatars/anti_allen.png
|
||||||
|
p4=C:/mr4th/podcast/test__anti_allen/test__anti_allen.wav
|
||||||
|
|
||||||
|
cd build
|
||||||
|
./podcastoscope.exe $p1 $p2 $p3 $p4
|
|
@ -0,0 +1,42 @@
|
||||||
|
version(2);
|
||||||
|
project_name = "Video Render";
|
||||||
|
patterns = {
|
||||||
|
"*.c",
|
||||||
|
"*.cpp",
|
||||||
|
"*.h",
|
||||||
|
"*.m",
|
||||||
|
"*.bat",
|
||||||
|
"*.sh",
|
||||||
|
"*.4coder",
|
||||||
|
"*.txt",
|
||||||
|
};
|
||||||
|
blacklist_patterns = {
|
||||||
|
".*",
|
||||||
|
};
|
||||||
|
load_paths_base = {
|
||||||
|
{ ".", .relative = true, .recursive = true, },
|
||||||
|
};
|
||||||
|
load_paths = {
|
||||||
|
.win = load_paths_base,
|
||||||
|
.linux = load_paths_base,
|
||||||
|
.mac = load_paths_base,
|
||||||
|
};
|
||||||
|
|
||||||
|
commands = {
|
||||||
|
.build = {
|
||||||
|
.out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
|
||||||
|
.win = "git_bash bin/build_video_render.sh", },
|
||||||
|
.run = {
|
||||||
|
.out = "*run*", .footer_panel = false, .save_dirty_files = true,
|
||||||
|
.win = "git_bash bin/run_video_render_test.sh", },
|
||||||
|
|
||||||
|
.run_play_temp_wave = { .out = "*run*", .footer_panel = false, .save_dirty_files = false,
|
||||||
|
.win = "pushd ..\\..\\mr4th\\build & play_temp_wave", },
|
||||||
|
};
|
||||||
|
|
||||||
|
fkey_command = {
|
||||||
|
.F1 = "build",
|
||||||
|
.F2 = "run",
|
||||||
|
|
||||||
|
.F5 = "run_play_temp_wave"
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,230 @@
|
||||||
|
/* date = April 15th 2023 2:40 pm */
|
||||||
|
|
||||||
|
#ifndef VIDEO_RENDER_H
|
||||||
|
#define VIDEO_RENDER_H
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// NOTE(allen): Audio Processing
|
||||||
|
|
||||||
|
// types
|
||||||
|
struct Track{
|
||||||
|
F32 *channels[2];
|
||||||
|
U32 sample_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpeakerMarker{
|
||||||
|
U32 frame_idx;
|
||||||
|
U32 speaker_idx;
|
||||||
|
B32 begin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpeakerMarkerNode{
|
||||||
|
SpeakerMarkerNode *next;
|
||||||
|
SpeakerMarker marker;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpeakerMarkerList{
|
||||||
|
SpeakerMarkerNode *first;
|
||||||
|
SpeakerMarkerNode *last;
|
||||||
|
U64 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpeakerMarkerArray{
|
||||||
|
SpeakerMarker *markers;
|
||||||
|
U64 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SortRange{
|
||||||
|
SortRange *next;
|
||||||
|
U64 first;
|
||||||
|
U64 opl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Array_F32{
|
||||||
|
F32 *v;
|
||||||
|
U64 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
// functions
|
||||||
|
function String8
|
||||||
|
bop_f32_from_s16(M_Arena *arena, String8 in);
|
||||||
|
|
||||||
|
function Track
|
||||||
|
track_from_file_path(M_Arena *arena, String8 full_path);
|
||||||
|
|
||||||
|
function F32
|
||||||
|
decibel_from_linear(F32 r);
|
||||||
|
|
||||||
|
function Array_F32
|
||||||
|
db_per_frame_from_samples(M_Arena *arena,
|
||||||
|
F32 *samples, U32 sample_count,
|
||||||
|
U32 sample_frequency);
|
||||||
|
|
||||||
|
function void
|
||||||
|
speaker_marker_push(M_Arena *arena, SpeakerMarkerList *list,
|
||||||
|
U32 frame_idx, U32 speaker_idx, B32 begin);
|
||||||
|
|
||||||
|
function SpeakerMarkerArray
|
||||||
|
speaker_marker_array_from_list(M_Arena *arena, SpeakerMarkerList *list);
|
||||||
|
|
||||||
|
function void
|
||||||
|
speaker_marker_array_sort_in_place(SpeakerMarker *markers, U64 count);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// NOTE(allen): Main Types
|
||||||
|
|
||||||
|
// data table
|
||||||
|
global F32
|
||||||
|
master_band_frequencies_hz[] = {
|
||||||
|
23.8f,
|
||||||
|
28.3f,
|
||||||
|
33.6f,
|
||||||
|
40.0f,
|
||||||
|
47.6f,
|
||||||
|
56.6f,
|
||||||
|
67.3f,
|
||||||
|
80.0f,
|
||||||
|
95.1f,
|
||||||
|
113.1f,
|
||||||
|
134.6f,
|
||||||
|
160.0f,
|
||||||
|
190.3f,
|
||||||
|
226.3f,
|
||||||
|
269.1f,
|
||||||
|
320.0f,
|
||||||
|
380.6f,
|
||||||
|
452.6f,
|
||||||
|
538.2f,
|
||||||
|
640.0f,
|
||||||
|
761.1f,
|
||||||
|
905.1f,
|
||||||
|
1076.4f,
|
||||||
|
1280.0f,
|
||||||
|
1522.2f,
|
||||||
|
1810.2f,
|
||||||
|
2152.7f,
|
||||||
|
2560.0f,
|
||||||
|
3044.4f,
|
||||||
|
3620.4f,
|
||||||
|
4305.4f,
|
||||||
|
5120.0f,
|
||||||
|
6088.7f,
|
||||||
|
7240.8f,
|
||||||
|
8610.8f,
|
||||||
|
10240.0f,
|
||||||
|
12177.5f,
|
||||||
|
14481.6f,
|
||||||
|
17221.6f,
|
||||||
|
};
|
||||||
|
|
||||||
|
global F32
|
||||||
|
avatar_band_frequencies_hz[] = {
|
||||||
|
40.f,
|
||||||
|
80.f,
|
||||||
|
160.f,
|
||||||
|
320.f,
|
||||||
|
640.f,
|
||||||
|
1280.f,
|
||||||
|
2560.f,
|
||||||
|
5120.f,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MASTER_BAND_COUNT (ArrayCount(master_band_frequencies_hz) - 1)
|
||||||
|
#define AVATAR_BAND_COUNT (ArrayCount(avatar_band_frequencies_hz) - 1)
|
||||||
|
|
||||||
|
#define MAX_BAND_COUNT Max(MASTER_BAND_COUNT, AVATAR_BAND_COUNT)
|
||||||
|
|
||||||
|
// types
|
||||||
|
struct Speaker{
|
||||||
|
String8 avatar_path;
|
||||||
|
String8 audio_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProcessedTrack{
|
||||||
|
U32 frame_count;
|
||||||
|
F32 *max_level_db_per_frame;
|
||||||
|
F32 *band_level_db_per_frame[MAX_BAND_COUNT];
|
||||||
|
U32 band_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpeakerState{
|
||||||
|
F32 is_speaking_level;
|
||||||
|
F32 freq_wiggles[MAX_BAND_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
// functions
|
||||||
|
function ProcessedTrack
|
||||||
|
processed_track_from_samples(M_Arena *arena,
|
||||||
|
F32 *samples, U32 sample_count,
|
||||||
|
U32 sample_frequency,
|
||||||
|
F32 *band_freq_hz, U32 band_count);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// NOTE(allen): Graphics Types
|
||||||
|
|
||||||
|
// types
|
||||||
|
struct Vertex{
|
||||||
|
// primitive shape
|
||||||
|
V2F32 p;
|
||||||
|
|
||||||
|
// color
|
||||||
|
U32 color;
|
||||||
|
|
||||||
|
// rectangle
|
||||||
|
I2F32 rect;
|
||||||
|
|
||||||
|
// uv
|
||||||
|
V2F32 uv;
|
||||||
|
|
||||||
|
// sat,val
|
||||||
|
F32 s_mul;
|
||||||
|
F32 v_mul;
|
||||||
|
F32 over;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RectNode{
|
||||||
|
RectNode *next;
|
||||||
|
I2F32 rect;
|
||||||
|
V4F32 top_color;
|
||||||
|
V4F32 bot_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RectList{
|
||||||
|
RectNode *first;
|
||||||
|
RectNode *last;
|
||||||
|
U64 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AvatarParams{
|
||||||
|
U32 frame_counter;
|
||||||
|
F32 radius;
|
||||||
|
F32 sat_mul;
|
||||||
|
F32 val_mul;
|
||||||
|
F32 freq_wiggles[MAX_BAND_COUNT];
|
||||||
|
U32 band_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
// functions
|
||||||
|
function void
|
||||||
|
setup_opengl_state(void);
|
||||||
|
|
||||||
|
function GLuint
|
||||||
|
avatar_gpu_texture_from_file_path(String8 full_path);
|
||||||
|
|
||||||
|
function void
|
||||||
|
draw_geometry_vert(Vertex *v, U32 count, GLuint tex, V2F32 windim);
|
||||||
|
|
||||||
|
function void
|
||||||
|
draw_geometry_rect(Vertex *v, U32 count, V2F32 windim);
|
||||||
|
|
||||||
|
function void
|
||||||
|
draw_avatar(V2F32 center, GLuint texture, AvatarParams *params, V2F32 windim);
|
||||||
|
|
||||||
|
function void
|
||||||
|
rectangle_push(M_Arena *arena, RectList *list,
|
||||||
|
I2F32 rect, V4F32 top_color, V4F32 bot_color);
|
||||||
|
|
||||||
|
function void
|
||||||
|
draw_rectangle_list(RectList *list, V2F32 windim);
|
||||||
|
|
||||||
|
#endif //VIDEO_RENDER_H
|
Reference in New Issue