From f3361119f9695154a6ab016b2950ee0a637c17f8 Mon Sep 17 00:00:00 2001 From: Andrew Leonard <31470007+andrew-m-leonard@users.noreply.github.com> Date: Tue, 19 Mar 2024 14:42:07 +0000 Subject: [PATCH] Support building in a user supplied OpenJDK build directory (#3696) * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard * Add new build arg option to specify an existing folder for openjdk build output Signed-off-by: Andrew Leonard --------- Signed-off-by: Andrew Leonard --- README.md | 4 ++ sbin/build.sh | 102 ++++++++++++++++++++++++++----------- sbin/common/common.sh | 2 +- sbin/common/config_init.sh | 7 +++ sbin/prepareWorkspace.sh | 11 ++++ 5 files changed, 95 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 144d340e7..d4df9e6b8 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,10 @@ This is typically used in conjunction with -b. --use-jep319-certs Use certs defined in JEP319 in Java 8/9. Deprecated, has no effect. +--user-openjdk-build-root-directory +Use a user specified openjdk build root directory, rather than the OpenJDK git source directory. +The directory must be empty, or not exist (in which case it gets created). + -v, --version specify the OpenJDK version to build e.g. jdk8u. Left for backwards compatibility. diff --git a/sbin/build.sh b/sbin/build.sh index 54e1bc807..a9143017f 100755 --- a/sbin/build.sh +++ b/sbin/build.sh @@ -263,8 +263,6 @@ getOpenJdkVersion() { # OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode) configureVersionStringParameter() { - stepIntoTheWorkingDirectory - local openJdkVersion=$(getOpenJdkVersion) echo "OpenJDK repo tag is ${openJdkVersion}" @@ -544,28 +542,39 @@ configureCommandParameters() { echo "Completed configuring the version string parameter, config args are now: ${CONFIGURE_ARGS}" } -# Make sure we're in the source directory for OpenJDK now -stepIntoTheWorkingDirectory() { - cd "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}" || exit +# Make sure we're in the build root directory for OpenJDK now +# This maybe the OpenJDK source directory, or a user supplied build directory +stepIntoTheOpenJDKBuildRootDirectory() { + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + cd "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}" || exit - # corretto/corretto-8 (jdk-8 only) nest their source under /src in their dir - if [ "${BUILD_CONFIG[BUILD_VARIANT]}" == "${BUILD_VARIANT_CORRETTO}" ] && [ "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" == "8" ]; then - cd "src" + # corretto/corretto-8 (jdk-8 only) nest their source under /src in their dir + if [ "${BUILD_CONFIG[BUILD_VARIANT]}" == "${BUILD_VARIANT_CORRETTO}" ] && [ "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" == "8" ]; then + cd "src" + fi + else + if [ ! -d "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + echo "ERROR: User supplied openjdk build root directory does not exist: ${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" + exit 2 + else + echo "Using user supplied openjdk build root directory: ${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" + cd "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" || exit + fi fi - echo "Should have the source, I'm at $PWD" + echo "Should be in the openjdk build root directory, I'm at $PWD" } buildTemplatedFile() { echo "Configuring command and using the pre-built config params..." - stepIntoTheWorkingDirectory + stepIntoTheOpenJDKBuildRootDirectory echo "Currently at '${PWD}'" if [[ "${BUILD_CONFIG[ASSEMBLE_EXPLODED_IMAGE]}" != "true" ]]; then - FULL_CONFIGURE="bash ./configure --verbose ${CONFIGURE_ARGS}" - echo "Running ./configure with arguments '${FULL_CONFIGURE}'" + FULL_CONFIGURE="bash ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/configure --verbose ${CONFIGURE_ARGS}" + echo "Running ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/configure with arguments '${FULL_CONFIGURE}'" else FULL_CONFIGURE="echo \"Skipping configure because we're assembling an exploded image\"" echo "Skipping configure because we're assembling an exploded image" @@ -599,7 +608,7 @@ buildTemplatedFile() { # Check if strace is available if rpm --version && rpm -q strace ; then echo "Strace and rpm is available on system" - FULL_MAKE_COMMAND="mkdir build/straceOutput \&\& strace -o build/straceOutput/outputFile -ff -e trace=open,openat,execve ${FULL_MAKE_COMMAND}" + FULL_MAKE_COMMAND="mkdir ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/straceOutput \&\& strace -o ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/straceOutput/outputFile -ff -e trace=open,openat,execve ${FULL_MAKE_COMMAND}" else echo "Strace is not available on system" exit 2 @@ -653,7 +662,7 @@ executeTemplatedFile() { if [ "${BUILD_CONFIG[CREATE_SOURCE_ARCHIVE]}" == "true" ]; then createSourceArchive fi - stepIntoTheWorkingDirectory + stepIntoTheOpenJDKBuildRootDirectory echo "Currently at '${PWD}'" @@ -678,8 +687,12 @@ executeTemplatedFile() { if [[ "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" -ge 19 || "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" -eq 17 ]]; then if [ "${BUILD_CONFIG[RELEASE]}" == "true" ]; then + local specFile="./spec.gmk" + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + specFile="build/*/spec.gmk" + fi # For "release" reproducible builds get openjdk timestamp used - local buildTimestamp=$(grep SOURCE_DATE_ISO_8601 build/*/spec.gmk | tr -s ' ' | cut -d' ' -f4) + local buildTimestamp=$(grep SOURCE_DATE_ISO_8601 ${specFile} | tr -s ' ' | cut -d' ' -f4) # BusyBox doesn't use T Z iso8601 format buildTimestamp="${buildTimestamp//T/ }" buildTimestamp="${buildTimestamp//Z/}" @@ -693,7 +706,9 @@ executeTemplatedFile() { createOpenJDKFailureLogsArchive() { echo "OpenJDK make failed, archiving make failed logs" - cd build/* + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + cd build/* + fi local adoptLogArchiveDir="TemurinLogsArchive" @@ -958,7 +973,7 @@ generateSBoM() { if [[ "${BUILD_CONFIG[ENABLE_SBOM_STRACE]}" == "true" ]]; then echo "Executing Analysis Script" tempBldDir="$(dirname "${BUILD_CONFIG[WORKSPACE_DIR]}")" - bash "$SCRIPT_DIR/../tooling/strace_analysis.sh" "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/straceOutput" "$tempBldDir" "$javaHome" "$classpath" "$sbomJson" + bash "$SCRIPT_DIR/../tooling/strace_analysis.sh" "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/straceOutput" "$tempBldDir" "$javaHome" "$classpath" "$sbomJson" fi # Print SBOM location @@ -975,11 +990,18 @@ checkingToolSummary() { # Determine FreeType version being used in the build from either the system or bundled freetype.h definition addFreeTypeVersionInfo() { + local specFile + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + specFile="${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk" + else + specFile="${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}/spec.gmk" + fi + # Default to "system" local FREETYPE_TO_USE="system" if [ "${BUILD_CONFIG[OPENJDK_CORE_VERSION]}" != "${JDK8_CORE_VERSION}" ]; then # For jdk-11+ get FreeType used from build spec.gmk, which can be "bundled" or "system" - FREETYPE_TO_USE="$(grep "^FREETYPE_TO_USE[ ]*:=" ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk | sed "s/^FREETYPE_TO_USE[ ]*:=[ ]*//")" + FREETYPE_TO_USE="$(grep "^FREETYPE_TO_USE[ ]*:=" ${specFile} | sed "s/^FREETYPE_TO_USE[ ]*:=[ ]*//")" fi echo "FREETYPE_TO_USE=${FREETYPE_TO_USE}" @@ -987,7 +1009,7 @@ addFreeTypeVersionInfo() { local version="Unknown" local freetypeInclude="" if [ "${FREETYPE_TO_USE}" == "system" ]; then - local FREETYPE_CFLAGS="$(grep "^FREETYPE_CFLAGS[ ]*:=" ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk | sed "s/^FREETYPE_CFLAGS[ ]*:=[ ]*//" | sed "s/\-I//g")" + local FREETYPE_CFLAGS="$(grep "^FREETYPE_CFLAGS[ ]*:=" ${specFile} | sed "s/^FREETYPE_CFLAGS[ ]*:=[ ]*//" | sed "s/\-I//g")" echo "FREETYPE_CFLAGS include paths=${FREETYPE_CFLAGS}" # Search freetype include path for freetype.h @@ -1066,12 +1088,18 @@ addGLIBCforLinux() { addSBOMMetadataTools "${javaHome}" "${classpath}" "${sbomJson}" "MUSL" "${MUSL_VERSION}" else # Get GLIBC from configured build spec.gmk sysroot and features.h definitions + local specFile + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + specFile="${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk" + else + specFile="${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}/spec.gmk" + fi # Get CC and SYSROOT_CFLAGS from the built build spec.gmk. - local CC="$(grep "^CC[ ]*:=" ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk | sed "s/^CC[ ]*:=[ ]*//")" + local CC="$(grep "^CC[ ]*:=" ${specFile} | sed "s/^CC[ ]*:=[ ]*//")" # Remove env=xx from CC, so we can call from bash to get __GLIBC. CC=$(echo "$CC" | tr -s " " | sed -E "s/[^ ]*=[^ ]*//g") - local SYSROOT_CFLAGS="$(grep "^SYSROOT_CFLAGS[ ]*:=" ${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}/${BUILD_CONFIG[OPENJDK_SOURCE_DIR]}/build/*/spec.gmk | tr -s " " | cut -d" " -f3-)" + local SYSROOT_CFLAGS="$(grep "^SYSROOT_CFLAGS[ ]*:=" ${specFile} | tr -s " " | cut -d" " -f3-)" local GLIBC_MAJOR="$(echo "#include " | $CC $SYSROOT_CFLAGS -dM -E - 2>&1 | tr -s " " | grep "#define __GLIBC__" | cut -d" " -f3)" local GLIBC_MINOR="$(echo "#include " | $CC $SYSROOT_CFLAGS -dM -E - 2>&1 | tr -s " " | grep "#define __GLIBC_MINOR__" | cut -d" " -f3)" @@ -1192,16 +1220,21 @@ parseJavaVersionString() { # Print the version string so we know what we've produced printJavaVersionString() { - stepIntoTheWorkingDirectory + stepIntoTheOpenJDKBuildRootDirectory + + local imagesFolder="images" + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + imagesFolder="build/*/images" + fi case "${BUILD_CONFIG[OS_KERNEL_NAME]}" in "darwin") # shellcheck disable=SC2086 - PRODUCT_HOME=$(ls -d ${PWD}/build/*/images/${BUILD_CONFIG[JDK_PATH]}/Contents/Home) + PRODUCT_HOME=$(ls -d ${PWD}/${imagesFolder}/${BUILD_CONFIG[JDK_PATH]}/Contents/Home) ;; *) # shellcheck disable=SC2086 - PRODUCT_HOME=$(ls -d ${PWD}/build/*/images/${BUILD_CONFIG[JDK_PATH]}) + PRODUCT_HOME=$(ls -d ${PWD}/${imagesFolder}/${BUILD_CONFIG[JDK_PATH]}) ;; esac if [[ -d "$PRODUCT_HOME" ]]; then @@ -1284,9 +1317,13 @@ cleanAndMoveArchiveFiles() { echo "Moving archive content to target archive paths and cleaning unnecessary files..." - stepIntoTheWorkingDirectory + stepIntoTheOpenJDKBuildRootDirectory - cd build/*/images || return + local imagesFolder="images" + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + imagesFolder="build/*/images" + fi + cd ${imagesFolder} || return echo "Currently at '${PWD}'" @@ -1706,7 +1743,7 @@ getLatestTagJDK11plus() { getFirstTagFromOpenJDKGitRepo() { # Save current directory of caller so we can return to that directory at the end of this function. - # Some callers are not in the git repo root, but instead build/*/images directory like the archive functions + # Some callers are not in the git repo root, but instead build root sub-directory like the archive functions # and any function called after cleanAndMoveArchiveFiles(). local savePwd="${PWD}" @@ -2051,15 +2088,20 @@ addSemVer() { # Pulls the semantic version from the tag associated with the open # Disable shellcheck in here as it causes issues with ls on mac mirrorToJRE() { - stepIntoTheWorkingDirectory + stepIntoTheOpenJDKBuildRootDirectory + + local imagesFolder="images" + if [ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ] ; then + imagesFolder="build/*/images" + fi # shellcheck disable=SC2086 case "${BUILD_CONFIG[OS_KERNEL_NAME]}" in "darwin") - JRE_HOME=$(ls -d ${PWD}/build/*/images/${BUILD_CONFIG[JRE_PATH]}/Contents/Home) + JRE_HOME=$(ls -d ${PWD}/${imagesFolder}/${BUILD_CONFIG[JRE_PATH]}/Contents/Home) ;; *) - JRE_HOME=$(ls -d ${PWD}/build/*/images/${BUILD_CONFIG[JRE_PATH]}) + JRE_HOME=$(ls -d ${PWD}/${imagesFolder}/${BUILD_CONFIG[JRE_PATH]}) ;; esac diff --git a/sbin/common/common.sh b/sbin/common/common.sh index d4e9d8ddb..261e4d08b 100755 --- a/sbin/common/common.sh +++ b/sbin/common/common.sh @@ -152,7 +152,7 @@ createOpenJDKArchive() local fullPath if [[ "${BUILD_CONFIG[OS_KERNEL_NAME]}" != "darwin" ]]; then fullPath=$(crossPlatformRealPath "$repoDir") - if [[ "$fullPath" != "${BUILD_CONFIG[WORKSPACE_DIR]}"* ]]; then + if [[ "$fullPath" != "${BUILD_CONFIG[WORKSPACE_DIR]}"* ]] && { [[ -z "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ]] || [[ "$fullPath" != "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}"* ]]; }; then echo "Requested to archive a dir outside of workspace" exit 1 fi diff --git a/sbin/common/config_init.sh b/sbin/common/config_init.sh index a0324f4be..3ee88244f 100755 --- a/sbin/common/config_init.sh +++ b/sbin/common/config_init.sh @@ -104,6 +104,7 @@ USE_JEP319_CERTS USE_SSH USER_SUPPLIED_CONFIGURE_ARGS USER_SUPPLIED_MAKE_ARGS +USER_OPENJDK_BUILD_ROOT_DIRECTORY VENDOR VENDOR_URL VENDOR_BUG_URL @@ -355,6 +356,9 @@ function parseConfigurationArguments() { "--use-jep319-certs" ) BUILD_CONFIG[USE_JEP319_CERTS]=true;; + "--user-openjdk-build-root-directory" ) + BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]="$1"; shift;; + "--vendor" | "-ve" ) BUILD_CONFIG[VENDOR]="$1"; shift;; @@ -490,6 +494,9 @@ function configDefaults() { # Default to no supplied reproducible build date, uses current date BUILD_CONFIG[BUILD_REPRODUCIBLE_DATE]="" + # Default to no user supplied openjdk build root directory + BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]="" + # The default behavior of whether we want to create a separate debug symbols archive BUILD_CONFIG[CREATE_DEBUG_IMAGE]="false" diff --git a/sbin/prepareWorkspace.sh b/sbin/prepareWorkspace.sh index 63b7fcf73..022a0b297 100644 --- a/sbin/prepareWorkspace.sh +++ b/sbin/prepareWorkspace.sh @@ -298,6 +298,17 @@ createWorkspace() { umask 022 mkdir -p "${BUILD_CONFIG[WORKSPACE_DIR]}" || exit mkdir -p "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}" || exit + + # If a user supplied OpenJDK build root directory has been specified and it is not empty + # then fail with an error, we don't want to delete it in case user has specified a wrong directory + # Ensure the directory is created if it doesn't exist + if [[ -n "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ]]; then + if [[ -d "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" ]] && [[ "$(ls -A "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}")" ]]; then + echo "ERROR: Existing user supplied OpenJDK build root directory ${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]} is not empty" + exit 1 + fi + mkdir -p "${BUILD_CONFIG[USER_OPENJDK_BUILD_ROOT_DIRECTORY]}" || exit + fi } # ALSA first for sound