Skip to content

Instantly share code, notes, and snippets.

@bartman
Last active May 12, 2024 15:07
Show Gist options
  • Save bartman/dc5b324501c87970b9ec4a193e53ae63 to your computer and use it in GitHub Desktop.
Save bartman/dc5b324501c87970b9ec4a193e53ae63 to your computer and use it in GitHub Desktop.
cpp scripting

want to write scripts in C++? sure you do.

put c-run in your path, then you can write scripts in C++ (or in C).

#!/usr/bin/env c-run
#include <iostream>
int main() {
    std::cout << "hello world\n";
}

and here is how it works...

$ hello-world.cpp
hello world

Note that running hello-world.cpp will compile the "script" the first time, and store it in ~/.cache/c-run. On subsequent invocation, c-run will check the timestamps and will not rebuild the "script" if it has not changed.

#!/bin/bash
# Input script from the command line
SCRIPT="$1"
[ -z "$SCRIPT" ] && { echo >&2 "no script given" ; exit 1 ; }
shift
ARGUMENTS=( "$@" )
# Directory to store compiled binaries
CACHE_DIR="$HOME/.cache/c-run"
# Ensure the cache directory exists
mkdir -p "$CACHE_DIR"
# Determine file extension and set the compiler
EXTENSION="${SCRIPT##*.}"
if [ "$EXTENSION" == "cpp" ]; then
COMPILER="clang++ -std=c++20"
elif [ "$EXTENSION" == "c" ]; then
COMPILER="clang -std=c17"
else
echo >&2 "cannot determine compiler for $EXTENSION"
exit 1
fi
# Remove the file extension to create a base name
BASENAME=$(basename "${SCRIPT%.*}")
# Compiled binary path
COMPILED="$CACHE_DIR/$BASENAME"
# Check if recompilation is needed (compile if source is newer than executable)
if [ "$SCRIPT" -nt "$COMPILED" ]; then
# remove the first line
FILTERED="$CACHE_DIR/$BASENAME.$EXTENSION"
sed '1{/^#!/d}' <"$SCRIPT" >"$FILTERED"
# Compile the file
$COMPILER "$FILTERED" -o "$COMPILED"
# Check if compilation was successful
if [ $? -ne 0 ]; then
echo "Compilation failed, not executing."
exit 1
fi
fi
# Execute the compiled binary
"$COMPILED" "${ARGUMENTS[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment