286 lines
7.5 KiB
Bash
Executable File
286 lines
7.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# CMake Preset Configuration Tester
|
|
# Tests that all CMake presets can configure successfully
|
|
#
|
|
# Usage:
|
|
# ./scripts/test-cmake-presets.sh [OPTIONS]
|
|
#
|
|
# Options:
|
|
# --parallel N Test N presets in parallel (default: 4)
|
|
# --preset PRESET Test only specific preset
|
|
# --platform PLATFORM Test only presets for platform (mac, win, lin)
|
|
# --quick Skip cleaning between tests
|
|
# --verbose Show full CMake output
|
|
#
|
|
# Exit codes:
|
|
# 0 - All presets configured successfully
|
|
# 1 - One or more presets failed
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Default options
|
|
PARALLEL_JOBS=4
|
|
SPECIFIC_PRESET=""
|
|
PLATFORM_FILTER=""
|
|
QUICK_MODE=false
|
|
VERBOSE=false
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--parallel)
|
|
PARALLEL_JOBS="$2"
|
|
shift 2
|
|
;;
|
|
--preset)
|
|
SPECIFIC_PRESET="$2"
|
|
shift 2
|
|
;;
|
|
--platform)
|
|
PLATFORM_FILTER="$2"
|
|
shift 2
|
|
;;
|
|
--quick)
|
|
QUICK_MODE=true
|
|
shift
|
|
;;
|
|
--verbose)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Detect current platform
|
|
detect_platform() {
|
|
case "$(uname -s)" in
|
|
Darwin*)
|
|
echo "mac"
|
|
;;
|
|
Linux*)
|
|
echo "lin"
|
|
;;
|
|
MINGW*|MSYS*|CYGWIN*)
|
|
echo "win"
|
|
;;
|
|
*)
|
|
echo "unknown"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
CURRENT_PLATFORM=$(detect_platform)
|
|
|
|
# Get list of presets from CMakePresets.json
|
|
get_presets() {
|
|
if [ ! -f "CMakePresets.json" ]; then
|
|
echo -e "${RED}✗ CMakePresets.json not found${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Use jq if available, otherwise use grep
|
|
if command -v jq &> /dev/null; then
|
|
jq -r '.configurePresets[] | select(.hidden != true) | .name' CMakePresets.json
|
|
else
|
|
# Fallback to grep-based extraction
|
|
grep -A 1 '"name":' CMakePresets.json | grep -v '"hidden": true' | grep '"name"' | cut -d'"' -f4
|
|
fi
|
|
}
|
|
|
|
# Filter presets based on criteria
|
|
filter_presets() {
|
|
local presets="$1"
|
|
local filtered=""
|
|
|
|
if [ -n "$SPECIFIC_PRESET" ]; then
|
|
echo "$SPECIFIC_PRESET"
|
|
return
|
|
fi
|
|
|
|
for preset in $presets; do
|
|
# Skip hidden/base presets
|
|
if [[ "$preset" == *"base"* ]]; then
|
|
continue
|
|
fi
|
|
|
|
# Filter by platform if specified
|
|
if [ -n "$PLATFORM_FILTER" ]; then
|
|
if [[ ! "$preset" == *"$PLATFORM_FILTER"* ]]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Skip platform-specific presets if not on that platform
|
|
if [ "$CURRENT_PLATFORM" != "unknown" ]; then
|
|
if [[ "$preset" == mac-* ]] && [ "$CURRENT_PLATFORM" != "mac" ]; then
|
|
continue
|
|
fi
|
|
if [[ "$preset" == win-* ]] && [ "$CURRENT_PLATFORM" != "win" ]; then
|
|
continue
|
|
fi
|
|
if [[ "$preset" == lin-* ]] && [ "$CURRENT_PLATFORM" != "lin" ]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
filtered="$filtered $preset"
|
|
done
|
|
|
|
echo "$filtered"
|
|
}
|
|
|
|
# Test a single preset
|
|
test_preset() {
|
|
local preset="$1"
|
|
local build_dir="build_preset_test_${preset}"
|
|
local log_file="preset_test_${preset}.log"
|
|
|
|
echo -e "${CYAN}Testing preset: $preset${NC}"
|
|
|
|
# Clean build directory unless in quick mode
|
|
if [ "$QUICK_MODE" = false ] && [ -d "$build_dir" ]; then
|
|
rm -rf "$build_dir"
|
|
fi
|
|
|
|
# Configure preset
|
|
local start_time=$(date +%s)
|
|
|
|
if [ "$VERBOSE" = true ]; then
|
|
if cmake --preset "$preset" -B "$build_dir" 2>&1 | tee "$log_file"; then
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
echo -e "${GREEN}✓${NC} $preset configured successfully (${duration}s)"
|
|
rm -f "$log_file"
|
|
return 0
|
|
else
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
echo -e "${RED}✗${NC} $preset failed (${duration}s)"
|
|
echo " Log saved to: $log_file"
|
|
return 1
|
|
fi
|
|
else
|
|
if cmake --preset "$preset" -B "$build_dir" > "$log_file" 2>&1; then
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
echo -e "${GREEN}✓${NC} $preset configured successfully (${duration}s)"
|
|
rm -f "$log_file"
|
|
return 0
|
|
else
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
echo -e "${RED}✗${NC} $preset failed (${duration}s)"
|
|
echo " Log saved to: $log_file"
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
echo -e "${BLUE}=== CMake Preset Configuration Tester ===${NC}"
|
|
echo "Platform: $CURRENT_PLATFORM"
|
|
echo "Parallel jobs: $PARALLEL_JOBS"
|
|
echo ""
|
|
|
|
# Get and filter presets
|
|
all_presets=$(get_presets)
|
|
test_presets=$(filter_presets "$all_presets")
|
|
|
|
if [ -z "$test_presets" ]; then
|
|
echo -e "${YELLOW}⚠ No presets to test${NC}"
|
|
exit 0
|
|
fi
|
|
|
|
echo -e "${BLUE}Presets to test:${NC}"
|
|
for preset in $test_presets; do
|
|
echo " - $preset"
|
|
done
|
|
echo ""
|
|
|
|
# Test presets
|
|
local total=0
|
|
local passed=0
|
|
local failed=0
|
|
local failed_presets=""
|
|
|
|
# Export function for parallel execution
|
|
export -f test_preset
|
|
export VERBOSE
|
|
export QUICK_MODE
|
|
export RED GREEN YELLOW BLUE CYAN NC
|
|
|
|
if [ "$PARALLEL_JOBS" -gt 1 ]; then
|
|
echo -e "${BLUE}Running tests in parallel (jobs: $PARALLEL_JOBS)...${NC}\n"
|
|
|
|
# Use GNU parallel if available, otherwise use xargs
|
|
if command -v parallel &> /dev/null; then
|
|
echo "$test_presets" | tr ' ' '\n' | parallel -j "$PARALLEL_JOBS" test_preset
|
|
else
|
|
echo "$test_presets" | tr ' ' '\n' | xargs -P "$PARALLEL_JOBS" -I {} bash -c "$(declare -f test_preset); test_preset {}"
|
|
fi
|
|
|
|
# Collect results
|
|
for preset in $test_presets; do
|
|
total=$((total + 1))
|
|
if [ -f "preset_test_${preset}.log" ]; then
|
|
failed=$((failed + 1))
|
|
failed_presets="$failed_presets\n - $preset"
|
|
else
|
|
passed=$((passed + 1))
|
|
fi
|
|
done
|
|
else
|
|
echo -e "${BLUE}Running tests sequentially...${NC}\n"
|
|
|
|
for preset in $test_presets; do
|
|
total=$((total + 1))
|
|
if test_preset "$preset"; then
|
|
passed=$((passed + 1))
|
|
else
|
|
failed=$((failed + 1))
|
|
failed_presets="$failed_presets\n - $preset"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Summary
|
|
echo ""
|
|
echo -e "${BLUE}=== Test Summary ===${NC}"
|
|
echo "Total presets tested: $total"
|
|
echo -e "${GREEN}Passed: $passed${NC}"
|
|
|
|
if [ $failed -gt 0 ]; then
|
|
echo -e "${RED}Failed: $failed${NC}"
|
|
echo -e "${RED}Failed presets:${NC}$failed_presets"
|
|
echo ""
|
|
echo "Check log files for details: preset_test_*.log"
|
|
exit 1
|
|
else
|
|
echo -e "${GREEN}✓ All presets configured successfully!${NC}"
|
|
|
|
# Cleanup test build directories
|
|
if [ "$QUICK_MODE" = false ]; then
|
|
echo "Cleaning up test build directories..."
|
|
rm -rf build_preset_test_*
|
|
fi
|
|
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Run main
|
|
main
|