Skip to content

Instantly share code, notes, and snippets.

@iliakonnov
Last active November 8, 2021 22:10
Show Gist options
  • Save iliakonnov/b14e1818c6d24c8b92d8e55b6a3da4ad to your computer and use it in GitHub Desktop.
Save iliakonnov/b14e1818c6d24c8b92d8e55b6a3da4ad to your computer and use it in GitHub Desktop.

Структура директорий:

./30929/
  ├── a_check.cpp
  ├── b_balance.cpp
  ├── c_count.cpp
  └── d_derevo.cpp
./utils/
  └── rbtree.cxx
./system-headers/
  └── ...
./build.sh
  • system-headers
  • .cpp файлы содержат код решений (с мейном)
  • .cxx файлы содержат вспомогательный код (без мейна)

build.sh генерирует: compile_commands.json и полноценный Makefile

Makefile компилирует:

out/30929/
  ├── a_check.bin  // Версия для дебага, с санитайзерами
  ├── a_check.cpp  // Код для контеста
  ├── a_check.opt  // Оптимизированная версия
  └ ...            // на основе файла для контеста

Для этого запускается:

  1. Компилятор
  2. Препроцессор
  3. clang-tidy
  4. clang-format
  5. cpplint — в контесте другая версия, которую я сумел нагуглить
  6. Компилятор
#!/usr/bin/env bash
SANITIZE="-fsanitize=address,undefined"
WARNINGS="-pedantic -Wall -Wextra -Wunused"
CXX="$(which g++) -std=c++17 $WARNINGS -g -O0 -U_FORTIFY_SOURCE $SANITIZE"
FMT="$(which clang-format) -i"
FIX="$(which clang-tidy) --fix --fix-errors --quiet"
CHECK="$(which clang-tidy) --quiet"
LINT="cpplint --filter=+,-legal,-whitespace/indent --linelength=100"
PREPROCESS="$(which g++) -E -P -C -nostdinc -nostdinc++ -Dinclude=#include -Ddefine=#define -Isystem-headers"
OPT="$(which g++) -std=c++17 -O2"
coproc CO_JQ { jq -s; }
if [ -f Makefile ]; then rm -v Makefile; fi
exec 9<>Makefile
echo "default: all" >&9
echo "" >&9
echo "clean:" >&9
echo -e "\trm -rf out/" >&9
echo -e "\trm compile_commands.json Makefile" >&9
echo "" >&9
echo ".PHONY: clean" >&9
echo "" >&9
COLOR='\e[41m'
RESET='\e[0m'
function add() {
out="$1"
task="$2"
cxx_args="$3"
ext="bin"
if [[ "$cxx_args" == *"-c"* ]]; then
ext="o"
fi
echo "{" >&"${CO_JQ[1]}"
echo " \"directory\": \"$PWD\"," >&"${CO_JQ[1]}"
echo " \"command\": \"$CXX $cxx_args -Ddebug $task -o $out\"," >&"${CO_JQ[1]}"
echo " \"file\": \"$task\"" >&"${CO_JQ[1]}"
echo "}" >&"${CO_JQ[1]}"
DEPENDENCIES=$(/usr/bin/clang++ -MT '__target__' -MM $task)
DEPENDENCIES="$DEPENDENCIES"
echo "build_$ext += $out.$ext" >&9
echo "${DEPENDENCIES/__target__/$out.$ext}" >&9
echo -e "\t@mkdir -p $(dirname $out)" >&9
echo -e "\t@echo -e '${COLOR}COMPILE $task > $out.$ext${RESET}'" >&9
echo -e "\t$CXX $cxx_args $task -Ddebug -o $out.$ext" >&9
echo "preprocess += $out.cpp" >&9
echo "${DEPENDENCIES/__target__/$out.cpp}" >&9
echo -e "\t@mkdir -p $(dirname $out)" >&9
echo -e "\t@echo -e '${COLOR}PREPROCESS $task > $out.cpp${RESET}'" >&9
echo -e "\t$PREPROCESS $cxx_args $task -Uforce_template > $out.cpp" >&9
echo -e "\t@echo -e '${COLOR}FIX&FMT $out.cpp${RESET}'" >&9
echo -e "\t$FIX $out.cpp 2>&1 >/dev/null || true" >&9
echo -e "\t$FMT $out.cpp" >&9
echo -e "\t@echo -e '${COLOR}LINT $out.cpp${RESET}'" >&9
echo -e "\t$CHECK $out.cpp" >&9
echo -e "\t$LINT $out.cpp" >&9
echo "optimize += $out.opt" >&9
echo "$out.opt: $out.cpp" >&9
echo -e "\t@echo '${COLOR}OPTIMIZE $out.cpp > $out.opt${RESET}'" >&9
echo -e "\t$OPT $cxx_args $out.cpp -o $out.opt" >&9
echo "" >&9
}
for task in ./*/*.cpp; do if [ -f "$task" ]; then
out="$(realpath --relative-to=. -m "out/${task%.cpp}")"
task="$(realpath --relative-to=. -m "${task}")"
echo "Adding $task -> $out"
add "$out" "$task"
fi; done
echo 'build_o: $(build_o)' >&9
echo 'build_bin: $(build_bin)' >&9
echo 'preprocess: $(preprocess)' >&9
echo 'optimize: $(optimize)' >&9
echo 'all: build_o build_bin preprocess optimize' >&9
echo "" >&9
exec {CO_JQ[1]}>&-
cat <&"${CO_JQ[0]}" >compile_commands.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment