diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a3f3e8..41f8622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,22 @@ +# v6 ++ `build_profile` task was split to `profile` and `gprof` ++ added task `sanitize` + # v5 -+ added task clean -+ added task exec_dbg -+ added task build_profile -+ added -flto optimization to build_exec task -+ added -fprofile-use to build_exec task ++ added task `clean` ++ added task `exec_dbg` ++ added task `build_profile` ++ added `-flto` optimization to `build_exec` task ++ added `-fprofile-use` to `build_exec` task + removed default configs loading in `init.sh`, now reads just line with version from `cbuild/default.config` and `default.config` -+ OBJDIR structure changed ++ `OBJDIR` structure changed + added error on unknown task in config -+ makefile now writes logs to make_raw.log -+ added makefile task fix_log ++ makefile now writes logs to `make_raw.log` ++ added makefile task `fix_log` + new comments in scripts and Makefile + wrapped arguments with quots in scripts -+ now u should add CPP_ARGS to LINKER_ARGS manually -+ added error(msg) function to functions.sh -+ replaced printf calls with myprint in scripts -+ added default .gitignore -+ added *.log to .gitignore ++ now you have to add `CPP_ARGS` to `LINKER_ARGS` manually ++ added `error(msg)` function to `functions.sh` ++ replaced `printf` calls with `myprint` in scripts ++ added default `.gitignore` ++ added *.log to `.gitignore` diff --git a/default.Makefile b/default.Makefile index 7f1ba15..0bd17cd 100644 --- a/default.Makefile +++ b/default.Makefile @@ -4,12 +4,8 @@ all: build_exec_dbg -# generates different profile info -build_profile: - @cbuild/call_task.sh build_profile 2>&1 | tee make_raw.log - -# creates executable using profile info generated by build_profile -build_exec: build_profile +# creates executable using profiling info generated by profile +build_exec: profile @cbuild/call_task.sh build_exec 2>&1 | tee -a make_raw.log # creates executable with debug info and no optimizations @@ -48,6 +44,19 @@ exec_dbg: build_exec_dbg valgrind: build_exec_dbg @cbuild/call_task.sh valgrind 2>&1 | tee -a make_raw.log +# generates profiling info +profile: + @cbuild/call_task.sh profile 2>&1 | tee make_raw.log + +# compiles program with -pg and runs it with gprof +# uses gprof2dot python script to generate function call tree +gprof: + @cbuild/call_task.sh gprof 2>&1 | tee make_raw.log + +# compiles executable with sanitizers and executes it to find errors and warnings +sanitize: + @cbuild/call_task.sh sanitize 2>&1 | tee make_raw.log + ###################################### ###### Other tasks ####### ###################################### diff --git a/default.config b/default.config index ddeee6b..0b46216 100644 --- a/default.config +++ b/default.config @@ -1,18 +1,18 @@ #!/bin/bash -CBUILD_VERSION=5 +CBUILD_VERSION=6 CONFIG_VERSION=1 PROJECT="NULL" -CMP_C=gcc -CMP_CPP=g++ -STD_C=c11 -STD_CPP=c++17 -WARN_C="-Wall -Wno-discarded-qualifiers" -WARN_CPP="-Wall" +CMP_C="gcc" +CMP_CPP="g++" +STD_C="c11" +STD_CPP="c++11" +WARN_C="-Wall -Wno-discarded-qualifiers -Wextra -Wno-unused-parameter" +WARN_CPP="-Wall -Wextra -Wno-unused-parameter" SRC_C="$( find src -name '*.c')" SRC_CPP="$( find src -name '*.cpp')" -#TESTS_C="$( find tests -name '*.c')" -#TESTS_CPP="$(find tests -name '*.cpp')" +TESTS_C="$( find tests -name '*.c')" +TESTS_CPP="$(find tests -name '*.cpp')" # OBJDIR structure: # ├── objects - dir where compiled *.o files are stored. cleans every call of build task @@ -40,26 +40,13 @@ esac # TASKS case "$TASK" in - # generates different profile info - build_profile) - OUTDIR="$OUTDIR/profile" - # -flto applies more optimizations across object files - # -flto=auto is needed to multithreaded copilation - # -fuse-linker-plugin is required to use static libs with lto, it strips away all - # -pg adds code to executable, that generates file containing function call info (gmon.out) - # -fprofile-generate - C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" - CPP_ARGS="$C_ARGS" - LINKER_ARGS="$CPP_ARGS" - PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh - TASK_SCRIPT=cbuild/default_tasks/profile.sh - POST_TASK_SCRIPT= - ;; - # creates executable using profile info generated by build_profile + # creates executable using profiling info if it exists build_exec) # -flto applies more optimizations across object files # -flto=auto is needed to multithreaded copilation - # -fuse-linker-plugin is required to use static libs with lto, it strips away all + # -fuse-linker-plugin is required to use static libs with lto + # -fprofile-use enables compiler to use profiling info files to optimize executable + # -fprofile-prefix-path sets path where profiling info about objects are be saved C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS" @@ -69,7 +56,7 @@ case "$TASK" in ;; # creates executable with debug info and no optimizations build_exec_dbg) - C_ARGS="-O0 -g" + C_ARGS="-O0 -g3" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS" PRE_TASK_SCRIPT= @@ -87,7 +74,7 @@ case "$TASK" in ;; # creates shared library with debug symbols and no optimizations build_shared_lib_dbg) - C_ARGS="-O0 -g -fpic -shared" + C_ARGS="-O0 -g3 -fpic -shared" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" PRE_TASK_SCRIPT= @@ -104,7 +91,7 @@ case "$TASK" in ;; # creates static library with debug symbols and no optimizations build_static_lib_dbg) - C_ARGS="-O0 -g" + C_ARGS="-O0 -g3" CPP_ARGS="$C_ARGS" PRE_TASK_SCRIPT= TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh @@ -119,6 +106,45 @@ case "$TASK" in VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all" TASK_SCRIPT=cbuild/default_tasks/valgrind.sh ;; + # generates profiling info + profile) + OUTDIR="$OUTDIR/profile" + # -flto applies more optimizations across object files + # -flto=auto is needed to multithreaded copilation + # -fuse-linker-plugin is required to use static libs with lto + # -pg adds code to executable, that generates file containing function call info (gmon.out) + # -fprofile-generate generates executable with profiling code + # -fprofile-prefix-path sets path where profiling info about objects will be saved + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/profile.sh + POST_TASK_SCRIPT= + ;; + # compiles program with -pg and runs it with gprof + # uses gprof2dot python script to generate function call tree (pip install gprof2dot) + # requires graphviz (https://www.graphviz.org/download/source/) + gprof) + OUTDIR="$OUTDIR/gprof" + # -pg adds code to executable, that generates file containing function call info (gmon.out) + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/gprof.sh + POST_TASK_SCRIPT= + ;; + # compiles executable with sanitizers and executes it to find errors and warnings + sanitize) + OUTDIR="bin/sanitize" + C_ARGS="-O0 -g3 -fsanitize=undefined,address" + CPP_ARGS="$C_ARGS" + LINKER_ARGS="$CPP_ARGS" + PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh + TASK_SCRIPT=cbuild/default_tasks/exec.sh + POST_TASK_SCRIPT= + ;; # deletes generated files clean) TASK_SCRIPT=cbuild/default_tasks/clean.sh diff --git a/default_tasks/build_exec.sh b/default_tasks/build_exec.sh index 094b0ba..8908ab3 100755 --- a/default_tasks/build_exec.sh +++ b/default_tasks/build_exec.sh @@ -8,6 +8,7 @@ prof_files=$(find "$OBJDIR/profile/" -name '*.gcda') if [ -z "$prof_files" ]; then myprint "${YELLOW}no profiling info found" else + myprint "${GREEN}profiling info found" for prof_file in $prof_files; do myprint "${GRAY}$(basename $prof_file)" cp $prof_file "$OBJDIR/objects/" diff --git a/default_tasks/gprof.sh b/default_tasks/gprof.sh new file mode 100644 index 0000000..edcc59e --- /dev/null +++ b/default_tasks/gprof.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +cd "$OUTDIR" + +# deleting all files except excutable +echo "$(find . ! -name $EXEC_FILE -type f -delete)" + +# executing file compiled with -pg +myprint "${BLUE}executing $OUTDIR/$EXEC_FILE" +./$EXEC_FILE > exec.log +myprint "${GREEN}execution log saved to ${CYAN}$OUTDIR/exec.log" + +# generating function call graph +myprint "${BLUE}generating function call graph..." +gprof ./$EXEC_FILE > gprof.log +gprof2dot gprof.log > gprof2dot.graph +dot gprof2dot.graph -Tpng -Gdpi=300 -o gprof2dot.png +myprint "${GREEN}function call graph saved to ${CYAN}$OUTDIR/gprof2dot.png" + +cd ../.. diff --git a/default_tasks/profile.sh b/default_tasks/profile.sh index 06473a4..39be355 100644 --- a/default_tasks/profile.sh +++ b/default_tasks/profile.sh @@ -5,7 +5,7 @@ cd "$OUTDIR" # deleting all files except excutable echo "$(find . ! -name $EXEC_FILE -type f -delete)" -# executing file compiled with -pg and -fprofile-gen +# executing file compiled with -fprofile-gen myprint "${BLUE}executing $OUTDIR/$EXEC_FILE" ./$EXEC_FILE > exec.log myprint "${GREEN}execution log saved to ${CYAN}$OUTDIR/exec.log" @@ -15,11 +15,4 @@ clean_dir ../../$OBJDIR/profile mv ../../$OBJDIR/objects/*.gcda ../../$OBJDIR/profile/ myprint "${GREEN}$(ls ../../$OBJDIR/profile | wc -l) *.gcda profiling files have written to $OBJDIR/profile" -# generating function call graph -myprint "${BLUE}generating function call graph..." -gprof ./$EXEC_FILE > gprof.log -gprof2dot gprof.log > gprof2dot.graph -dot gprof2dot.graph -Tpng -Gdpi=300 -o gprof2dot.png -myprint "${GREEN}function call graph saved to ${CYAN}$OUTDIR/gprof2dot.png" - cd ../..