//===----------------------------------------------------------------------===// // Copyright © 2024 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. //===----------------------------------------------------------------------===// /// Builds the native `pkl` CLI extends "GradleJob.pkl" import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.0#/Config.pkl" import "package://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.uri@1.0.0#/URI.pkl" /// The OS to run on os: "macOS"|"linux" /// The architecture to use arch: "amd64"|"aarch64" /// Whether to link to musl. Otherwise, links to glibc. musl: Boolean = false local setupLinuxEnvironment: Config.RunStep = let (jdkVersion = "11.0.20.1+1") let (muslVersion = "1.2.2") let (zlibVersion = "1.2.13") let (jdkVersionEncoded = URI.encodeComponent(jdkVersion)) let (jdkVersionAlt = jdkVersion.replaceLast("+", "_")) let (majorJdkVersion = jdkVersion.split(".").first) new { name = "Set up environment" shell = "#!/bin/bash -exo pipefail" command = new Listing { #""" sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \ && microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \ && microdnf clean all \ && rm -rf /var/cache/dnf # install jdk curl -L \ https://github.com/adoptium/temurin\#(majorJdkVersion)-binaries/releases/download/jdk-\#(jdkVersionEncoded)/OpenJDK\#(majorJdkVersion)U-jdk_\#(if (arch == "amd64") "x64" else "aarch64")_linux_hotspot_\#(jdkVersionAlt).tar.gz -o /tmp/jdk.tar.gz mkdir /jdk \ && cd /jdk \ && cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC . mkdir -p ~/staticdeps/bin cp /usr/lib/gcc/\#(if (arch == "amd64") "x86_64" else "aarch64")-redhat-linux/8/libstdc++.a ~/staticdeps # install zlib if [[ ! -f ~/staticdeps/include/zlib.h ]]; then curl -L https://github.com/madler/zlib/releases/download/v\#(zlibVersion)/zlib-\#(zlibVersion).tar.gz -o /tmp/zlib.tar.gz mkdir -p /tmp/dep_zlib-\#(zlibVersion) \ && cd /tmp/dep_zlib-\#(zlibVersion) \ && cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \ && echo "zlib-\#(zlibVersion): configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \ && echo "zlib-\#(zlibVersion): make..." && make -s -j4 \ && echo "zlib-\#(zlibVersion): make install..." && make -s install \ && rm -rf /tmp/dep_zlib-\#(zlibVersion) fi """# // don't need musl on aarch because GraalVM only supports musl builds on x86 when (arch == "amd64") { #""" # install musl if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then curl -L https://musl.libc.org/releases/musl-\#(muslVersion).tar.gz -o /tmp/musl.tar.gz mkdir -p /tmp/dep_musl-\#(muslVersion) \ && cd /tmp/dep_musl-\#(muslVersion) \ && cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \ && echo "musl-\#(muslVersion): configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \ && echo "musl-\#(muslVersion): make..." && make -s -j4 \ && echo "musl-\#(muslVersion): make install..." && make -s install \ && rm -rf /tmp/dep_musl-\#(muslVersion) # native-image expects to find an executable at this path. ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc fi """# } }.join("\n\n") } steps { when (os == "linux") { new Config.RestoreCacheStep { name = "Restore static deps from cache" key = "staticdeps-\(arch)" } setupLinuxEnvironment new Config.SaveCacheStep { name = "Save statics deps to cache" key = "staticdeps-\(arch)" paths { "~/staticdeps" } } } when (os == "macOS" && arch == "amd64") { new Config.RunStep { name = "Installing Rosetta 2" command = """ /usr/sbin/softwareupdate --install-rosetta --agree-to-license """ } } // If building macOS/aarch64, we need to use GraalVM 23. // We can't use GraalVM 23 for any other build because we need to support Java 11, which was // dropped in GraalVM 23. when (os == "macOS" && arch == "aarch64") { new Config.RunStep { command = "git apply patches/graalVm23.patch" } } new Config.RunStep { name = "gradle buildNative" local _os = if (os == "macOS") "mac" else if (musl) "alpine" else "linux" local jobName = "\(_os)Executable\(arch.capitalize())" command = #""" export PATH=~/staticdeps/bin:$PATH ./gradlew \#(module.gradleArgs) pkl-cli:\#(jobName) pkl-core:test\#(jobName.capitalize()) """# } new Config.PersistToWorkspaceStep { root = "." paths { "pkl-cli/build/executable/" } } } job { when (os == "macOS") { macos { xcode = "15.2.0" } // Use M1 for all architectures. We build amd64/aarch64 based on the GraalVM version, // which gets patched in via `git apply patches/graalVm23.patch`. resource_class = "macos.m1.large.gen1" } else { docker { new { image = if (arch == "aarch64") "arm64v8/oraclelinux:8-slim" else "oraclelinux:8-slim" } } environment { ["JAVA_HOME"] = "/jdk" } resource_class = if (arch == "aarch64") "arm.xlarge" else "xlarge" } }