mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
[build scripts] unified handling of boot classpath between launchers (IJPL-174985)
... + centralized setting of routing FS options and more realistic VM options in integration tests GitOrigin-RevId: 54dad6314198edaf5ce0f99c33c213305d78e322
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f951c6bf77
commit
80a4a5e8fa
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import com.intellij.platform.buildData.productInfo.ProductInfoLayoutItem
|
||||
@@ -63,13 +63,10 @@ interface BuildContext : CompilationContext {
|
||||
*/
|
||||
val systemSelector: String
|
||||
|
||||
/**
|
||||
* Names of JARs inside `IDE_HOME/lib` directory which need to be added to the JVM boot classpath to start the IDE.
|
||||
*/
|
||||
val xBootClassPathJarNames: List<String>
|
||||
|
||||
/**
|
||||
* Names of JARs inside `IDE_HOME/lib` directory which need to be added to the JVM classpath to start the IDE.
|
||||
*
|
||||
* **Note**: In terms of JVM, these JARs form a regular classpath (`-cp`), not a boot classpath (`-Xbootclasspath`).
|
||||
*/
|
||||
var bootClassPathJarNames: List<String>
|
||||
|
||||
@@ -137,6 +134,7 @@ interface BuildContext : CompilationContext {
|
||||
arch: JvmArchitecture,
|
||||
isScript: Boolean = false,
|
||||
isPortableDist: Boolean = false,
|
||||
isQodana: Boolean = false,
|
||||
): List<String>
|
||||
|
||||
fun findApplicationInfoModule(): JpsModule
|
||||
|
||||
@@ -26,10 +26,7 @@ abstract class JetBrainsProductProperties : ProductProperties() {
|
||||
sbomOptions.creator = "Organization: ${Suppliers.JETBRAINS}"
|
||||
sbomOptions.license = SoftwareBillOfMaterials.Options.DistributionLicense.JETBRAINS
|
||||
|
||||
productLayout.addPlatformSpec { layout, _ ->
|
||||
layout.withModule(IJENT_BOOT_CLASSPATH_MODULE, PLATFORM_CORE_NIO_FS)
|
||||
xBootClassPathJarNames += PLATFORM_CORE_NIO_FS
|
||||
}
|
||||
productLayout.addPlatformSpec { layout, _ -> layout.withModule(IJENT_BOOT_CLASSPATH_MODULE, PLATFORM_CORE_NIO_FS) }
|
||||
}
|
||||
|
||||
protected fun isCommunityModule(module: JpsModule, context: BuildContext): Boolean {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet", "ReplaceJavaStaticMethodWithKotlinAnalog")
|
||||
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import com.intellij.platform.ijent.community.buildConstants.isIjentWslFsEnabledByDefaultForProduct
|
||||
import com.intellij.platform.util.putMoreLikelyPluginJarsFirst
|
||||
import com.intellij.util.lang.HashMapZipFile
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
@@ -11,6 +12,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
import org.jetbrains.intellij.build.impl.ModuleOutputPatcher
|
||||
import org.jetbrains.intellij.build.impl.PlatformJarNames
|
||||
import org.jetbrains.intellij.build.impl.PlatformJarNames.PLATFORM_CORE_NIO_FS
|
||||
import org.jetbrains.intellij.build.impl.PluginLayout
|
||||
import org.jetbrains.intellij.build.impl.projectStructureMapping.DistributionFileEntry
|
||||
import org.jetbrains.intellij.build.io.INDEX_FILENAME
|
||||
@@ -58,17 +60,22 @@ suspend fun reorderJar(relativePath: String, file: Path) {
|
||||
}
|
||||
}
|
||||
|
||||
internal val excludedLibJars: Set<String> = java.util.Set.of(PlatformJarNames.TEST_FRAMEWORK_JAR)
|
||||
internal fun excludedLibJars(context: BuildContext): Set<String> =
|
||||
setOf(PlatformJarNames.TEST_FRAMEWORK_JAR) +
|
||||
if (isIjentWslFsEnabledByDefaultForProduct(context.productProperties.platformPrefix)) setOf(PLATFORM_CORE_NIO_FS) else emptySet()
|
||||
|
||||
internal suspend fun generateClasspath(homeDir: Path, libDir: Path): List<String> {
|
||||
internal suspend fun generateClasspath(context: BuildContext): List<String> {
|
||||
val homeDir = context.paths.distAllDir
|
||||
val libDir = homeDir.resolve("lib")
|
||||
return spanBuilder("generate classpath")
|
||||
.setAttribute("dir", homeDir.toString())
|
||||
.use { span ->
|
||||
val excluded = excludedLibJars(context)
|
||||
val existing = HashSet<Path>()
|
||||
addJarsFromDir(dir = libDir) { paths ->
|
||||
paths.filterTo(existing) { !excludedLibJars.contains(it.fileName.toString()) }
|
||||
addJarsFromDir(libDir) { paths ->
|
||||
paths.filterTo(existing) { !excluded.contains(it.fileName.toString()) }
|
||||
}
|
||||
val files = computeAppClassPath(libDir = libDir, existing = existing, homeDir = homeDir)
|
||||
val files = computeAppClassPath(libDir, existing, homeDir)
|
||||
val result = files.map { libDir.relativize(it).toString() }
|
||||
span.setAttribute(AttributeKey.stringArrayKey("result"), result)
|
||||
result
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet", "ReplacePutWithAssignment", "LiftReturnOrAssignment")
|
||||
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build.dev
|
||||
|
||||
import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.platform.buildData.productInfo.ProductInfoData
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.jetbrains.intellij.build.BuildOptions
|
||||
import org.jetbrains.intellij.build.JvmArchitecture
|
||||
import org.jetbrains.intellij.build.VmProperties
|
||||
import org.jetbrains.intellij.build.closeKtorClient
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import org.jetbrains.intellij.build.*
|
||||
import org.jetbrains.intellij.build.impl.productInfo.PRODUCT_INFO_FILE_NAME
|
||||
import org.jetbrains.intellij.build.impl.productInfo.jsonEncoder
|
||||
import org.jetbrains.intellij.build.telemetry.TraceManager
|
||||
import org.jetbrains.intellij.build.telemetry.use
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.inputStream
|
||||
import kotlin.io.path.readLines
|
||||
|
||||
@Serializable
|
||||
internal data class Configuration(@JvmField val products: Map<String, ProductConfiguration>)
|
||||
@@ -31,6 +34,7 @@ private const val PRODUCTS_PROPERTIES_PATH = "build/dev-build.json"
|
||||
*/
|
||||
private const val CUSTOM_PRODUCT_PROPERTIES_PATH = "idea.product.properties.path"
|
||||
|
||||
@Deprecated("Prefer `readVmOptions` for more accurate result")
|
||||
@Suppress("SpellCheckingInspection")
|
||||
fun getIdeSystemProperties(runDir: Path): VmProperties {
|
||||
val result = LinkedHashMap<String, String>()
|
||||
@@ -58,6 +62,30 @@ fun getIdeSystemProperties(runDir: Path): VmProperties {
|
||||
return VmProperties(result)
|
||||
}
|
||||
|
||||
fun readVmOptions(runDir: Path): List<String> {
|
||||
val result = ArrayList<String>()
|
||||
|
||||
val vmOptionsFile = Files.newDirectoryStream(runDir.resolve("bin"), "*.vmoptions").use { it.singleOrNull() }
|
||||
require(vmOptionsFile != null) {
|
||||
"No single *.vmoptions file in ${runDir} (${NioFiles.list(runDir).map(Path::getFileName).joinToString()})}"
|
||||
}
|
||||
result += vmOptionsFile.readLines()
|
||||
result += "-Djb.vmOptionsFile=${vmOptionsFile}"
|
||||
|
||||
val productInfoFile = runDir.resolve("bin").resolve(PRODUCT_INFO_FILE_NAME)
|
||||
if (productInfoFile.exists()) {
|
||||
val productJson = productInfoFile.inputStream().use { jsonEncoder.decodeFromStream<ProductInfoData>(it) }
|
||||
val macroName = when (OsFamily.currentOs) {
|
||||
OsFamily.WINDOWS -> "%IDE_HOME%"
|
||||
OsFamily.MACOS -> "\$APP_PACKAGE/Contents"
|
||||
OsFamily.LINUX -> "\$IDE_HOME"
|
||||
}
|
||||
result += productJson.launch[0].additionalJvmArguments.map { it.replace(macroName, runDir.toString()) }
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns IDE installation directory */
|
||||
suspend fun buildProductInProcess(request: BuildRequest): Path {
|
||||
if (request.tracer != null) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplacePutWithAssignment")
|
||||
|
||||
package org.jetbrains.intellij.build.dev
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.intellij.build.*
|
||||
import org.jetbrains.intellij.build.BuildOptions.Companion.PROJECT_CLASSES_OUTPUT_DIRECTORY_PROPERTY
|
||||
import org.jetbrains.intellij.build.BuildPaths.Companion.COMMUNITY_ROOT
|
||||
import org.jetbrains.intellij.build.impl.*
|
||||
import org.jetbrains.intellij.build.impl.productInfo.PRODUCT_INFO_FILE_NAME
|
||||
import org.jetbrains.intellij.build.impl.projectStructureMapping.DistributionFileEntry
|
||||
import org.jetbrains.intellij.build.impl.projectStructureMapping.ModuleOutputEntry
|
||||
import org.jetbrains.intellij.build.jarCache.LocalDiskJarCacheManager
|
||||
@@ -42,6 +43,8 @@ import java.time.DayOfWeek
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.time.temporal.TemporalAdjusters
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.moveTo
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
data class BuildRequest(
|
||||
@@ -55,7 +58,7 @@ data class BuildRequest(
|
||||
@JvmField val platformClassPathConsumer: ((classPath: Set<Path>, runDir: Path) -> Unit)? = null,
|
||||
/**
|
||||
* If `true`, the dev build will include a [runtime module repository](psi_element://com.intellij.platform.runtime.repository).
|
||||
* It's currently used only to run an instance of JetBrains Client from IDE's installation,
|
||||
* It's currently used only to run an instance of JetBrains Client from IDE's installation,
|
||||
* and its generation makes build a little longer, so it should be enabled only if needed.
|
||||
*/
|
||||
@JvmField val generateRuntimeModuleRepository: Boolean = false,
|
||||
@@ -134,11 +137,16 @@ internal suspend fun buildProduct(request: BuildRequest, createProductProperties
|
||||
launch(Dispatchers.IO) {
|
||||
// PathManager.getBinPath() is used as a working dir for maven
|
||||
val binDir = Files.createDirectories(runDir.resolve("bin"))
|
||||
val oldFiles = Files.newDirectoryStream(binDir).use { it -> it.toCollection(HashSet()) }
|
||||
val oldFiles = Files.newDirectoryStream(binDir).use { it.toCollection(HashSet()) }
|
||||
|
||||
val osDistributionBuilder = getOsDistributionBuilder(os = OsFamily.currentOs, context = context)
|
||||
if (osDistributionBuilder != null) {
|
||||
oldFiles.remove(osDistributionBuilder.writeVmOptions(binDir))
|
||||
// the file cannot be placed right into the distribution as it throws off home dir detection in `PathManager#getHomeDirFor`
|
||||
val productInfoDir = context.paths.tempDir.resolve("product-info").createDirectories()
|
||||
val productInfoFile = osDistributionBuilder.writeProductInfoFile(productInfoDir, JvmArchitecture.currentJvmArch)
|
||||
oldFiles.remove(productInfoFile.moveTo(binDir.resolve(PRODUCT_INFO_FILE_NAME), overwrite = true))
|
||||
NioFiles.deleteRecursively(productInfoDir)
|
||||
}
|
||||
|
||||
val ideaPropertyFile = binDir.resolve(PathManager.PROPERTIES_FILE_NAME)
|
||||
@@ -164,9 +172,10 @@ internal suspend fun buildProduct(request: BuildRequest, createProductProperties
|
||||
|
||||
if (request.writeCoreClasspath) {
|
||||
launch(Dispatchers.IO) {
|
||||
val excluded = excludedLibJars(context)
|
||||
val classPathString = classPath
|
||||
.asSequence()
|
||||
.filter { !excludedLibJars.contains(it.fileName.toString()) }
|
||||
.filter { it.fileName.toString() !in excluded }
|
||||
.joinToString(separator = "\n")
|
||||
Files.writeString(runDir.resolve("core-classpath.txt"), classPathString)
|
||||
}
|
||||
@@ -464,6 +473,7 @@ private suspend fun createBuildContext(
|
||||
BuildOptions.PREBUILD_SHARED_INDEXES,
|
||||
BuildOptions.GENERATE_JAR_ORDER_STEP,
|
||||
BuildOptions.FUS_METADATA_BUNDLE_STEP,
|
||||
BuildOptions.PROVIDED_MODULES_LIST_STEP,
|
||||
)
|
||||
|
||||
if (request.isUnpackedDist && options.enableEmbeddedFrontend) {
|
||||
@@ -472,6 +482,11 @@ private suspend fun createBuildContext(
|
||||
|
||||
options.generateRuntimeModuleRepository = options.generateRuntimeModuleRepository && request.generateRuntimeModuleRepository
|
||||
|
||||
buildOptionsTemplate?.let { template ->
|
||||
options.isInDevelopmentMode = template.isInDevelopmentMode
|
||||
options.isTestBuild = template.isTestBuild
|
||||
}
|
||||
|
||||
val tempDir = buildDir.resolve("temp")
|
||||
val result = BuildPaths(
|
||||
communityHomeDirRoot = COMMUNITY_ROOT,
|
||||
@@ -663,4 +678,4 @@ private fun getCommunityHomePath(homePath: Path): Path = if (Files.isDirectory(h
|
||||
|
||||
fun getAdditionalPluginMainModules(): List<String> {
|
||||
return System.getProperty("additional.modules")?.splitToSequence(',')?.map { it.trim() }?.filter { it.isNotEmpty() }?.toList() ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet", "ReplaceJavaStaticMethodWithKotlinAnalog")
|
||||
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import com.dynatrace.hash4j.hashing.HashStream64
|
||||
import com.intellij.platform.ijent.community.buildConstants.IJENT_WSL_FILE_SYSTEM_REGISTRY_KEY
|
||||
import com.intellij.platform.ijent.community.buildConstants.MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS
|
||||
import com.intellij.platform.ijent.community.buildConstants.isIjentWslFsEnabledByDefaultForProduct
|
||||
import com.intellij.platform.runtime.product.ProductMode
|
||||
import com.intellij.util.containers.with
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
@@ -13,6 +16,7 @@ import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.intellij.build.*
|
||||
import org.jetbrains.intellij.build.impl.PlatformJarNames.PLATFORM_CORE_NIO_FS
|
||||
import org.jetbrains.intellij.build.impl.plugins.PluginAutoPublishList
|
||||
import org.jetbrains.intellij.build.io.runProcess
|
||||
import org.jetbrains.intellij.build.jarCache.JarCacheManager
|
||||
@@ -80,9 +84,6 @@ class BuildContextImpl internal constructor(
|
||||
jarCacheManager.cleanup()
|
||||
}
|
||||
|
||||
override val xBootClassPathJarNames: List<String>
|
||||
get() = productProperties.xBootClassPathJarNames
|
||||
|
||||
override var bootClassPathJarNames: List<String> = java.util.List.of(PLATFORM_LOADER_JAR)
|
||||
|
||||
override val ideMainClassName: String
|
||||
@@ -316,8 +317,21 @@ class BuildContextImpl internal constructor(
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override fun getAdditionalJvmArguments(os: OsFamily, arch: JvmArchitecture, isScript: Boolean, isPortableDist: Boolean): List<String> {
|
||||
override fun getAdditionalJvmArguments(os: OsFamily, arch: JvmArchitecture, isScript: Boolean, isPortableDist: Boolean, isQodana: Boolean): List<String> {
|
||||
val jvmArgs = ArrayList<String>()
|
||||
val macroName = when (os) {
|
||||
OsFamily.WINDOWS -> "%IDE_HOME%"
|
||||
OsFamily.MACOS -> "\$APP_PACKAGE${if (isPortableDist) "" else "/Contents"}"
|
||||
OsFamily.LINUX -> "\$IDE_HOME"
|
||||
}
|
||||
val useMultiRoutingFs = !isQodana && isIjentWslFsEnabledByDefaultForProduct(productProperties.platformPrefix)
|
||||
|
||||
val bcpJarNames = productProperties.xBootClassPathJarNames + if (useMultiRoutingFs) listOf(PLATFORM_CORE_NIO_FS) else emptyList()
|
||||
if (bcpJarNames.isNotEmpty()) {
|
||||
val separator = if (os == OsFamily.WINDOWS) ";" else ":"
|
||||
val bootCp = bcpJarNames.joinToString(separator) { "${macroName}/lib/${it}" }
|
||||
jvmArgs += "-Xbootclasspath/a:${bootCp}".let { if (isScript) '"' + it + '"' else it }
|
||||
}
|
||||
|
||||
if (productProperties.enableCds) {
|
||||
val cacheDir = if (os == OsFamily.WINDOWS) "%IDE_CACHE_DIR%\\" else "\$IDE_CACHE_DIR/"
|
||||
@@ -333,11 +347,6 @@ class BuildContextImpl internal constructor(
|
||||
jvmArgs.add("-Didea.vendor.name=${applicationInfo.shortCompanyName}")
|
||||
jvmArgs.add("-Didea.paths.selector=${systemSelector}")
|
||||
|
||||
val macroName = when (os) {
|
||||
OsFamily.WINDOWS -> "%IDE_HOME%"
|
||||
OsFamily.MACOS -> "\$APP_PACKAGE${if (isPortableDist) "" else "/Contents"}"
|
||||
OsFamily.LINUX -> "\$IDE_HOME"
|
||||
}
|
||||
jvmArgs.add("-Djna.boot.library.path=${macroName}/lib/jna/${arch.dirName}".let { if (isScript) '"' + it + '"' else it })
|
||||
jvmArgs.add("-Dpty4j.preferred.native.folder=${macroName}/lib/pty4j".let { if (isScript) '"' + it + '"' else it })
|
||||
// require bundled JNA dispatcher lib
|
||||
@@ -357,6 +366,13 @@ class BuildContextImpl internal constructor(
|
||||
jvmArgs.add("-Didea.platform.prefix=${productProperties.platformPrefix}")
|
||||
}
|
||||
|
||||
if (os == OsFamily.WINDOWS) {
|
||||
jvmArgs += "-D${IJENT_WSL_FILE_SYSTEM_REGISTRY_KEY}=${useMultiRoutingFs}"
|
||||
if (useMultiRoutingFs) {
|
||||
jvmArgs += MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
jvmArgs.addAll(productProperties.additionalIdeJvmArguments)
|
||||
jvmArgs.addAll(productProperties.getAdditionalContextDependentIdeJvmArguments(this))
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet")
|
||||
|
||||
package org.jetbrains.intellij.build.impl
|
||||
@@ -88,10 +88,7 @@ internal suspend fun buildDistribution(
|
||||
if (!isUpdateFromSources && context.productProperties.scrambleMainJar) {
|
||||
scramble(state.platform, context)
|
||||
}
|
||||
|
||||
val distAllDir = context.paths.distAllDir
|
||||
val libDir = distAllDir.resolve("lib")
|
||||
context.bootClassPathJarNames = if (context.useModularLoader) listOf(PLATFORM_LOADER_JAR) else generateClasspath(homeDir = distAllDir, libDir = libDir)
|
||||
context.bootClassPathJarNames = if (context.useModularLoader) listOf(PLATFORM_LOADER_JAR) else generateClasspath(context)
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
@@ -26,6 +26,7 @@ import java.nio.file.StandardCopyOption
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.nameWithoutExtension
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
private const val NO_RUNTIME_SUFFIX = "-no-jbr"
|
||||
@@ -130,9 +131,7 @@ class LinuxDistributionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture) {
|
||||
generateProductJson(targetDir, arch)
|
||||
}
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture): Path = writeProductJsonFile(targetDir, arch)
|
||||
|
||||
override fun writeVmOptions(distBinDir: Path): Path = writeLinuxVmOptions(distBinDir, context)
|
||||
|
||||
@@ -173,7 +172,7 @@ class LinuxDistributionBuilder(
|
||||
}
|
||||
|
||||
val productJsonDir = context.paths.tempDir.resolve("linux.dist.product-info.json${suffix}")
|
||||
generateProductJson(productJsonDir, arch, withRuntime = runtimeDir != null)
|
||||
writeProductJsonFile(productJsonDir, arch, withRuntime = runtimeDir != null)
|
||||
dirs.add(productJsonDir)
|
||||
|
||||
spanBuilder("build Linux tar.gz")
|
||||
@@ -270,14 +269,9 @@ class LinuxDistributionBuilder(
|
||||
""".trimMargin()
|
||||
)
|
||||
val productJsonDir = context.paths.tempDir.resolve("linux.dist.snap.product-info.json.$architecture")
|
||||
val jsonText = generateProductJson(productJsonDir, arch)
|
||||
validateProductJson(
|
||||
jsonText,
|
||||
relativePathToProductJson = "",
|
||||
installationDirectories = listOf(context.paths.distAllDir, unixDistPath, runtimeDir),
|
||||
installationArchives = listOf(),
|
||||
context
|
||||
)
|
||||
val productJsonFile = writeProductJsonFile(productJsonDir, arch)
|
||||
val installationDirectories = listOf(context.paths.distAllDir, unixDistPath, runtimeDir)
|
||||
validateProductJson(jsonText = productJsonFile.readText(), relativePathToProductJson = "", installationDirectories, installationArchives = emptyList(), context)
|
||||
val resultDir = snapDir.resolve("result")
|
||||
Files.createDirectories(resultDir)
|
||||
|
||||
@@ -330,7 +324,7 @@ class LinuxDistributionBuilder(
|
||||
|
||||
override fun isRuntimeBundled(file: Path): Boolean = !file.name.contains(NO_RUNTIME_SUFFIX)
|
||||
|
||||
private suspend fun generateProductJson(targetDir: Path, arch: JvmArchitecture, withRuntime: Boolean = true): String {
|
||||
private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, withRuntime: Boolean = true): Path {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.LINUX, context) {
|
||||
"bin/${it.productProperties.baseFileName}64.vmoptions"
|
||||
}
|
||||
@@ -354,8 +348,9 @@ class LinuxDistributionBuilder(
|
||||
),
|
||||
context
|
||||
)
|
||||
writeProductInfoJson(targetFile = targetDir.resolve(PRODUCT_INFO_FILE_NAME), json = json, context = context)
|
||||
return json
|
||||
val file = targetDir.resolve(PRODUCT_INFO_FILE_NAME)
|
||||
writeProductInfoJson(file, json, context)
|
||||
return file
|
||||
}
|
||||
|
||||
private fun generateVersionMarker(unixDistPath: Path) {
|
||||
@@ -405,17 +400,11 @@ class LinuxDistributionBuilder(
|
||||
classPath += "\nCLASS_PATH=\"\$CLASS_PATH:\$IDE_HOME/lib/${classPathJars[i]}\""
|
||||
}
|
||||
|
||||
val additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.LINUX, arch, isScript = true).toMutableList()
|
||||
additionalJvmArguments.addAll(nonCustomizableJvmArgs)
|
||||
if (!context.xBootClassPathJarNames.isEmpty()) {
|
||||
val bootCp = context.xBootClassPathJarNames.joinToString(separator = ":") { "\$IDE_HOME/lib/${it}" }
|
||||
additionalJvmArguments.add("\"-Xbootclasspath/a:$bootCp\"")
|
||||
}
|
||||
val additionalJvmArgs = additionalJvmArguments.joinToString(separator = " ")
|
||||
val additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.LINUX, arch, isScript = true) + nonCustomizableJvmArgs
|
||||
val additionalTemplateValues = listOf(
|
||||
Pair("vm_options", context.productProperties.baseFileName),
|
||||
Pair("system_selector", context.systemSelector),
|
||||
Pair("ide_jvm_args", additionalJvmArgs),
|
||||
Pair("ide_jvm_args", additionalJvmArguments.joinToString(separator = " ")),
|
||||
Pair("ide_default_xmx", defaultXmxParameter.trim()),
|
||||
Pair("class_path", classPath),
|
||||
Pair("main_class_name", context.ideMainClassName),
|
||||
|
||||
@@ -182,9 +182,11 @@ class MacDistributionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture) {
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture): Path {
|
||||
val json = generateProductJson(context, arch, withRuntime = true)
|
||||
writeProductInfoJson(targetDir.resolve("Resources/${PRODUCT_INFO_FILE_NAME}"), json, context)
|
||||
val file = targetDir.resolve("Resources/${PRODUCT_INFO_FILE_NAME}")
|
||||
writeProductInfoJson(file, json, context)
|
||||
return file
|
||||
}
|
||||
|
||||
private suspend fun signMacBinaries(osAndArchSpecificDistPath: Path, runtimeDist: Path, arch: JvmArchitecture) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
@@ -31,7 +31,7 @@ interface OsSpecificDistributionBuilder {
|
||||
|
||||
suspend fun buildArtifacts(osAndArchSpecificDistPath: Path, arch: JvmArchitecture)
|
||||
|
||||
suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture)
|
||||
suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture): Path
|
||||
|
||||
fun generateExecutableFilesPatterns(includeRuntime: Boolean, arch: JvmArchitecture): Sequence<String> = emptySequence()
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.platform.buildData.productInfo.ProductInfoLaunchData
|
||||
import com.intellij.platform.ijent.community.buildConstants.IJENT_WSL_FILE_SYSTEM_REGISTRY_KEY
|
||||
import com.intellij.platform.ijent.community.buildConstants.MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS
|
||||
import com.intellij.platform.ijent.community.buildConstants.isIjentWslFsEnabledByDefaultForProduct
|
||||
import com.jetbrains.plugin.structure.base.utils.exists
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.api.trace.Span
|
||||
@@ -28,6 +25,7 @@ import java.time.LocalDate
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.readText
|
||||
|
||||
internal class WindowsDistributionBuilder(
|
||||
override val context: BuildContext,
|
||||
@@ -128,9 +126,9 @@ internal class WindowsDistributionBuilder(
|
||||
|
||||
context.executeStep(spanBuilder("build Windows installer").setAttribute("arch", arch.dirName), BuildOptions.WINDOWS_EXE_INSTALLER_STEP) {
|
||||
val productJsonDir = Files.createTempDirectory(context.paths.tempDir, "win-product-info")
|
||||
val jsonText = generateProductJson(productJsonDir, context, arch)
|
||||
val productJsonFile = writeProductJsonFile(productJsonDir, arch)
|
||||
val installationDirectories = listOf(context.paths.distAllDir, osAndArchSpecificDistPath, runtimeDir)
|
||||
validateProductJson(jsonText, relativePathToProductJson = "", installationDirectories, installationArchives = emptyList(), context)
|
||||
validateProductJson(jsonText = productJsonFile.readText(), relativePathToProductJson = "", installationDirectories, installationArchives = emptyList(), context)
|
||||
launch(Dispatchers.IO + CoroutineName("build Windows ${arch.dirName} installer")) {
|
||||
exePath = buildNsisInstaller(osAndArchSpecificDistPath, additionalDirectoryToInclude = productJsonDir, suffix(arch), customizer, runtimeDir, context)
|
||||
}
|
||||
@@ -152,9 +150,7 @@ internal class WindowsDistributionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture) {
|
||||
generateProductJson(targetDir = targetDir, context = context, arch = arch)
|
||||
}
|
||||
override suspend fun writeProductInfoFile(targetDir: Path, arch: JvmArchitecture): Path = writeProductJsonFile(targetDir, arch)
|
||||
|
||||
private fun generateScripts(distBinDir: Path, arch: JvmArchitecture) {
|
||||
val fullName = context.applicationInfo.fullProductName
|
||||
@@ -168,13 +164,7 @@ internal class WindowsDistributionBuilder(
|
||||
classPath += "\nSET \"CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${classPathJars[i]}\""
|
||||
}
|
||||
|
||||
var additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch, isScript = true)
|
||||
if (!context.xBootClassPathJarNames.isEmpty()) {
|
||||
additionalJvmArguments = additionalJvmArguments.toMutableList()
|
||||
val bootCp = context.xBootClassPathJarNames.joinToString(separator = ";") { "%IDE_HOME%\\lib\\${it}" }
|
||||
additionalJvmArguments.add("\"-Xbootclasspath/a:$bootCp\"")
|
||||
}
|
||||
|
||||
val additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch, isScript = true)
|
||||
val winScripts = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/win/scripts")
|
||||
val actualScriptNames = Files.newDirectoryStream(winScripts).use { dirStream -> dirStream.map { it.fileName.toString() }.sorted() }
|
||||
|
||||
@@ -261,7 +251,7 @@ internal class WindowsDistributionBuilder(
|
||||
}
|
||||
|
||||
val productJsonDir = context.paths.tempDir.resolve("win.dist.product-info.json.zip${zipNameSuffix}")
|
||||
generateProductJson(productJsonDir, context, arch, withRuntime = runtimeDir != null)
|
||||
writeProductJsonFile(productJsonDir, arch, withRuntime = runtimeDir != null)
|
||||
dirs.add(productJsonDir)
|
||||
|
||||
val zipPrefix = customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)
|
||||
@@ -383,22 +373,16 @@ internal class WindowsDistributionBuilder(
|
||||
|
||||
private fun writeWindowsVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val vmOptionsFile = distBinDir.resolve("${context.productProperties.baseFileName}64.exe.vmoptions")
|
||||
var vmOptions = VmOptionsGenerator.generate(context).asSequence()
|
||||
val isIjentWslFsEnabled = isIjentWslFsEnabledByDefaultForProduct(context.productProperties.platformPrefix)
|
||||
vmOptions += "-D${IJENT_WSL_FILE_SYSTEM_REGISTRY_KEY}=${isIjentWslFsEnabled}"
|
||||
if (isIjentWslFsEnabled) {
|
||||
vmOptions += MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS
|
||||
}
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence()
|
||||
VmOptionsGenerator.writeVmOptions(vmOptionsFile, vmOptions, separator = "\r\n")
|
||||
return vmOptionsFile
|
||||
}
|
||||
|
||||
private suspend fun generateProductJson(targetDir: Path, context: BuildContext, arch: JvmArchitecture, withRuntime: Boolean = true): String {
|
||||
private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, withRuntime: Boolean = true): Path {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch = arch, os = OsFamily.WINDOWS, ideContext = context) {
|
||||
"bin/${it.productProperties.baseFileName}64.exe.vmoptions"
|
||||
}
|
||||
val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.WINDOWS)
|
||||
|
||||
val json = generateProductInfoJson(
|
||||
relativePathToBin = "bin",
|
||||
builtinModules = context.builtinModule,
|
||||
@@ -416,8 +400,9 @@ internal class WindowsDistributionBuilder(
|
||||
)
|
||||
),
|
||||
context)
|
||||
writeProductInfoJson(targetDir.resolve(PRODUCT_INFO_FILE_NAME), json, context)
|
||||
return json
|
||||
val file = targetDir.resolve(PRODUCT_INFO_FILE_NAME)
|
||||
writeProductInfoJson(file, json, context)
|
||||
return file
|
||||
}
|
||||
|
||||
private fun toDosLineEndings(x: String): String = x.replace("\r", "").replace("\n", "\r\n")
|
||||
|
||||
@@ -71,7 +71,7 @@ internal fun generateProductInfoJson(
|
||||
private fun generateGitRevisionProperty(context: BuildContext): CustomProperty? {
|
||||
val gitRoot = context.paths.projectHome
|
||||
if (!gitRoot.resolve(".git").isDirectory) {
|
||||
if (!context.options.isInDevelopmentMode) {
|
||||
if (!context.options.isInDevelopmentMode && !context.options.isTestBuild) {
|
||||
context.messages.error("Cannot find Git repository root in '$gitRoot'")
|
||||
}
|
||||
return null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.intellij.build.impl.qodana
|
||||
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
@@ -13,9 +13,9 @@ internal fun generateQodanaLaunchData(
|
||||
os: OsFamily,
|
||||
): CustomCommandLaunchData? {
|
||||
val qodanaProductProperties = ideContext.productProperties.qodanaProductProperties ?: return null
|
||||
val vmOptions = ideContext.getAdditionalJvmArguments(os, arch) + qodanaProductProperties.getAdditionalVmOptions(ideContext)
|
||||
val vmOptions = ideContext.getAdditionalJvmArguments(os, arch, isQodana = true) + qodanaProductProperties.getAdditionalVmOptions(ideContext)
|
||||
return CustomCommandLaunchData(
|
||||
commands = listOf("qodana"),
|
||||
additionalJvmArguments = vmOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user