#!/usr/bin/env bash# Compile a C solution into an executable, linked against the runner harness.## Usage:# scripts/c/compile.sh <solution.c> [--clean]## The executable is written next to the solution file, named after the# solution without the .c extension plus a '_c' suffix (e.g. p0001_s0_c).# It is made executable so that evaluate.py can discover and run it directly.# Each solution file is expected to define its own main().## Example:# scripts/c/compile.sh solutions/public/p0001/p0001_s0.c# # produces: solutions/public/p0001/p0001_s0_c (executable)set-euopipefailif[[$#-lt1]];thenecho"Usage: $0 <solution.c> [--clean]">&2exit1fiSOLUTION="$1"CLEAN_FLAG="${2:-}"if[[!-f"${SOLUTION}"]];thenecho"Error: file not found: ${SOLUTION}">&2exit1fiSOLUTION_DIR="$(dirname"${SOLUTION}")"SOLUTION_BASE="$(basename"${SOLUTION}".c)"OUTPUT="${SOLUTION_DIR}/${SOLUTION_BASE}_c"# Check if output exists and is newer than sourceif[[-f"${OUTPUT}"]]&&[["${OUTPUT}"-nt"${SOLUTION}"]];thenif[["${CLEAN_FLAG}"!="--clean"]];thenecho"Skipping compile: ${OUTPUT} is up to date"exit0fifi# Make the runner framework header (packages/solver/solver/runners/runner.h) discoverable,# resolved relative to this script so it works regardless of the caller's cwd.SCRIPT_DIR="$(cd"$(dirname"${BASH_SOURCE[0]}")"&&pwd)"RUNNER_INCLUDE="${SCRIPT_DIR}/../../packages/solver/solver/runners"# One array element per flag: the link line is built word by word, so it survives# quoting on expansion instead of relying on the shell to re-split a string.EXTRA_LIBS=()ifgrep-q'^#include[[:space:]]*<primesieve\.h>'"${SOLUTION}";thenEXTRA_LIBS+=(-lprimesieve)fi# Arbitrary-precision arithmetic: link the bignum library matching each include.# MPFR depends on GMP, so it pulls in -lgmp too (and must precede it on the line).ifgrep-q'^#include[[:space:]]*<mpfr\.h>'"${SOLUTION}";thenEXTRA_LIBS+=(-lmpfr-lgmp)elifgrep-q'^#include[[:space:]]*<gmp\.h>'"${SOLUTION}";thenEXTRA_LIBS+=(-lgmp)fiifgrep-q'^#include[[:space:]]*<openssl/bn\.h>'"${SOLUTION}";thenEXTRA_LIBS+=(-lcrypto)fiset+egcc-O2-Werror-I"${RUNNER_INCLUDE}"-o"${OUTPUT}""${SOLUTION}"-lm"${EXTRA_LIBS[@]}"GCC_EXIT_CODE=$?set-eif[[${GCC_EXIT_CODE}-eq0]];thenchmod+x"${OUTPUT}"echo"Compiled: ${SOLUTION} -> ${OUTPUT}"elseecho"Error: compile failed ${SOLUTION}"rm-f"${OUTPUT}"fiexit${GCC_EXIT_CODE}