280 lines
8.3 KiB
Bash
280 lines
8.3 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
include "@cbuild/include/myprint.sh"
|
|
|
|
function exec_script_line {
|
|
local script="$1"
|
|
local line_num="$2"
|
|
#true or false
|
|
local quiet=$3
|
|
|
|
myprint_quiet $quiet "${BLUE}reading line $line_num from $script"
|
|
local line_str="$(sed $line_num'!d' $script)"
|
|
if [ -z "$line_str" ]; then
|
|
error "script line is empty"
|
|
fi
|
|
myprint_quiet $quiet "$line_str"
|
|
eval "$line_str"
|
|
}
|
|
|
|
function replace_var_value_in_script(){
|
|
local script="$1"
|
|
local var_name="$2"
|
|
local new_value="$3"
|
|
|
|
myprint "${BLUE}setting $var_name to ${CYAN}'$new_value' in '$script'"
|
|
cp "$script" "$script.tmp"
|
|
sed "s,$var_name=\".*\",$var_name=\"$new_value\",g" \
|
|
"$script.tmp" > "$script"
|
|
rm "$script.tmp"
|
|
}
|
|
|
|
function clean_dir {
|
|
local dir="$1"
|
|
myprint "${BLUE}cleaning ${WHITE}'$dir'"
|
|
rm -rf "$dir"
|
|
mkdir "$dir"
|
|
}
|
|
|
|
function delete_dir {
|
|
local dir="$1"
|
|
myprint "${BLUE}deleting ${WHITE}'$dir'"
|
|
rm -rf "$dir"
|
|
}
|
|
|
|
function try_delete_dir_or_file {
|
|
local path="$1"
|
|
if [ -f "$path" ] || [ -d "$path" ]; then
|
|
rm -rf "$path"
|
|
myprint "${BLUE}deleting ${WHITE}'$path'"
|
|
fi
|
|
}
|
|
|
|
file_copy_default_if_not_present(){
|
|
local file="$1"
|
|
local file_default="$2"
|
|
if [ ! -f "$file" ]; then
|
|
myprint "${YELLOW}creating default ${WHITE}'$file'"
|
|
cp -r "$file_default" "$file"
|
|
fi
|
|
}
|
|
|
|
function exec_command {
|
|
local command="$@"
|
|
if [ ! -z "$command" ]; then
|
|
myprint "${GRAY}$command"
|
|
$command || error "command returned eror"
|
|
fi
|
|
}
|
|
|
|
function load_dependency_config {
|
|
local dep_conf_file="$1"
|
|
myprint "${BLUE}loading dependency config ${WHITE}'${dep_conf_file}'"
|
|
include "$dep_conf_file"
|
|
}
|
|
|
|
# builds a dependency when $dep_out_files dont exist or rebuild task is executed
|
|
function build_dependency {
|
|
# path to *.config file
|
|
local dep_conf_file="$1"
|
|
# true or false
|
|
local force_build="$2"
|
|
load_dependency_config "$dep_conf_file"
|
|
|
|
local proj_root_dir="$(pwd)"
|
|
myprint "${BLUE}entering dependency directory '${DEP_WORKING_DIR}'"
|
|
cd "$DEP_WORKING_DIR"
|
|
|
|
local build_needed="$force_build"
|
|
if [ "$build_needed" != true ]; then
|
|
for file in $DEP_STATIC_OUT_FILES $DEP_DYNAMIC_OUT_FILES $DEP_OTHER_OUT_FILES; do
|
|
if [ ! -f "$file" ]; then
|
|
myprint "${GRAY}missing file '$file'"
|
|
local build_needed=true
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ "$build_needed" = true ]; then
|
|
exec_command "$DEP_PRE_BUILD_COMMAND"
|
|
exec_command "$DEP_BUILD_COMMAND"
|
|
exec_command "$DEP_POST_BUILD_COMMAND"
|
|
myprint "${GRAY}dependency build finished"
|
|
else
|
|
myprint "${GRAY}dependency was built already"
|
|
fi
|
|
|
|
if [ ! -z "$DEP_DYNAMIC_OUT_FILES" ]; then
|
|
# copies each file to $OUTDIR and creates symbolic link in $OBJDIR/dynamic_libs
|
|
for file in $DEP_DYNAMIC_OUT_FILES; do
|
|
# doesnt return error if called not like this
|
|
real_file=$(realpath $file)
|
|
file_dir=$(dirname $file)
|
|
if [ "$PRESERVE_OUT_DIRECTORY_STRUCTURE" = true ] && [ "$file_dir" != '.' ]; then
|
|
mkdir -p "$proj_root_dir/$OUTDIR/$file_dir"
|
|
mkdir -p "$proj_root_dir/$OBJDIR/dynamic_libs/$file_dir"
|
|
cp -v -u --preserve=timestamps "$file" "$proj_root_dir/$OUTDIR/$file"
|
|
ln -sfv "$real_file" "$proj_root_dir/$OBJDIR/dynamic_libs/$file"
|
|
else
|
|
cp -v -u --preserve=timestamps "$file" "$proj_root_dir/$OUTDIR/"
|
|
ln -sfv "$real_file" "$proj_root_dir/$OBJDIR/dynamic_libs/"
|
|
fi
|
|
done
|
|
fi
|
|
if [ ! -z "$DEP_OTHER_OUT_FILES" ]; then
|
|
# copies each file to $OUTDIR
|
|
for file in $DEP_OTHER_OUT_FILES; do
|
|
if [ "$PRESERVE_OUT_DIRECTORY_STRUCTURE" = true ]; then
|
|
file_dir=$(dirname $file)
|
|
mkdir -p "$proj_root_dir/$OUTDIR/$file_dir"
|
|
cp -v -u --preserve=timestamps "$file" "$proj_root_dir/$OUTDIR/$file"
|
|
else
|
|
cp -v -u --preserve=timestamps "$file" "$proj_root_dir/$OUTDIR/"
|
|
fi
|
|
done
|
|
fi
|
|
if [ ! -z "$DEP_STATIC_OUT_FILES" ]; then
|
|
# creates symbolic link to each file in $OBJDIR/static_libs
|
|
for file in $DEP_STATIC_OUT_FILES; do
|
|
# doesnt return error if called not like this
|
|
f=$(realpath $file)
|
|
ln -sfv $f "$proj_root_dir/$OBJDIR/static_libs"
|
|
done
|
|
fi
|
|
|
|
cd "$proj_root_dir"
|
|
|
|
# unsed all dependency config variables to not mess with next dependencies
|
|
unset DEP_WORKING_DIR
|
|
unset DEP_PRE_BUILD_COMMAND
|
|
unset DEP_BUILD_COMMAND
|
|
unset DEP_POST_BUILD_COMMAND
|
|
unset DEP_CLEAN_COMMAND
|
|
unset DEP_STATIC_OUT_FILES
|
|
unset PRESERVE_OUT_DIRECTORY_STRUCTURE
|
|
unset DEP_DYNAMIC_OUT_FILES
|
|
unset DEP_OTHER_OUT_FILES
|
|
}
|
|
|
|
function build_dependencies {
|
|
local dependencies="$1"
|
|
# true or false
|
|
local force_build="$2"
|
|
myprint "${BLUE}resolving dependencies"
|
|
clean_dir "$OBJDIR/static_libs"
|
|
clean_dir "$OBJDIR/dynamic_libs"
|
|
for dep in $dependencies; do
|
|
build_dependency "$DEPENDENCY_CONFIGS_DIR/$dep.config" "$force_build"
|
|
done
|
|
}
|
|
|
|
function compile {
|
|
build_dependencies "$ENABLED_DEPENDENCIES"
|
|
print_hline "${BLUE}" "─"
|
|
|
|
local cmp="$1"
|
|
local std="$2"
|
|
local warn="$3"
|
|
local args="$4"
|
|
local include="$5"
|
|
local sources="$6"
|
|
myprint "${BLUE}compiler: ${GRAY}$cmp"
|
|
myprint "${BLUE}standard: ${GRAY}$std"
|
|
myprint "${BLUE}warnings: ${GRAY}$warn"
|
|
myprint "${BLUE}args: ${GRAY}$args"
|
|
myprint "${BLUE}include dirs: ${GRAY}$include"
|
|
myprint "${BLUE}sources: ${GRAY}$sources"
|
|
for srcfile in $sources
|
|
do (
|
|
local object="$OBJDIR/objects/$(basename $srcfile).o"
|
|
if ! $($cmp -std=$std $warn $args $include -c -o $object $srcfile)
|
|
then
|
|
error "some error happened"
|
|
# TODO stop all threads
|
|
fi
|
|
) & done
|
|
wait
|
|
}
|
|
|
|
# (args, sources)
|
|
function compile_c {
|
|
local cmp="$1"
|
|
local std="$2"
|
|
local warn="$3"
|
|
local args="$4"
|
|
local include="$5"
|
|
local sources="$6"
|
|
print_header "${CYAN}" "─" "$PROJECT/$TASK/compile_c"
|
|
compile "$cmp" "$std" "$warn" "$args" "$include" "$sources"
|
|
}
|
|
|
|
# (args, sources)
|
|
function compile_cpp {
|
|
local cmp="$1"
|
|
local std="$2"
|
|
local warn="$3"
|
|
local args="$4"
|
|
local include="$5"
|
|
local sources="$6"
|
|
print_header "${CYAN}" "─" "$PROJECT/$TASK/compile_cpp"
|
|
compile "$cmp" "$std" "$warn" "$args" "$include" "$sources"
|
|
}
|
|
|
|
# (outfile)
|
|
function pack_static_lib {
|
|
print_header "${CYAN}" "─" "$PROJECT/$TASK/pack_static_lib"
|
|
local outfile="$1"
|
|
myprint "${BLUE}outfile: ${GRAY}$outfile"
|
|
|
|
local objects=$(find $OBJDIR/objects -type f,l | tr '\n' ' ')
|
|
myprint "${BLUE}objects: ${GRAY}$objects"
|
|
if [ -z "$objects" ]; then
|
|
error "no compiled objects found"
|
|
fi
|
|
|
|
local command="ar rcs $OUTDIR/$outfile $objects"
|
|
myprint "$command"
|
|
if $command
|
|
then
|
|
myprint "${GREEN}file $CYAN$outfile ${GREEN}created"
|
|
else
|
|
error "some error happened"
|
|
fi
|
|
clean_dir "$OBJDIR/objects"
|
|
}
|
|
|
|
function link {
|
|
print_header "${CYAN}" "─" "$PROJECT/$TASK/link"
|
|
local args="$1"
|
|
local outfile="$2"
|
|
myprint "${BLUE}args: ${GRAY}$args"
|
|
myprint "${BLUE}outfile: ${GRAY}$outfile"
|
|
|
|
local objects=$(find $OBJDIR/objects -type f,l | tr '\n' ' ')
|
|
myprint "${BLUE}objects: ${GRAY}$objects"
|
|
if [ -z "$objects" ]; then
|
|
error "no compiled objects found"
|
|
fi
|
|
|
|
local static_libs=$(find $OBJDIR/static_libs -type f,l | tr '\n' ' ')
|
|
myprint "${BLUE}static libraries: ${GRAY}$static_libs"
|
|
|
|
local dynamic_libs=$(find $OBJDIR/dynamic_libs -type f,l | tr '\n' ' '\
|
|
| sed "s,$OBJDIR/dynamic_libs/,,g")
|
|
myprint "${BLUE}dynamic libraries: ${GRAY}$dynamic_libs"
|
|
local dynamic_libs_args="-L./$OBJDIR/dynamic_libs -Wl,-Bdynamic"
|
|
for lib in $dynamic_libs; do
|
|
dynamic_libs_args="$dynamic_libs_args -Wl,-rpath=$(dirname $lib) -l:$lib"
|
|
done
|
|
|
|
local command="$CMP_CPP $objects $static_libs $args $dynamic_libs_args -o $OUTDIR/$outfile"
|
|
myprint "$command"
|
|
if $command
|
|
then
|
|
myprint "${GREEN}file $CYAN$outfile ${GREEN}created"
|
|
else
|
|
error "some error happened"
|
|
fi
|
|
clean_dir "$OBJDIR/objects"
|
|
}
|