241 lines
6.1 KiB
Bash
Executable file
241 lines
6.1 KiB
Bash
Executable file
set -e
|
|
|
|
SCRIPT_NAME="vk"
|
|
PROJECT_ROOT=$(pwd)
|
|
BUILD_DIR="$PROJECT_ROOT/build"
|
|
|
|
function help() {
|
|
echo "Vulkan Cookbook Project Management Tool"
|
|
echo ""
|
|
echo "Usage: $SCRIPT_NAME [command]"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " new CHAPTER SAMPLE NAME Create a new sample (e.g. vk new 2 1 'GLFW Window')"
|
|
echo " build [sample] Build project using Ninja (all or specific sample)"
|
|
echo " run CHAPTER SAMPLE Run a specific sample"
|
|
echo " cmake Regenerate CMake files"
|
|
echo " list List all samples"
|
|
echo " compile-commands Copy compile_commands.json to project root"
|
|
echo " deps Run deps bootstrapping"
|
|
echo " help Show this help message"
|
|
}
|
|
|
|
function new_sample() {
|
|
if [ $# -lt 3 ]; then
|
|
echo "Error: Missing arguments for 'new'"
|
|
echo "Usage: $SCRIPT_NAME new CHAPTER SAMPLE NAME"
|
|
return 1
|
|
fi
|
|
|
|
CHAPTER=$1
|
|
SAMPLE=$2
|
|
NAME=$3
|
|
|
|
PADDED_CHAPTER=$(printf "%02d" "$CHAPTER")
|
|
PADDED_SAMPLE=$(printf "%02d" "$SAMPLE")
|
|
|
|
SAMPLE_DIR="$PROJECT_ROOT/Chapter$PADDED_CHAPTER/$PADDED_SAMPLE"_"$NAME"
|
|
|
|
if [ -d "$SAMPLE_DIR" ]; then
|
|
echo "Error: Sample directory already exists: $SAMPLE_DIR"
|
|
return 1
|
|
fi
|
|
|
|
echo "Creating new sample Ch${PADDED_CHAPTER}_${PADDED_SAMPLE}_${NAME}..."
|
|
mkdir -p "$SAMPLE_DIR/src"
|
|
|
|
# Create CMakeLists.txt
|
|
cat >"$SAMPLE_DIR/CMakeLists.txt" <<EOL
|
|
cmake_minimum_required(VERSION 3.19)
|
|
project(Chapter${PADDED_CHAPTER})
|
|
include(../../CMake/CommonMacros.txt)
|
|
SETUP_APP(Ch${PADDED_CHAPTER}_${PADDED_SAMPLE}_${NAME} "Chapter ${PADDED_CHAPTER}")
|
|
|
|
target_include_directories(Ch${PADDED_CHAPTER}_${PADDED_SAMPLE}_${NAME} PUBLIC \${CMAKE_SOURCE_DIR})
|
|
target_link_libraries(Ch${PADDED_CHAPTER}_${PADDED_SAMPLE}_${NAME} SharedUtils)
|
|
EOL
|
|
|
|
# Create minimal main.cpp with GLFW boilerplate
|
|
cat >"$SAMPLE_DIR/src/main.cpp" <<EOL
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
#include <shared/HelpersGLFW.h>
|
|
|
|
int main(int argc, char* argv[]) {
|
|
std::cout << "Chapter ${CHAPTER}, Sample ${SAMPLE}: ${NAME}" << std::endl;
|
|
|
|
uint32_t width = 1280;
|
|
uint32_t height = 720;
|
|
|
|
GLFWwindow *window = initWindow("Ch${PADDED_CHAPTER}_${PADDED_SAMPLE}: ${NAME}", width, height);
|
|
|
|
while (!glfwWindowShouldClose(window)) {
|
|
glfwPollEvents();
|
|
}
|
|
|
|
glfwDestroyWindow(window);
|
|
glfwTerminate();
|
|
return 0;
|
|
}
|
|
EOL
|
|
|
|
echo "Successfully created new sample: $SAMPLE_DIR"
|
|
echo "Run '$SCRIPT_NAME cmake' to update CMake configuration"
|
|
}
|
|
|
|
function build_project() {
|
|
if [ ! -d "$BUILD_DIR" ]; then
|
|
echo "Creating build directory..."
|
|
mkdir -p "$BUILD_DIR"
|
|
fi
|
|
|
|
cd "$BUILD_DIR"
|
|
|
|
if [ $# -eq 0 ]; then
|
|
echo "Building all targets..."
|
|
ninja
|
|
else
|
|
TARGET="Ch$1"
|
|
echo "Building target: $TARGET"
|
|
ninja "$TARGET"
|
|
fi
|
|
|
|
cd "$PROJECT_ROOT"
|
|
}
|
|
|
|
function run_sample() {
|
|
if [ $# -lt 2 ]; then
|
|
echo "Error: Missing arguments for 'run'"
|
|
echo "Usage: $SCRIPT_NAME run CHAPTER SAMPLE"
|
|
return 1
|
|
fi
|
|
|
|
CHAPTER=$(printf "%02d" "$1")
|
|
SAMPLE=$(printf "%02d" "$2")
|
|
|
|
# Find the exact sample name
|
|
SAMPLE_PATTERN="Ch${CHAPTER}_${SAMPLE}_*"
|
|
SAMPLE_BINARY=$(find "$PROJECT_ROOT/bin" -name "$SAMPLE_PATTERN" -type f -executable 2>/dev/null | head -1)
|
|
|
|
if [ -z "$SAMPLE_BINARY" ]; then
|
|
echo "Error: Sample not found or not built: Chapter $CHAPTER, Sample $SAMPLE"
|
|
echo "Try building it first: $SCRIPT_NAME build"
|
|
return 1
|
|
fi
|
|
|
|
echo "Running $SAMPLE_BINARY..."
|
|
"$SAMPLE_BINARY"
|
|
}
|
|
|
|
function regenerate_cmake() {
|
|
if [ ! -d "$BUILD_DIR" ]; then
|
|
mkdir -p "$BUILD_DIR"
|
|
fi
|
|
|
|
# Update root CMakeLists.txt to include all chapters/samples
|
|
echo "Updating root CMakeLists.txt with new samples..."
|
|
|
|
# Find all chapter/sample directories, excluding the build directory
|
|
SAMPLES=$(find "$PROJECT_ROOT" -type d -path "*/Chapter*/[0-9][0-9]_*" -not -path "*/**/build/*" -not -path "*/**/src" | sort)
|
|
|
|
# Create a temporary file with updated subdirectories
|
|
TEMP_CMAKE=$(mktemp)
|
|
|
|
# Extract the content up to line 100 (before add_subdirectory calls)
|
|
head -n "$(grep -n "BINARIES" CMakeLists.txt | head -n 1 | cut -d: -f1)" "$PROJECT_ROOT/CMakeLists.txt" >"$TEMP_CMAKE"
|
|
|
|
# Add subdirectories for all samples
|
|
for SAMPLE_DIR in $SAMPLES; do
|
|
# Skip src directories
|
|
if [[ "$SAMPLE_DIR" == */src ]]; then
|
|
continue
|
|
fi
|
|
|
|
# Get relative path from project root
|
|
REL_PATH=$(realpath --relative-to="$PROJECT_ROOT" "$SAMPLE_DIR")
|
|
echo "add_subdirectory($REL_PATH)" >>"$TEMP_CMAKE"
|
|
done
|
|
|
|
# Update the CMakeLists.txt file
|
|
mv "$TEMP_CMAKE" "$PROJECT_ROOT/CMakeLists.txt"
|
|
|
|
cd "$BUILD_DIR"
|
|
echo "Regenerating CMake files..."
|
|
cmake -G Ninja ..
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Copy compile_commands.json to project root
|
|
if [ -f "$BUILD_DIR/compile_commands.json" ]; then
|
|
cp "$BUILD_DIR/compile_commands.json" "$PROJECT_ROOT/"
|
|
echo "Copied compile_commands.json to project root"
|
|
fi
|
|
}
|
|
|
|
function update_deps() {
|
|
echo "Updating Dependencies"
|
|
pushd "$PROJECT_ROOT/deps"
|
|
./bootstrap.py
|
|
popd
|
|
echo "Dependencies updated"
|
|
}
|
|
|
|
function list_samples() {
|
|
echo "Available samples:"
|
|
find "$PROJECT_ROOT" -type d -path "*/Chapter*/[0-9][0-9]_*" -not -path "build/*" -not -path "*/**/src" | sort | while read -r dir; do
|
|
# Skip src directories
|
|
if [[ "$dir" == */src ]]; then
|
|
continue
|
|
fi
|
|
echo " $(basename "$(dirname "$dir")")/$(basename "$dir")"
|
|
done
|
|
}
|
|
|
|
# Update main CMakeLists.txt if sample is added or removed
|
|
function update_root_cmake() {
|
|
# Check if we need to update the root CMakeLists.txt
|
|
if [ "$1" == "new" ] || [ "$1" == "delete" ]; then
|
|
regenerate_cmake
|
|
fi
|
|
}
|
|
|
|
# Main command dispatcher
|
|
if [ $# -eq 0 ]; then
|
|
help
|
|
exit 0
|
|
fi
|
|
|
|
COMMAND=$1
|
|
shift
|
|
|
|
case "$COMMAND" in
|
|
"new")
|
|
new_sample "$@"
|
|
update_root_cmake "new"
|
|
;;
|
|
"build")
|
|
build_project "$@"
|
|
;;
|
|
"run")
|
|
run_sample "$@"
|
|
;;
|
|
"cmake")
|
|
regenerate_cmake
|
|
;;
|
|
"list")
|
|
list_samples
|
|
;;
|
|
"deps")
|
|
update_deps
|
|
;;
|
|
"compile-commands")
|
|
cp "$BUILD_DIR/compile_commands.json" "$PROJECT_ROOT/" 2>/dev/null || echo "No compile_commands.json found in build directory"
|
|
;;
|
|
"help")
|
|
help
|
|
;;
|
|
*)
|
|
echo "Unknown command: $COMMAND"
|
|
help
|
|
exit 1
|
|
;;
|
|
esac
|