first commit

This commit is contained in:
Jose Caban
2025-06-07 11:38:03 -04:00
commit e0316ca3ff
79 changed files with 3155 additions and 0 deletions

515
gen_makefiles.sh Normal file
View File

@@ -0,0 +1,515 @@
#!/usr/bin/env bash
# Programs
declare -A PROGRAMS
PROGRAMS[HelloWorld]="HelloWorld"
PROGRAMS[FizzBuzz]="FizzBuzz"
PROGRAMS[RecurringRainfall]="RecurringRainfall"
PROGRAMS[ProducerConsumer]="ProducerConsumer"
PROGRAMS[ArrayStack]="ArrayStack"
PROGRAMS[Endian]="Endian"
PROGRAMS[BreakMemory]="BreakMemory"
PROGRAMS[AddTwoNumbers]="l33tcode_addtwonumbers"
PROGRAMS[MedianOfSortedArrays]="l33tcode_medianofsortedarrays"
PROGRAMS[ReverseWords]="l33tcode_reversewords"
PROGRAMS[merge2sortedlists]="l33tcode_merge2sortedlists"
#########################
# DON'T EDIT BELOW HERE #
#########################
declare -A CC_EXISTS
declare -A CC_EXE
declare -A CC_OPTS
declare -A LINK_OPTS
operating_system=$(uname)
# Detect command line
if [ $# == 0 ] || [ $1 == 'opt' ]; then
echo "[INFO] Enabling optimizations and Enabling debugging"
ENABLE_OPTS=true
ENABLE_DEBUG=true
elif [ $1 == 'help' ]; then
echo "Usage: gen_makefiles.sh <args>"
echo " args:"
echo " help - This message"
echo " debug - Generate makefiles with optimizations off and debugging enabled"
echo " opt - Generate makefiles with optimizations on and debugging enabled"
echo " release - Generate makefiles with optimizations and debugging disabled"
echo " If no args are provided, opt is the default"
exit 1
elif [ $1 == 'debug' ]; then
echo "[INFO] Disabling optimizations and Enabling debugging"
ENABLE_OPTS=false
ENABLE_DEBUG=true
elif [ $1 == 'release' ]; then
echo "[INFO] Enabling optimizations and Disabling debugging"
ENABLE_OPTS=true
ENABLE_DEBUG=false
else
echo "[ERR] Unknown option, use gen_makefiles.sh help for help"
exit 2
fi
###################
# Detect compilers
#
# Tries to find the compilers on the host system
# If a compiler isn't found, it won't generate makefiles for that target
#
# Priority order:
# LLVM -> GCC -> Closed Source
function detect_compilers() {
# Handy default to avoid copy/paste
INTERNAL_GCC_WARNINGS="-Wall"
if [ $ENABLE_OPTS == 'true' ]; then
INTERNAL_GCC_STYLE_DEFAULT_OPTS="-O3"
fi
if [ $ENABLE_DEBUG == 'true' ]; then
INTERNAL_GCC_STYLE_DEBUG="-g"
fi
INTERNAL_GCC_STYLE_FLAGS="$INTERNAL_GCC_STYLE_DEFAULT_OPTS $INTERNAL_GCC_WARNINGS $INTERNAL_GCC_STYLE_DEBUG"
# Ada Compiler
type -a gnatmake &> /dev/null
if [ $? == 0 ]; then
echo [INFO] Found Ada gnatmake, using gnatmake for Ada
CC_EXISTS['Ada']=true
CC_EXE['Ada']=gnatmake
CC_OPTS['Ada']=$INTERNAL_GCC_STYLE_FLAGS
else
echo [WARN] No Ada compiler found, no Ada makefiles will be generated
fi
# C Compiler
type -a clang &> /dev/null
INT_HAS_CLANG=$?
type -a gcc &> /dev/null
INT_HAS_GCC=$?
if [ $INT_HAS_CLANG == 0 ]; then
echo [INFO] Found clang, using clang for C
CC_EXISTS['C']=true
CC_EXE['C']=clang
CC_OPTS['C']=$INTERNAL_GCC_STYLE_FLAGS
elif [ $INT_HAS_GCC == 0 ]; then
echo [INFO] No clang, found gcc, using gcc for C
CC_EXISTS['C']=true
CC_EXE['C']=gcc
CC_OPTS['C']=$INTERNAL_GCC_STYLE_FLAGS
else
echo [WARN] No C compiler found, no C makefiles will be generated
fi
# Cpp Compiler
type -a clang++ &> /dev/null
INT_HAS_CLANGPP=$?
type -a g++ &> /dev/null
INT_HAS_GPP=$?
if [ $INT_HAS_CLANGPP == 0 ]; then
echo [INFO] Found clang++, using clang for C++
CC_EXISTS['Cpp']=true
CC_EXE['Cpp']=clang++
CC_OPTS['Cpp']=$INTERNAL_GCC_STYLE_FLAGS
elif [ $INT_HAS_GPP == 0 ]; then
echo [INFO] No clang++, found g++, using g++ for C++
CC_EXISTS['Cpp']=true
CC_EXE['Cpp']=g++
CC_OPTS['Cpp']=$INTERNAL_GCC_STYLE_FLAGS
else
echo [WARN] No C++ compiler found, no C++ makefiles will be generated
fi
if [ $operating_system == 'Linux' ]; then
LINK_OPTS['Cpp']="-lpthread"
elif [ $operating_system == 'FreeBSD' ]; then
LINK_OPTS['Cpp']="-lpthread"
fi
# C# Compiler
type -a mcs &> /dev/null
if [ $? == 0 ]; then
echo [INFO] Found mcs, using mcs for C#
CC_EXISTS['CSharp']=true
CC_EXE['CSharp']=mcs
if [ $ENABLE_DEBUG == true ]; then
CSHARP_DEBUG="-debug"
fi
if [ $ENABLE_OPTS == true ]; then
CSHARP_OPTS="-optimize"
fi
CC_OPTS['CSharp']="$CSHARP_DEBUG $CSHARP_OPTS"
else
echo [WARN] No C# compiler found, no C# makefiles will be generated
fi
# D Compiler
type -a ldc2 &> /dev/null
INT_HAS_LDC2=$?
type -a gdc &> /dev/null
INT_HAS_GDC=$?
if [ $INT_HAS_LDC2 == 0 ]; then
echo [INFO] Found ldc2, using ldc2 for D
CC_EXISTS['D']=true
CC_EXE['D']=ldc2
if [ $ENABLE_DEBUG == true ]; then
D_DEBUG="-g"
fi
if [ $ENABLE_OPTS == true ]; then
D_OPTS="-O3"
fi
CC_OPTS['D']="$D_DEBUG $D_OPTS"
elif [ $INT_HAS_GDC == 0 ]; then
echo [INFO] No ldc2, found gdc, using gdc for D
CC_EXISTS['D']=true
CC_EXE['D']=gdc
CC_OPTS['D']=$INTERNAL_GCC_STYLE_FLAGS
else
echo [WARN] No D compiler found, no D makefiles will be generated
fi
# Fortran compiler
type -a flang &> /dev/null
INT_HAS_FLANG=$?
type -a gfortran &> /dev/null
INT_HAS_GFORTRAN=$?
if [ $INT_HAS_FLANG == 0 ]; then
echo [INFO] Found flang, using flang for Fortran
CC_EXISTS['Fortran']=true
CC_EXE['Fortran']=flang
if [ $operating_system == 'FreeBSD' ]; then
CC_OPTS['Fortran']="$INTERNAL_GCC_STYLE_FLAGS -lexecinfo"
else
CC_OPTS['Fortran']=$INTERNAL_GCC_STYLE_FLAGS
fi
elif [ $INT_HAS_GFORTRAN == 0 ]; then
echo [INFO] No flang, found gfortran, using gfortran for Fortran
CC_EXISTS['Fortran']=true
CC_EXE['Fortran']=gfortran
CC_OPTS['Fortran']=$INTERNAL_GCC_STYLE_FLAGS
else
echo [WARN] No Fortran compiler found, no Fortran makefiles will be generated
fi
# Haskell Compiler
type -a ghc &> /dev/null
if [ $? == 0 ]; then
echo [INFO] Found ghc, using ghc for Haskell
CC_EXISTS['Haskell']=true
CC_EXE['Haskell']=ghc
if [ $ENABLE_DEBUG == true ]; then
HASKELL_DEBUG="-g"
fi
if [ $ENABLE_OPTS == true ]; then
HASKELL_OPTS="-O3"
fi
CC_OPTS['Haskell']="-Wall $HASKELL_DEBUG $HASKELL_OPTS"
else
echo [WARN] No Haskell compiler found, no Haskell makefiles will be generated
fi
# Java compiler
type -a javac &> /dev/null
if [ $? == 0 ]; then
echo [INFO] Found javac, using javac for Java
CC_EXISTS['Java']=true
CC_EXE['Java']=javac
CC_OPTS['Java']=
if [ $ENABLE_DEBUG == true ]; then
CC_OPTS['Java']="-g"
fi
else
echo [WARN] No Java compiler found, no Java makefiles will be generated
fi
# Rust compiler
type -a rustc &> /dev/null
if [ $? == 0 ]; then
echo [INFO] Found rustc, using rustc for Rust
CC_EXISTS['Rust']=true
CC_EXE['Rust']=rustc
if [ $ENABLE_DEBUG == true ]; then
RUST_DEBUG="-g"
fi
if [ $ENABLE_OPTS == true ]; then
RUST_OPTS="-C opt-level=3"
fi
CC_OPTS['Rust']="$RUST_DEBUG $RUST_OPTS"
else
echo [WARN] No Rust compiler found, no Rust makefiles will be generated
fi
}
function gen_std_program_makefile() {
declare makefile=$1
echo "\$(PROB): \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -o \$(PROB) \$(DIR)/\$(PROB).\$(EXT) \$(LINK_OPTS)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm \$(PROB)" >> $makefile
}
function gen_ghc_program_makefile() {
declare makefile=$1
echo "\$(PROB): \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -o \$(PROB) \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm \$(PROB) \$(DIR)/\$(PROB).o \$(DIR)/\$(PROB).hi" >> $makefile
}
function gen_gnat_program_makefile() {
declare makefile=$1
echo "\$(PROB): \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -o \$(PROB) \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm \$(PROB) \$(PROB).o \$(PROB).ali" >> $makefile
}
function gen_ldc_program_makefile() {
declare makefile=$1
echo "\$(PROB): \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -of=\$(PROB) \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm \$(PROB) \$(PROB).o" >> $makefile
}
function gen_mcs_program_makefile() {
declare makefile=$1
echo "\$(PROB): \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -out:\$(PROB) \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm \$(PROB)" >> $makefile
}
function gen_javac_program_makefile() {
declare makefile=$1
echo "\$(PROB).class: \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
printf "\t%s\n\n" "\$(CC) \$(CC_OPTS) -d . \$(DIR)/\$(PROB).\$(EXT)" >> $makefile
echo "clean:" >> $makefile
printf "\t%s\n" "rm *.class" >> $makefile
}
function gen_Ada_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for Ada:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=adb >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_gnat_program_makefile $makefile
}
function gen_C_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
declare link_opts=$6
echo [GEN] Writing makefile for C:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=c >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo LINK_OPTS=$link_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_std_program_makefile $makefile
}
function gen_Cpp_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
declare link_opts=$6
echo [GEN] Writing makefile for Cpp:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=cpp >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo LINK_OPTS=$link_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_std_program_makefile $makefile
}
function gen_CSharp_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for CSharp:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=cs >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_mcs_program_makefile $makefile
}
function gen_D_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for D:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=d >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
if [[ $cc_exe == ldc2 ]]; then
gen_ldc_program_makefile $makefile
else
gen_std_program_makefile $makefile
fi
}
function gen_Fortran_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for Fortran:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=f90 >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_std_program_makefile $makefile
}
function gen_Haskell_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for Haskell:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=hs >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_ghc_program_makefile $makefile
}
function gen_Java_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for Java:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=java >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_javac_program_makefile $makefile
}
function gen_Rust_program_makefile() {
declare program=$1
declare makefile=$2
declare src_dir=$3
declare cc_exe=$4
declare cc_opts=$5
echo [GEN] Writing makefile for Rust:$program to $makefile
echo PROB=${program,,} > $makefile
echo EXT=rs >> $makefile
echo CC=$cc_exe >> $makefile
echo CC_OPTS=$cc_opts >> $makefile
echo DIR=$src_dir >> $makefile
echo "" >> $makefile
gen_std_program_makefile $makefile
}
function gen_program_makefile() {
declare program=$1
echo [INFO] Writing makes files for $program
cd $program
for lang_name in *; do
if [ ${CC_EXISTS[${lang_name}]} ]; then
mkdir -p ../build/$program/$lang_name
COMMAND="gen_${lang_name}_program_makefile $program ../build/$program/$lang_name/Makefile ../../../$program/$lang_name ${CC_EXE[${lang_name}]} '${CC_OPTS[${lang_name}]}' '${LINK_OPTS[${lang_name}]}'"
eval $COMMAND
else
echo [INFO] $lang_name has no compiler, skipping makefile generation
fi
done
cd ..
}
detect_compilers
for program in "${PROGRAMS[@]}"; do
gen_program_makefile $program
done