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