#!/bin/bash #===----------------------------------------------------------------------===// # Copyright © 2026 Apple Inc. and the Pkl project authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #===----------------------------------------------------------------------===// ## build_unix.sh # Adapted from https://github.com/oracle/graal/issues/3053#issuecomment-1866735057 # This script intercepts compiler arguments from graalvm native shared images # and additionally generates a static library. # # Use with --native-compiler-path=${pathToThisScript} set -e # Detect OS OS=$(uname -s) case "$OS" in Darwin) SHARED_LIB_EXT="dylib" ;; Linux) SHARED_LIB_EXT="so" ;; *) echo "Unsupported OS: $OS" exit 1 ;; esac # Determine the project name and output path based on the output library argument for arg in "$@"; do if [[ "$arg" == *."$SHARED_LIB_EXT" ]]; then OUTPUT_PATH=$(dirname "$arg") LIB_NAME=$(basename "${arg%."$SHARED_LIB_EXT"}") break fi done # Do a simple forward for any calls that are used to compile individual C files if [[ -z $LIB_NAME ]]; then cc "$@" exit 0 fi # Create a debug log in $output/logs LOG_PATH="${OUTPUT_PATH}/logs" LOG_FILE="${LOG_PATH}/compiler_commands.txt" mkdir -p "$LOG_PATH" WORKINGDIR=${PWD} echo "Working directory: ${WORKINGDIR}" > "${LOG_FILE}" echo "Output path: ${OUTPUT_PATH}" >> "${LOG_FILE}" echo "Library name: ${LIB_NAME}" >> "${LOG_FILE}" echo "OS: ${OS}" >> "${LOG_FILE}" echo "=====================================================" >> "${LOG_FILE}" echo " SHARED LIBRARY " >> "${LOG_FILE}" echo "=====================================================" >> "${LOG_FILE}" CC_ARGS=( "$@" ) echo "cc ${CC_ARGS[*]@Q}" >> "${LOG_FILE}" cc "${CC_ARGS[@]}" echo "=====================================================" >> "${LOG_FILE}" echo " STATIC LIBRARY " >> "${LOG_FILE}" echo "=====================================================" >> "${LOG_FILE}" # To create a single static library we need to call 'ar -r' on all .o files. # In order to also include all static library dependencies, we can first extract the # .o files and then include them as well. echo "======= Source archives" >> "${LOG_FILE}" OBJECTS=${OUTPUT_PATH}/objects rm -rf "${OBJECTS}" mkdir "${OBJECTS}" # Remove existing archive to avoid "fat file" errors ARCHIVE_FILE="${OUTPUT_PATH}/${LIB_NAME}.a" rm -f "${ARCHIVE_FILE}" AR_ARGS="-rcs ${ARCHIVE_FILE} ${OBJECTS}/*.o" for arg in "$@" do if [[ $arg =~ .*\.(a)$ ]]; then # extract the objects (.o) of each archive (.a) into # separate directories to avoid naming collisions echo "$arg" >> "${LOG_FILE}" ARCHIVE_DIR=${OBJECTS}/$(basename "${arg%.a}") mkdir "${ARCHIVE_DIR}" cp "$arg" "${ARCHIVE_DIR}" cd "${ARCHIVE_DIR}" || exit ar -x "$arg" cd "${WORKINGDIR}" || exit AR_ARGS+=" ${ARCHIVE_DIR}/*.o" fi if [[ $arg =~ .*\.(o)$ ]]; then cp "$arg" "${OBJECTS}" fi done echo "======= Objects" >> "${LOG_FILE}" find "${OBJECTS}" -name "*.o" >> "${LOG_FILE}" echo "======= Archive command" >> "${LOG_FILE}" echo "ar $AR_ARGS" >> "${LOG_FILE}" # shellcheck disable=SC2086 ar $AR_ARGS