Created
November 30, 2025 03:40
-
-
Save Urpagin/551fa3efa77d56d1ca701efd391ea304 to your computer and use it in GitHub Desktop.
A Bash script to quickly build & execute a C project.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Author: Urpagin | |
| # Date: 2025-11-30 | |
| # Description: eXecute C (xc) compiles and executes a C project | |
| # without cluttering your machine. | |
| set -euo pipefail | |
| _usage() { | |
| cat << 'SKIBIDI' | |
| DESCRIPTION | |
| eXecute C (xc) compiles and executes C code | |
| without leaving any clutter (out files) on | |
| your machine. | |
| The build is made using debug arguments. | |
| USAGE | |
| xc [C_SOURCE_FILE_OR_OPTION...] -- [ARG...] | |
| EXAMPLE | |
| # Standard usage | |
| xc main.c | |
| # Multiple source files | |
| xc main.c lib1.c lib2.c | |
| # Multiple source files & three arguments | |
| xc main.c lib.c -- John Arkansas 22 | |
| # You can override the compiler flags | |
| XC_CFLAGS='-Wall -O3' xc main.c | |
| # This is also valid | |
| XC_CFLAGS='' xc -Wall -O3 main.c | |
| BEHAVIOUR | |
| The default compiler is clang, if not found, gcc | |
| is used. | |
| SKIBIDI | |
| } | |
| if [[ "${1:-}" == '-h' || "${1:-}" == '--help' ]]; then | |
| _usage | |
| exit 0 | |
| fi | |
| # We prefer clang because it generates better error messages. | |
| _get_compiler() { | |
| if command -v clang >/dev/null 2>&1; then | |
| echo 'clang' | |
| return 0 | |
| fi | |
| if command -v gcc >/dev/null 2>&1; then | |
| echo 'gcc' | |
| return 0 | |
| fi | |
| # No compatible compiler found | |
| echo 'No compatible C compiler found (need clang or gcc)' >&2 | |
| return 1 | |
| } | |
| _COMPILER="$(_get_compiler)" || exit 1 | |
| readonly _COMPILER | |
| declare -ra _DEFAULT_C_FLAGS=( | |
| '-std=c11' | |
| '-Wall' | |
| '-Wextra' | |
| '-Wpedantic' | |
| '-Og' | |
| '-g' | |
| ) | |
| # Use user-provided XC_CFLAGS in priority if provided. | |
| _C_FLAGS=() | |
| if [[ "${XC_CFLAGS+x}" ]]; then | |
| # splits XC_CFLAGS into an array without globbing | |
| read -r -a _C_FLAGS <<< "${XC_CFLAGS}" | |
| else | |
| _C_FLAGS=("${_DEFAULT_C_FLAGS[@]}") | |
| fi | |
| readonly -a _C_FLAGS | |
| if [[ -z "${1:-}" ]]; then | |
| printf 'Missing C source files\nUse -h to show detailed help\n' | |
| exit 1 | |
| fi | |
| # Temp directory where to store our out file. | |
| _TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}"/xc.XXXXXXXXXXXX)" | |
| readonly _BIN_PATH="${_TMP_DIR}/xc_a.out" | |
| readonly _TMP_DIR | |
| _cleanup() { | |
| # Remove temp directory | |
| [[ "$_TMP_DIR" == "${TMPDIR:-/tmp}"* ]] && rm -rf -- "$_TMP_DIR" | |
| } | |
| trap _cleanup 'EXIT' | |
| # Separate compiler flags from program flags. | |
| # -- is the delimiter. | |
| compiler_args=() | |
| program_args=() | |
| program_flag=false | |
| for arg in "$@"; do | |
| [[ "$arg" == '--' ]] && program_flag=true && continue | |
| if [[ "$program_flag" == false ]]; then | |
| compiler_args+=("$arg") | |
| else | |
| program_args+=("$arg") | |
| fi | |
| done | |
| # Compile. Arguments for the compiler. | |
| "$_COMPILER" "${_C_FLAGS[@]}" -o "$_BIN_PATH" "${compiler_args[@]}" | |
| # Execute | |
| "$_BIN_PATH" "${program_args[@]}" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment