mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cleanup [build scripts]: obsolete code; minor optimization; formatting
GitOrigin-RevId: 428337908e5ba55ff0c11341af21820b6c3f353d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c43ff906a2
commit
1a3d0197dd
+92
-102
@@ -73,11 +73,11 @@ class LinuxDistributionBuilder(
|
||||
withContext(Dispatchers.IO) {
|
||||
val distBinDir = targetPath.resolve("bin")
|
||||
val sourceBinDir = context.paths.communityHomeDir.resolve("bin/linux")
|
||||
addNativeLauncher(distBinDir = distBinDir, targetPath = targetPath, arch = arch, context = context)
|
||||
addNativeLauncher(distBinDir, targetPath, arch, context)
|
||||
copyFileToDir(NativeBinaryDownloader.getRestarter(context, OsFamily.LINUX, arch), distBinDir)
|
||||
copyFileToDir(sourceBinDir.resolve("${arch.dirName}/fsnotifier"), distBinDir)
|
||||
generateBuildTxt(context = context, targetDirectory = targetPath)
|
||||
copyDistFiles(context = context, newDir = targetPath, os = OsFamily.LINUX, arch = arch, libcImpl = targetLibcImpl)
|
||||
generateBuildTxt(context, targetPath)
|
||||
copyDistFiles(context, targetPath, OsFamily.LINUX, arch, targetLibcImpl)
|
||||
|
||||
//todo converting line separators to unix-style make sense only when building Linux distributions under Windows on a local machine;
|
||||
// for real installers we need to checkout all text files with 'lf' separators anyway
|
||||
@@ -87,15 +87,11 @@ class LinuxDistributionBuilder(
|
||||
Files.copy(iconPngPath, distBinDir.resolve("${context.productProperties.baseFileName}.png"), StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
writeVmOptions(distBinDir)
|
||||
generateScripts(distBinDir = distBinDir, arch = arch, targetLibcImpl = targetLibcImpl, context = context)
|
||||
generateScripts(distBinDir, arch, targetLibcImpl, context)
|
||||
createFrontendContextForLaunchers(context)?.let { clientContext ->
|
||||
writeLinuxVmOptions(distBinDir, clientContext)
|
||||
generateLauncherScript(
|
||||
distBinDir = distBinDir,
|
||||
arch = arch,
|
||||
nonCustomizableJvmArgs = ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS,
|
||||
context = clientContext,
|
||||
targetLibcImpl = targetLibcImpl
|
||||
distBinDir, arch, ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, clientContext, targetLibcImpl
|
||||
)
|
||||
}
|
||||
generateReadme(targetPath)
|
||||
@@ -183,9 +179,8 @@ class LinuxDistributionBuilder(
|
||||
)
|
||||
}
|
||||
|
||||
override fun generateExecutableFilesPatterns(includeRuntime: Boolean, arch: JvmArchitecture, libc: LibcImpl): Sequence<String> {
|
||||
return customizer.generateExecutableFilesPatterns(context, includeRuntime, arch, libc)
|
||||
}
|
||||
override fun generateExecutableFilesPatterns(includeRuntime: Boolean, arch: JvmArchitecture, libc: LibcImpl): Sequence<String> =
|
||||
customizer.generateExecutableFilesPatterns(context, includeRuntime, arch, libc)
|
||||
|
||||
private val rootDirectoryName: String
|
||||
get() = customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)
|
||||
@@ -237,9 +232,7 @@ class LinuxDistributionBuilder(
|
||||
JvmArchitecture.aarch64 -> "arm64"
|
||||
}
|
||||
|
||||
private fun getSnapArtifactName(snapName: String, arch: JvmArchitecture): String {
|
||||
return "${snapName}_${snapVersion}_${getSnapArchName(arch)}.snap"
|
||||
}
|
||||
private fun getSnapArtifactName(snapName: String, arch: JvmArchitecture): String = "${snapName}_${snapVersion}_${getSnapArchName(arch)}.snap"
|
||||
|
||||
private suspend fun buildSnapPackage(runtimeDir: Path, unixDistPath: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl) {
|
||||
if (!context.options.buildUnixSnaps) {
|
||||
@@ -331,7 +324,7 @@ class LinuxDistributionBuilder(
|
||||
"--volume=$runtimeDir:/build/jre:ro",
|
||||
"--workdir=/build",
|
||||
context.options.snapDockerImage,
|
||||
"snapcraft",
|
||||
@Suppress("SpellCheckingInspection") "snapcraft",
|
||||
"snap",
|
||||
"--build-for=$architecture",
|
||||
"-o", "result/$snapArtifactName"
|
||||
@@ -392,104 +385,101 @@ class LinuxDistributionBuilder(
|
||||
writeProductInfoJson(file, json, context)
|
||||
return file
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateVersionMarker(unixDistPath: Path, context: BuildContext) {
|
||||
val targetDir = unixDistPath.resolve("lib")
|
||||
Files.createDirectories(targetDir)
|
||||
Files.writeString(targetDir.resolve("build-marker-" + context.fullBuildNumber), context.fullBuildNumber)
|
||||
}
|
||||
private fun generateVersionMarker(unixDistPath: Path, context: BuildContext) {
|
||||
val targetDir = unixDistPath.resolve("lib")
|
||||
Files.createDirectories(targetDir)
|
||||
Files.writeString(targetDir.resolve("build-marker-" + context.fullBuildNumber), context.fullBuildNumber)
|
||||
}
|
||||
|
||||
private fun generateScripts(distBinDir: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl, context: BuildContext) {
|
||||
Files.createDirectories(distBinDir)
|
||||
|
||||
private fun generateScripts(distBinDir: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl, context: BuildContext) {
|
||||
Files.createDirectories(distBinDir)
|
||||
|
||||
val sourceScriptDir = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts")
|
||||
Files.newDirectoryStream(sourceScriptDir).use {
|
||||
for (file in it) {
|
||||
val fileName = file.fileName.toString()
|
||||
if (fileName != EXECUTABLE_TEMPLATE_NAME) {
|
||||
copyScript(file, distBinDir.resolve(fileName), additionalTemplateValues = emptyList(), context)
|
||||
val sourceScriptDir = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts")
|
||||
Files.newDirectoryStream(sourceScriptDir).use {
|
||||
for (file in it) {
|
||||
val fileName = file.fileName.toString()
|
||||
if (fileName != EXECUTABLE_TEMPLATE_NAME) {
|
||||
copyScript(file, distBinDir.resolve(fileName), additionalTemplateValues = emptyList(), context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copyInspectScript(context, distBinDir)
|
||||
|
||||
generateLauncherScript(distBinDir, arch, nonCustomizableJvmArgs = emptyList(), context, targetLibcImpl)
|
||||
}
|
||||
|
||||
copyInspectScript(context, distBinDir)
|
||||
|
||||
generateLauncherScript(distBinDir, arch, nonCustomizableJvmArgs = emptyList(), context, targetLibcImpl)
|
||||
}
|
||||
|
||||
private suspend fun addNativeLauncher(distBinDir: Path, targetPath: Path, arch: JvmArchitecture, context: BuildContext) {
|
||||
val (execPath, licensePath) = NativeBinaryDownloader.getLauncher(context, OsFamily.LINUX, arch)
|
||||
copyFile(execPath, distBinDir.resolve(context.productProperties.baseFileName))
|
||||
copyFile(licensePath, targetPath.resolve("license/launcher-third-party-libraries.html"))
|
||||
}
|
||||
|
||||
private fun generateLauncherScript(distBinDir: Path, arch: JvmArchitecture, nonCustomizableJvmArgs: List<String>, context: BuildContext, targetLibcImpl: LinuxLibcImpl) {
|
||||
val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions")
|
||||
|
||||
val defaultXmxParameter = try {
|
||||
Files.readAllLines(vmOptionsPath).firstOrNull { it.startsWith("-Xmx") }
|
||||
?: throw IllegalStateException("-Xmx was not found in '$vmOptionsPath'")
|
||||
}
|
||||
catch (e: NoSuchFileException) {
|
||||
throw IllegalStateException("File '$vmOptionsPath' should be already generated at this point", e)
|
||||
private suspend fun addNativeLauncher(distBinDir: Path, targetPath: Path, arch: JvmArchitecture, context: BuildContext) {
|
||||
val (execPath, licensePath) = NativeBinaryDownloader.getLauncher(context, OsFamily.LINUX, arch)
|
||||
copyFile(execPath, distBinDir.resolve(context.productProperties.baseFileName))
|
||||
copyFile(licensePath, targetPath.resolve("license/launcher-third-party-libraries.html"))
|
||||
}
|
||||
|
||||
val classPathJars = context.bootClassPathJarNames
|
||||
var classPath = $$"CLASS_PATH=\"$IDE_HOME/lib/$${classPathJars[0]}\""
|
||||
for (i in 1 until classPathJars.size) {
|
||||
classPath += $$"\nCLASS_PATH=\"$CLASS_PATH:$IDE_HOME/lib/$${classPathJars[i]}\""
|
||||
private fun generateLauncherScript(distBinDir: Path, arch: JvmArchitecture, nonCustomizableJvmArgs: List<String>, context: BuildContext, targetLibcImpl: LinuxLibcImpl) {
|
||||
val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions")
|
||||
|
||||
val defaultXmxParameter = try {
|
||||
Files.readAllLines(vmOptionsPath).firstOrNull { it.startsWith("-Xmx") }
|
||||
?: throw IllegalStateException("-Xmx was not found in '$vmOptionsPath'")
|
||||
}
|
||||
catch (e: NoSuchFileException) {
|
||||
throw IllegalStateException("File '$vmOptionsPath' should be already generated at this point", e)
|
||||
}
|
||||
|
||||
val classPathJars = context.bootClassPathJarNames
|
||||
var classPath = $$"CLASS_PATH=\"$IDE_HOME/lib/$${classPathJars[0]}\""
|
||||
for (i in 1 until classPathJars.size) {
|
||||
classPath += $$"\nCLASS_PATH=\"$CLASS_PATH:$IDE_HOME/lib/$${classPathJars[i]}\""
|
||||
}
|
||||
|
||||
val additionalJvmArguments = mutableListOf<String>()
|
||||
// https://youtrack.jetbrains.com/issue/IDEA-304440
|
||||
// "-Djdk.lang.Process.launchMechanism=vfork"
|
||||
if (targetLibcImpl == LinuxLibcImpl.MUSL) {
|
||||
additionalJvmArguments.add("-Djdk.lang.Process.launchMechanism=vfork")
|
||||
}
|
||||
additionalJvmArguments.addAll(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", additionalJvmArguments.joinToString(separator = " ")),
|
||||
Pair("ide_default_xmx", defaultXmxParameter.trim()),
|
||||
Pair("class_path", classPath),
|
||||
Pair("main_class_name", context.ideMainClassName),
|
||||
)
|
||||
|
||||
val template = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts/${EXECUTABLE_TEMPLATE_NAME}")
|
||||
copyScript(template, distBinDir.resolve("${context.productProperties.baseFileName}.sh"), additionalTemplateValues, context)
|
||||
}
|
||||
|
||||
val additionalJvmArguments = mutableListOf<String>()
|
||||
// https://youtrack.jetbrains.com/issue/IDEA-304440
|
||||
// "-Djdk.lang.Process.launchMechanism=vfork"
|
||||
if (targetLibcImpl == LinuxLibcImpl.MUSL) {
|
||||
additionalJvmArguments.add("-Djdk.lang.Process.launchMechanism=vfork")
|
||||
private fun copyScript(sourceFile: Path, targetFile: Path, additionalTemplateValues: List<Pair<String, String>>, context: BuildContext) {
|
||||
// Until CR (\r) will be removed from the repository checkout, we need to filter it out from Unix-style scripts
|
||||
// https://youtrack.jetbrains.com/issue/IJI-526/Force-git-to-use-LF-line-endings-in-working-copy-of-via-gitattri
|
||||
substituteTemplatePlaceholders(
|
||||
inputFile = sourceFile,
|
||||
outputFile = targetFile,
|
||||
placeholder = "__",
|
||||
values = listOf(
|
||||
Pair("product_full", context.applicationInfo.fullProductName),
|
||||
Pair("product_uc", context.productProperties.getEnvironmentVariableBaseName(context.applicationInfo)),
|
||||
Pair("product_vendor", context.applicationInfo.shortCompanyName),
|
||||
Pair("product_code", context.applicationInfo.productCode),
|
||||
Pair("script_name", "${context.productProperties.baseFileName}.sh"),
|
||||
) + additionalTemplateValues,
|
||||
mustUseAllPlaceholders = false,
|
||||
convertToUnixLineEndings = true,
|
||||
)
|
||||
}
|
||||
additionalJvmArguments.addAll(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", additionalJvmArguments.joinToString(separator = " ")),
|
||||
Pair("ide_default_xmx", defaultXmxParameter.trim()),
|
||||
Pair("class_path", classPath),
|
||||
Pair("main_class_name", context.ideMainClassName),
|
||||
)
|
||||
private fun writeLinuxVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions")
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dsun.tools.attach.tmp.only=true", "-Dawt.lock.fair=true")
|
||||
VmOptionsGenerator.writeVmOptions(vmOptionsPath, vmOptions, separator = "\n")
|
||||
return vmOptionsPath
|
||||
}
|
||||
|
||||
val template = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts/${EXECUTABLE_TEMPLATE_NAME}")
|
||||
copyScript(template, distBinDir.resolve("${context.productProperties.baseFileName}.sh"), additionalTemplateValues, context)
|
||||
}
|
||||
|
||||
private fun copyScript(sourceFile: Path, targetFile: Path, additionalTemplateValues: List<Pair<String, String>>, context: BuildContext) {
|
||||
// Until CR (\r) will be removed from the repository checkout, we need to filter it out from Unix-style scripts
|
||||
// https://youtrack.jetbrains.com/issue/IJI-526/Force-git-to-use-LF-line-endings-in-working-copy-of-via-gitattri
|
||||
substituteTemplatePlaceholders(
|
||||
inputFile = sourceFile,
|
||||
outputFile = targetFile,
|
||||
placeholder = "__",
|
||||
values = listOf(
|
||||
Pair("product_full", context.applicationInfo.fullProductName),
|
||||
Pair("product_uc", context.productProperties.getEnvironmentVariableBaseName(context.applicationInfo)),
|
||||
Pair("product_vendor", context.applicationInfo.shortCompanyName),
|
||||
Pair("product_code", context.applicationInfo.productCode),
|
||||
Pair("script_name", "${context.productProperties.baseFileName}.sh"),
|
||||
) + additionalTemplateValues,
|
||||
mustUseAllPlaceholders = false,
|
||||
convertToUnixLineEndings = true,
|
||||
)
|
||||
}
|
||||
|
||||
private fun writeLinuxVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions")
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dsun.tools.attach.tmp.only=true", "-Dawt.lock.fair=true")
|
||||
writeVmOptions(file = vmOptionsPath, vmOptions = vmOptions, separator = "\n")
|
||||
return vmOptionsPath
|
||||
}
|
||||
|
||||
|
||||
private fun suffix(arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl): String {
|
||||
return suffix(arch) + if (targetLibcImpl == LinuxLibcImpl.MUSL) "-musl" else ""
|
||||
private fun suffix(arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl): String =
|
||||
suffix(arch) + if (targetLibcImpl == LinuxLibcImpl.MUSL) "-musl" else ""
|
||||
}
|
||||
|
||||
+77
-102
@@ -123,7 +123,6 @@ class MacDistributionBuilder(
|
||||
}
|
||||
|
||||
private suspend fun doCopyExtraFiles(macDistDir: Path, arch: JvmArchitecture, copyDistFiles: Boolean) {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val platformProperties = mutableListOf(
|
||||
"\n#---------------------------------------------------------------------",
|
||||
"# macOS-specific system properties",
|
||||
@@ -185,36 +184,20 @@ class MacDistributionBuilder(
|
||||
val builder = this@MacDistributionBuilder
|
||||
|
||||
val productJson = generateProductJson(context, arch, withRuntime = true)
|
||||
val productJsonWithoutRuntime = generateProductJson(context = context, arch = arch, withRuntime = false)
|
||||
val productJsonWithoutRuntime = generateProductJson(context, arch, withRuntime = false)
|
||||
withContext(Dispatchers.IO) {
|
||||
macZipProductInfoJson.writeText(productJson)
|
||||
macZipWithoutRuntimeProductInfoJson.writeText(productJsonWithoutRuntime)
|
||||
}
|
||||
|
||||
buildMacZip(
|
||||
macDistributionBuilder = builder,
|
||||
targetFile = macZip,
|
||||
zipRoot = zipRoot,
|
||||
arch = arch,
|
||||
productJson = productJson,
|
||||
directories = directories,
|
||||
extraFiles = extraFiles,
|
||||
includeRuntime = true,
|
||||
compressionLevel = compressionLevel,
|
||||
builder, macZip, zipRoot, arch, productJson, directories, extraFiles, includeRuntime = true, compressionLevel
|
||||
)
|
||||
|
||||
if (customizer.buildArtifactWithoutRuntime) {
|
||||
val directoriesSansRuntime = directories.filterNot { it == runtimeDir }
|
||||
buildMacZip(
|
||||
macDistributionBuilder = builder,
|
||||
targetFile = macZipWithoutRuntime,
|
||||
zipRoot = zipRoot,
|
||||
arch = arch,
|
||||
productJson = productJsonWithoutRuntime,
|
||||
directories = directoriesSansRuntime,
|
||||
extraFiles = extraFiles,
|
||||
includeRuntime = false,
|
||||
compressionLevel = compressionLevel,
|
||||
builder, macZipWithoutRuntime, zipRoot, arch, productJsonWithoutRuntime, directoriesSansRuntime, extraFiles, includeRuntime = false, compressionLevel
|
||||
)
|
||||
}
|
||||
|
||||
@@ -228,13 +211,7 @@ class MacDistributionBuilder(
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildForArch(
|
||||
arch = arch,
|
||||
macZip = macZip,
|
||||
macZipProductInfoJson = macZipProductInfoJson,
|
||||
macZipWithoutRuntime = macZipWithoutRuntime,
|
||||
macZipWithoutRuntimeProductInfoJson = macZipWithoutRuntimeProductInfoJson,
|
||||
)
|
||||
buildForArch(arch, macZip, macZipProductInfoJson, macZipWithoutRuntime, macZipWithoutRuntimeProductInfoJson)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,8 +236,7 @@ class MacDistributionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeVmOptions(distBinDir: Path): Path =
|
||||
writeMacOsVmOptions(distBinDir, context)
|
||||
override fun writeVmOptions(distBinDir: Path): Path = writeMacOsVmOptions(distBinDir, context)
|
||||
|
||||
private suspend fun layoutMacApp(
|
||||
ideaPropertyContent: CharSequence,
|
||||
@@ -359,9 +335,9 @@ class MacDistributionBuilder(
|
||||
macZipWithoutRuntime: Path, macZipWithoutRuntimeProductInfoJson: Path,
|
||||
) {
|
||||
spanBuilder("build macOS artifacts for specific arch").setAttribute("arch", arch.name).use(Dispatchers.IO) {
|
||||
val notarize = System.getProperty("intellij.build.mac.notarize")?.toBoolean()
|
||||
?: !context.isStepSkipped(BuildOptions.MAC_NOTARIZE_STEP)
|
||||
&& !context.isStepSkipped(BuildOptions.MAC_SIGN_STEP)
|
||||
val notarize =
|
||||
(System.getProperty("intellij.build.mac.notarize")?.toBoolean() ?: !context.isStepSkipped(BuildOptions.MAC_NOTARIZE_STEP)) &&
|
||||
!context.isStepSkipped(BuildOptions.MAC_SIGN_STEP)
|
||||
buildForArch(arch, macZip, macZipProductInfoJson, macZipWithoutRuntime, macZipWithoutRuntimeProductInfoJson, notarize)
|
||||
Files.deleteIfExists(macZip)
|
||||
}
|
||||
@@ -372,7 +348,7 @@ class MacDistributionBuilder(
|
||||
macZip: Path, macZipProductInfoJson: Path,
|
||||
macZipWithoutRuntime: Path, macZipWithoutRuntimeProductInfoJson: Path,
|
||||
notarize: Boolean,
|
||||
) {
|
||||
) {
|
||||
val archStr = arch.name
|
||||
coroutineScope {
|
||||
val taskId = "${BuildOptions.MAC_ARTIFACTS_STEP}_jre_${archStr}"
|
||||
@@ -412,10 +388,10 @@ class MacDistributionBuilder(
|
||||
override fun isRuntimeBundled(file: Path): Boolean = !file.name.contains(NO_RUNTIME_SUFFIX)
|
||||
|
||||
private suspend fun generateProductJson(context: BuildContext, arch: JvmArchitecture, withRuntime: Boolean): String {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch = arch, os = OsFamily.MACOS, ideContext = context) {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.MACOS, context) {
|
||||
"../bin/${it.productProperties.baseFileName}.vmoptions"
|
||||
}
|
||||
val qodanaCustomLaunchData = generateQodanaLaunchData(ideContext = context, arch = arch, os = OsFamily.MACOS)
|
||||
val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.MACOS)
|
||||
return generateProductInfoJson(
|
||||
relativePathToBin = "../bin",
|
||||
builtinModules = context.builtinModule,
|
||||
@@ -432,7 +408,7 @@ class MacDistributionBuilder(
|
||||
customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData)
|
||||
)
|
||||
),
|
||||
context = context
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
@@ -520,9 +496,9 @@ class MacDistributionBuilder(
|
||||
|
||||
private fun writeMacOsVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val executable = context.productProperties.baseFileName
|
||||
val fileVmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dapple.awt.application.appearance=system")
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dapple.awt.application.appearance=system")
|
||||
val vmOptionsPath = distBinDir.resolve("${executable}.vmoptions")
|
||||
writeVmOptions(file = vmOptionsPath, vmOptions = fileVmOptions, separator = "\n")
|
||||
VmOptionsGenerator.writeVmOptions(vmOptionsPath, vmOptions, separator = "\n")
|
||||
return vmOptionsPath
|
||||
}
|
||||
|
||||
@@ -591,9 +567,8 @@ class MacDistributionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMacZipRoot(customizer: MacDistributionCustomizer, context: BuildContext): String {
|
||||
return "${customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)}/Contents"
|
||||
}
|
||||
private fun getMacZipRoot(customizer: MacDistributionCustomizer, context: BuildContext): String =
|
||||
"${customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)}/Contents"
|
||||
|
||||
private val publishSitArchive: Boolean
|
||||
get() = !context.isStepSkipped(BuildOptions.MAC_SIT_PUBLICATION_STEP)
|
||||
@@ -615,7 +590,7 @@ class MacDistributionBuilder(
|
||||
notarize(sitFile, context)
|
||||
}
|
||||
|
||||
buildDmg(sitFile = sitFile, productInfoJson = productInfoJson, dmgName = "${baseName}.dmg", staple = notarize)
|
||||
buildDmg(sitFile, productInfoJson, "${baseName}.dmg", notarize)
|
||||
|
||||
if (publishSitArchive) {
|
||||
context.notifyArtifactBuilt(sitFile)
|
||||
@@ -623,7 +598,7 @@ class MacDistributionBuilder(
|
||||
}
|
||||
|
||||
val zipRoot = getMacZipRoot(customizer, context)
|
||||
checkExecutablePermissions(distribution = sitFile, root = zipRoot, includeRuntime = isRuntimeBundled, arch = arch, libc = targetLibcImpl)
|
||||
checkExecutablePermissions(sitFile, zipRoot, isRuntimeBundled, arch, targetLibcImpl)
|
||||
|
||||
if (isRuntimeBundled) {
|
||||
generateIntegrityManifest(sitFile, zipRoot, arch, context)
|
||||
@@ -637,7 +612,7 @@ class MacDistributionBuilder(
|
||||
NioFiles.deleteRecursively(tempDir)
|
||||
NioFiles.createDirectories(tempDir)
|
||||
NioFiles.createDirectories(context.paths.artifactDir)
|
||||
val entrypoint = prepareDmgBuildScripts(tempDir = tempDir, staple = staple, customizer = customizer, context = context)
|
||||
val entrypoint = prepareDmgBuildScripts(tempDir, staple, customizer, context)
|
||||
if (!SystemInfoRt.isMac) {
|
||||
it.addEvent(".dmg can be built only on macOS")
|
||||
if (publishSitArchive) {
|
||||
@@ -661,76 +636,76 @@ class MacDistributionBuilder(
|
||||
NioFiles.deleteRecursively(tempDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareDmgBuildScripts(tempDir: Path, staple: Boolean, customizer: MacDistributionCustomizer, context: BuildContext): Path {
|
||||
NioFiles.deleteRecursively(tempDir)
|
||||
Files.createDirectories(tempDir)
|
||||
val dmgImageCopy = tempDir.resolve("${context.fullBuildNumber}.png")
|
||||
Files.copy(Path.of((if (context.applicationInfo.isEAP) customizer.dmgImagePathForEAP else null) ?: customizer.dmgImagePath), dmgImageCopy)
|
||||
val scriptsDir = context.paths.communityHomeDir.resolve("platform/build-scripts/tools/mac/scripts")
|
||||
Files.copy(scriptsDir.resolve("makedmg.sh"), tempDir.resolve("makedmg.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
NioFiles.setExecutable(tempDir.resolve("makedmg.sh"))
|
||||
Files.copy(scriptsDir.resolve("makedmg.py"), tempDir.resolve("makedmg.py"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
Files.copy(scriptsDir.resolve("staple.sh"), tempDir.resolve("staple.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
val entrypoint = tempDir.resolve("build.sh")
|
||||
Files.writeString(
|
||||
entrypoint,
|
||||
Files.readString(scriptsDir.resolve("build-template.sh"))
|
||||
.resolveTemplateVar("staple", "$staple")
|
||||
.resolveTemplateVar("appName", context.fullBuildNumber)
|
||||
.resolveTemplateVar("contentSigned", "${context.isMacCodeSignEnabled}")
|
||||
.resolveTemplateVar("buildDateInSeconds", "${context.options.buildDateInSeconds}")
|
||||
)
|
||||
NioFiles.setExecutable(entrypoint)
|
||||
return entrypoint
|
||||
}
|
||||
private fun prepareDmgBuildScripts(tempDir: Path, staple: Boolean, customizer: MacDistributionCustomizer, context: BuildContext): Path {
|
||||
NioFiles.deleteRecursively(tempDir)
|
||||
Files.createDirectories(tempDir)
|
||||
val dmgImageCopy = tempDir.resolve("${context.fullBuildNumber}.png")
|
||||
Files.copy(Path.of((if (context.applicationInfo.isEAP) customizer.dmgImagePathForEAP else null) ?: customizer.dmgImagePath), dmgImageCopy)
|
||||
val scriptsDir = context.paths.communityHomeDir.resolve("platform/build-scripts/tools/mac/scripts")
|
||||
Files.copy(scriptsDir.resolve("makedmg.sh"), tempDir.resolve("makedmg.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
NioFiles.setExecutable(tempDir.resolve("makedmg.sh"))
|
||||
Files.copy(scriptsDir.resolve("makedmg.py"), tempDir.resolve("makedmg.py"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
Files.copy(scriptsDir.resolve("staple.sh"), tempDir.resolve("staple.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
val entrypoint = tempDir.resolve("build.sh")
|
||||
Files.writeString(
|
||||
entrypoint,
|
||||
Files.readString(scriptsDir.resolve("build-template.sh"))
|
||||
.resolveTemplateVar("staple", "$staple")
|
||||
.resolveTemplateVar("appName", context.fullBuildNumber)
|
||||
.resolveTemplateVar("contentSigned", "${context.isMacCodeSignEnabled}")
|
||||
.resolveTemplateVar("buildDateInSeconds", "${context.options.buildDateInSeconds}")
|
||||
)
|
||||
NioFiles.setExecutable(entrypoint)
|
||||
return entrypoint
|
||||
}
|
||||
|
||||
|
||||
private fun String.resolveTemplateVar(variable: String, value: String): String {
|
||||
val reference = "%$variable%"
|
||||
check(contains(reference)) { "No $reference is found in:\n'$this'" }
|
||||
return replace(reference, value)
|
||||
}
|
||||
private fun String.resolveTemplateVar(variable: String, value: String): String {
|
||||
val reference = "%$variable%"
|
||||
check(contains(reference)) { "No $reference is found in:\n'$this'" }
|
||||
return replace(reference, value)
|
||||
}
|
||||
|
||||
private fun publishDmgBuildScripts(entrypoint: Path, tempDir: Path, context: BuildContext) {
|
||||
val artifactDir = context.paths.artifactDir.resolve("macos-dmg-build")
|
||||
artifactDir.createDirectories()
|
||||
synchronized("$artifactDir".intern()) {
|
||||
tempDir.listDirectoryEntries().forEach {
|
||||
Files.copy(it, artifactDir.resolve(it.name), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
}
|
||||
val message = """
|
||||
private fun publishDmgBuildScripts(entrypoint: Path, tempDir: Path, context: BuildContext) {
|
||||
val artifactDir = context.paths.artifactDir.resolve("macos-dmg-build")
|
||||
artifactDir.createDirectories()
|
||||
synchronized("$artifactDir".intern()) {
|
||||
tempDir.listDirectoryEntries().forEach {
|
||||
Files.copy(it, artifactDir.resolve(it.name), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES)
|
||||
}
|
||||
val message = """
|
||||
To build .dmg(s):
|
||||
1. transfer .sit(s) to macOS host;
|
||||
2. transfer ${artifactDir.name}/ content to the same folder;
|
||||
3. execute ${entrypoint.name} from Terminal.
|
||||
.dmg(s) will be built in the same folder.
|
||||
""".trimIndent()
|
||||
artifactDir.resolve("README.txt").writeText(message)
|
||||
context.messages.info(message)
|
||||
context.notifyArtifactBuilt(artifactDir)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun generateIntegrityManifest(sitFile: Path, sitRoot: String, arch: JvmArchitecture, context: BuildContext) {
|
||||
if (context.options.buildStepsToSkip.contains(BuildOptions.REPAIR_UTILITY_BUNDLE_STEP)) {
|
||||
return
|
||||
}
|
||||
|
||||
val tempSit = Files.createTempDirectory(context.paths.tempDir, "sit-")
|
||||
try {
|
||||
spanBuilder("extracting ${sitFile.name}").use(Dispatchers.IO) {
|
||||
Decompressor.Zip(sitFile)
|
||||
.withZipExtensions()
|
||||
.extract(tempSit)
|
||||
artifactDir.resolve("README.txt").writeText(message)
|
||||
context.messages.info(message)
|
||||
context.notifyArtifactBuilt(artifactDir)
|
||||
}
|
||||
RepairUtilityBuilder.generateManifest(context, tempSit.resolve(sitRoot), OsFamily.MACOS, arch)
|
||||
}
|
||||
finally {
|
||||
withContext(Dispatchers.IO + NonCancellable) {
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
tempSit.deleteRecursively()
|
||||
|
||||
private suspend fun generateIntegrityManifest(sitFile: Path, sitRoot: String, arch: JvmArchitecture, context: BuildContext) {
|
||||
if (context.options.buildStepsToSkip.contains(BuildOptions.REPAIR_UTILITY_BUNDLE_STEP)) {
|
||||
return
|
||||
}
|
||||
|
||||
val tempSit = Files.createTempDirectory(context.paths.tempDir, "sit-")
|
||||
try {
|
||||
spanBuilder("extracting ${sitFile.name}").use(Dispatchers.IO) {
|
||||
Decompressor.Zip(sitFile)
|
||||
.withZipExtensions()
|
||||
.extract(tempSit)
|
||||
}
|
||||
RepairUtilityBuilder.generateManifest(context, tempSit.resolve(sitRoot), OsFamily.MACOS, arch)
|
||||
}
|
||||
finally {
|
||||
withContext(Dispatchers.IO + NonCancellable) {
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
tempSit.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +635,6 @@ internal class TestingTasksImpl(context: CompilationContext, private val options
|
||||
index = 0,
|
||||
elements = VmOptionsGenerator.generate(
|
||||
isEAP = true,
|
||||
bundledRuntime = context.bundledRuntime,
|
||||
customVmMemoryOptions = if (customMemoryOptions == null) mapOf("-Xms" to "750m", "-Xmx" to "1024m") else emptyMap(),
|
||||
additionalVmOptions = customMemoryOptions ?: emptyList(),
|
||||
platformPrefix = options.platformPrefix,
|
||||
|
||||
+48
-71
@@ -1,7 +1,6 @@
|
||||
// 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.ReviseWhenPortedToJDK
|
||||
import com.intellij.platform.ijent.community.buildConstants.MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS
|
||||
import com.intellij.platform.ijent.community.buildConstants.isMultiRoutingFileSystemEnabledForProduct
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
@@ -10,51 +9,46 @@ import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.name
|
||||
|
||||
private const val DEFAULT_MIN_HEAP = "128m"
|
||||
private const val DEFAULT_MAX_HEAP = "2048m"
|
||||
|
||||
private val COMMON_VM_OPTIONS: List<String> = listOf(
|
||||
"-XX:JbrShrinkingGcMaxHeapFreeRatio=40", // IJPL-181469. Used in a couple with AppIdleMemoryCleaner.runGc()
|
||||
"-XX:ReservedCodeCacheSize=512m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-XX:-OmitStackTraceInFastThrow",
|
||||
"-XX:CICompilerCount=2",
|
||||
"-XX:+IgnoreUnrecognizedVMOptions", // allowing the JVM to start even with outdated options stuck in user configs
|
||||
"-ea",
|
||||
"-Dsun.io.useCanonCaches=false",
|
||||
"-Dsun.java2d.metal=true",
|
||||
"-Djbr.catch.SIGABRT=true",
|
||||
"-Djdk.http.auth.tunneling.disabledSchemes=\"\"",
|
||||
"-Djdk.attach.allowAttachSelf=true",
|
||||
"-Djdk.module.illegalAccess.silent=true",
|
||||
"-Djdk.nio.maxCachedBufferSize=2097152",
|
||||
"-Djava.util.zip.use.nio.for.zip.file.access=true", // IJPL-149160
|
||||
"-Dkotlinx.coroutines.debug=off",
|
||||
)
|
||||
|
||||
/** duplicates RepositoryHelper.CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY */
|
||||
private const val CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY = "intellij.plugins.custom.built.in.repository.url"
|
||||
|
||||
object VmOptionsGenerator {
|
||||
private const val DEFAULT_MIN_HEAP = "128m"
|
||||
private const val DEFAULT_MAX_HEAP = "2048m"
|
||||
|
||||
private val COMMON_VM_OPTIONS: List<String> = listOf(
|
||||
"-XX:JbrShrinkingGcMaxHeapFreeRatio=40", // IJPL-181469. Used in a couple with AppIdleMemoryCleaner.runGc()
|
||||
"-XX:ReservedCodeCacheSize=512m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-XX:-OmitStackTraceInFastThrow",
|
||||
"-XX:CICompilerCount=2",
|
||||
"-XX:+IgnoreUnrecognizedVMOptions", // allowing the JVM to start even with outdated options stuck in user configs
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:TieredOldPercentage=100000",
|
||||
"-ea",
|
||||
"-Dsun.io.useCanonCaches=false",
|
||||
"-Dsun.java2d.metal=true",
|
||||
"-Djbr.catch.SIGABRT=true",
|
||||
"-Djdk.http.auth.tunneling.disabledSchemes=\"\"",
|
||||
"-Djdk.attach.allowAttachSelf=true",
|
||||
"-Djdk.module.illegalAccess.silent=true",
|
||||
"-Djdk.nio.maxCachedBufferSize=2097152",
|
||||
"-Djava.util.zip.use.nio.for.zip.file.access=true", // IJPL-149160
|
||||
"-Dkotlinx.coroutines.debug=off",
|
||||
)
|
||||
|
||||
/** duplicates RepositoryHelper.CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY */
|
||||
private const val CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY = "intellij.plugins.custom.built.in.repository.url"
|
||||
|
||||
fun generate(context: BuildContext): List<String> = generate(
|
||||
context.applicationInfo.isEAP,
|
||||
context.bundledRuntime,
|
||||
context.productProperties.customJvmMemoryOptions,
|
||||
context.productProperties.additionalVmOptions.let {
|
||||
val customPluginRepositoryUrl = computeCustomPluginRepositoryUrl(context)
|
||||
if (customPluginRepositoryUrl == null) {
|
||||
it
|
||||
}
|
||||
else {
|
||||
it + "-D${CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY}=${customPluginRepositoryUrl}"
|
||||
}
|
||||
val url = computeCustomPluginRepositoryUrl(context)
|
||||
if (url == null) it else it + "-D${CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY}=${url}"
|
||||
},
|
||||
context.productProperties.platformPrefix,
|
||||
)
|
||||
|
||||
internal fun generate(
|
||||
isEAP: Boolean,
|
||||
bundledRuntime: BundledRuntime,
|
||||
customVmMemoryOptions: Map<String, String>,
|
||||
additionalVmOptions: List<String>,
|
||||
platformPrefix: String?,
|
||||
@@ -63,12 +57,12 @@ object VmOptionsGenerator {
|
||||
|
||||
val memory = LinkedHashMap<String, String>(customVmMemoryOptions)
|
||||
memory.putIfAbsent("-Xms", DEFAULT_MIN_HEAP)
|
||||
memory.putIfAbsent("-Xmx", DEFAULT_MAX_HEAP) // must be the same as [com.intellij.diagnostic.MemorySizeConfigurator.DEFAULT_XMX]
|
||||
memory.putIfAbsent("-Xmx", DEFAULT_MAX_HEAP)
|
||||
for ((k, v) in memory) {
|
||||
result.add(k + v)
|
||||
result += k + v
|
||||
}
|
||||
|
||||
result.addAll(COMMON_VM_OPTIONS)
|
||||
result += COMMON_VM_OPTIONS
|
||||
|
||||
if (isMultiRoutingFileSystemEnabledForProduct(platformPrefix)) {
|
||||
result.addAll(MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS)
|
||||
@@ -76,48 +70,31 @@ object VmOptionsGenerator {
|
||||
|
||||
result += additionalVmOptions
|
||||
|
||||
var index = result.indexOf("-ea")
|
||||
if (index < 0) {
|
||||
index = result.indexOfFirst { it.startsWith("-D") }
|
||||
}
|
||||
if (index < 0) {
|
||||
index = result.size
|
||||
}
|
||||
|
||||
result.addAll(
|
||||
index,
|
||||
@ReviseWhenPortedToJDK("21", description = "Merge into `COMMON_VM_OPTIONS`")
|
||||
if (bundledRuntime.build.startsWith("17.")) {
|
||||
listOf(
|
||||
"-XX:CompileCommand=exclude,com/intellij/openapi/vfs/impl/FilePartNodeRoot,trieDescend", // temporary workaround for crashes in С2 (JBR-4509)
|
||||
"-XX:SoftRefLRUPolicyMSPerMB=50",
|
||||
)
|
||||
}
|
||||
else listOf("-XX:+UnlockDiagnosticVMOptions", "-XX:TieredOldPercentage=100000")
|
||||
)
|
||||
|
||||
if (isEAP) {
|
||||
var index = result.indexOf("-ea")
|
||||
if (index < 0) index = result.indexOfFirst { it.startsWith("-D") }
|
||||
if (index < 0) index = result.size
|
||||
result.add(index, "-XX:MaxJavaStackTraceDepth=10000") // must be consistent with `ConfigImportHelper#updateVMOptions`
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeCustomPluginRepositoryUrl(context: BuildContext): String? {
|
||||
val artifactsServer = context.proprietaryBuildTools.artifactsServer
|
||||
if (artifactsServer != null && context.productProperties.productLayout.prepareCustomPluginRepositoryForPublishedPlugins) {
|
||||
val builtinPluginsRepoUrl = artifactsServer.urlToArtifact(context, "${context.nonBundledPlugins.name}/plugins.xml")
|
||||
if (builtinPluginsRepoUrl != null) {
|
||||
if (builtinPluginsRepoUrl.startsWith("http:")) {
|
||||
context.messages.logErrorAndThrow("Insecure artifact server: ${builtinPluginsRepoUrl}")
|
||||
private fun computeCustomPluginRepositoryUrl(context: BuildContext): String? {
|
||||
val artifactsServer = context.proprietaryBuildTools.artifactsServer
|
||||
if (artifactsServer != null && context.productProperties.productLayout.prepareCustomPluginRepositoryForPublishedPlugins) {
|
||||
val builtinPluginsRepoUrl = artifactsServer.urlToArtifact(context, "${context.nonBundledPlugins.name}/plugins.xml")
|
||||
if (builtinPluginsRepoUrl != null) {
|
||||
if (builtinPluginsRepoUrl.startsWith("http:")) {
|
||||
context.messages.logErrorAndThrow("Insecure artifact server: ${builtinPluginsRepoUrl}")
|
||||
}
|
||||
return builtinPluginsRepoUrl
|
||||
}
|
||||
return builtinPluginsRepoUrl
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun writeVmOptions(file: Path, vmOptions: Sequence<String>, separator: String) {
|
||||
Files.writeString(file, vmOptions.joinToString(separator, postfix = separator), StandardCharsets.US_ASCII)
|
||||
internal fun writeVmOptions(file: Path, vmOptions: Sequence<String>, separator: String) {
|
||||
Files.writeString(file, vmOptions.joinToString(separator, postfix = separator), StandardCharsets.US_ASCII)
|
||||
}
|
||||
}
|
||||
|
||||
+41
-56
@@ -89,7 +89,7 @@ internal class WindowsDistributionBuilder(
|
||||
copyFileToDir(NativeBinaryDownloader.getRestarter(context, OsFamily.WINDOWS, arch), distBinDir)
|
||||
|
||||
generateBuildTxt(context, targetPath)
|
||||
copyDistFiles(context = context, newDir = targetPath, os = OsFamily.WINDOWS, arch = arch, libcImpl = WindowsLibcImpl.DEFAULT)
|
||||
copyDistFiles(context, targetPath, OsFamily.WINDOWS, arch, WindowsLibcImpl.DEFAULT)
|
||||
|
||||
Files.writeString(distBinDir.resolve(PROPERTIES_FILE_NAME), StringUtilRt.convertLineSeparators(ideaProperties!!, "\r\n"))
|
||||
|
||||
@@ -101,11 +101,11 @@ internal class WindowsDistributionBuilder(
|
||||
|
||||
writeVmOptions(distBinDir)
|
||||
|
||||
buildWinLauncher(winDistPath = targetPath, arch = arch, context = context, copyLicense = true)
|
||||
buildWinLauncher(targetPath, arch, context, copyLicense = true)
|
||||
|
||||
createFrontendContextForLaunchers(context)?.let { clientContext ->
|
||||
writeWindowsVmOptions(distBinDir, clientContext)
|
||||
buildWinLauncher(winDistPath = targetPath, arch = arch, context = clientContext, copyLicense = false)
|
||||
buildWinLauncher(targetPath, arch, clientContext, copyLicense = false)
|
||||
}
|
||||
|
||||
customizer.copyAdditionalFiles(context, targetPath, arch)
|
||||
@@ -133,7 +133,6 @@ internal class WindowsDistributionBuilder(
|
||||
copyFilesForOsDistribution(osAndArchSpecificDistPath, arch)
|
||||
val runtimeDir = context.bundledRuntime.extract(OsFamily.WINDOWS, arch, WindowsLibcImpl.DEFAULT)
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val vcRtDll = runtimeDir.resolve("jbr/bin/msvcp140.dll")
|
||||
check(Files.exists(vcRtDll)) {
|
||||
"VS C++ Runtime DLL (${vcRtDll.fileName}) not found in ${vcRtDll.parent}.\n" +
|
||||
@@ -151,14 +150,7 @@ internal class WindowsDistributionBuilder(
|
||||
if (customizer.buildZipArchiveWithBundledJre && !context.isStepSkipped(BuildOptions.WINDOWS_ZIP_STEP)) {
|
||||
val zipNameSuffix = suffix(arch) + customizer.zipArchiveWithBundledJreSuffix
|
||||
launch(Dispatchers.IO + CoroutineName("build Windows ${zipNameSuffix}.zip distribution")) {
|
||||
zipWithJbrPath = createBuildWinZipTask(
|
||||
runtimeDir = runtimeDir,
|
||||
zipNameSuffix = zipNameSuffix,
|
||||
winDistPath = osAndArchSpecificDistPath,
|
||||
arch = arch,
|
||||
customizer = customizer,
|
||||
context = context,
|
||||
)
|
||||
zipWithJbrPath = createBuildWinZipTask(runtimeDir, zipNameSuffix, osAndArchSpecificDistPath, arch, customizer, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,14 +168,7 @@ internal class WindowsDistributionBuilder(
|
||||
validateProductJson(jsonText = productJsonFile.readText(), installationDirectories, installationArchives = emptyList(), context)
|
||||
launch(Dispatchers.IO + CoroutineName("build Windows ${arch.dirName} installer")) {
|
||||
exePath = buildNsisInstaller(
|
||||
winDistPath = osAndArchSpecificDistPath,
|
||||
productInfoJsonFile = productJsonFile,
|
||||
additionalDirectoryToInclude = productJsonDir,
|
||||
suffix = suffix(arch),
|
||||
customizer = customizer,
|
||||
runtimeDir = runtimeDir,
|
||||
context = context,
|
||||
arch = arch,
|
||||
osAndArchSpecificDistPath, productJsonFile, productJsonDir, suffix(arch), customizer, runtimeDir, context, arch
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -222,7 +207,7 @@ internal class WindowsDistributionBuilder(
|
||||
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() }
|
||||
|
||||
val expectedScriptNames = listOf("executable-template.bat", "format.bat", "inspect.bat", @Suppress("SpellCheckingInspection") "ltedit.bat")
|
||||
val expectedScriptNames = listOf("executable-template.bat", "format.bat", "inspect.bat", "ltedit.bat")
|
||||
check(actualScriptNames == expectedScriptNames) {
|
||||
"Expected script names '${expectedScriptNames.joinToString(separator = " ")}', " +
|
||||
"but got '${actualScriptNames.joinToString(separator = " ")}' " +
|
||||
@@ -247,7 +232,7 @@ internal class WindowsDistributionBuilder(
|
||||
)
|
||||
|
||||
val inspectScript = context.productProperties.inspectCommandName
|
||||
for (fileName in listOf("format.bat", "inspect.bat", @Suppress("SpellCheckingInspection") "ltedit.bat")) {
|
||||
for (fileName in listOf("format.bat", "inspect.bat", "ltedit.bat")) {
|
||||
substituteTemplatePlaceholders(
|
||||
inputFile = winScripts.resolve(fileName),
|
||||
outputFile = distBinDir.resolve(fileName),
|
||||
@@ -479,40 +464,40 @@ internal class WindowsDistributionBuilder(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeWindowsVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val vmOptionsFile = distBinDir.resolve("${context.productProperties.baseFileName}64.exe.vmoptions")
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence()
|
||||
writeVmOptions(file = vmOptionsFile, vmOptions = vmOptions, separator = "\r\n")
|
||||
return vmOptionsFile
|
||||
}
|
||||
|
||||
private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, context: BuildContext, withRuntime: Boolean = true): Path {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.WINDOWS, context) {
|
||||
"bin/${it.productProperties.baseFileName}64.exe.vmoptions"
|
||||
private fun writeWindowsVmOptions(distBinDir: Path, context: BuildContext): Path {
|
||||
val vmOptionsFile = distBinDir.resolve("${context.productProperties.baseFileName}64.exe.vmoptions")
|
||||
val vmOptions = VmOptionsGenerator.generate(context).asSequence()
|
||||
VmOptionsGenerator.writeVmOptions(vmOptionsFile, vmOptions, separator = "\r\n")
|
||||
return vmOptionsFile
|
||||
}
|
||||
val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.WINDOWS)
|
||||
val json = generateProductInfoJson(
|
||||
relativePathToBin = "bin",
|
||||
builtinModules = context.builtinModule,
|
||||
launch = listOf(
|
||||
ProductInfoLaunchData.create(
|
||||
os = OsFamily.WINDOWS.osName,
|
||||
arch = arch.dirName,
|
||||
launcherPath = "bin/${context.productProperties.baseFileName}64.exe",
|
||||
javaExecutablePath = if (withRuntime) "jbr/bin/java.exe" else null,
|
||||
vmOptionsFilePath = "bin/${context.productProperties.baseFileName}64.exe.vmoptions",
|
||||
bootClassPathJarNames = context.bootClassPathJarNames,
|
||||
additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch),
|
||||
mainClass = context.ideMainClassName,
|
||||
customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData),
|
||||
)
|
||||
),
|
||||
context)
|
||||
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")
|
||||
private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, context: BuildContext, withRuntime: Boolean = true): Path {
|
||||
val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.WINDOWS, context) {
|
||||
"bin/${it.productProperties.baseFileName}64.exe.vmoptions"
|
||||
}
|
||||
val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.WINDOWS)
|
||||
val json = generateProductInfoJson(
|
||||
relativePathToBin = "bin",
|
||||
builtinModules = context.builtinModule,
|
||||
launch = listOf(
|
||||
ProductInfoLaunchData.create(
|
||||
os = OsFamily.WINDOWS.osName,
|
||||
arch = arch.dirName,
|
||||
launcherPath = "bin/${context.productProperties.baseFileName}64.exe",
|
||||
javaExecutablePath = if (withRuntime) "jbr/bin/java.exe" else null,
|
||||
vmOptionsFilePath = "bin/${context.productProperties.baseFileName}64.exe.vmoptions",
|
||||
bootClassPathJarNames = context.bootClassPathJarNames,
|
||||
additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch),
|
||||
mainClass = context.ideMainClassName,
|
||||
customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData),
|
||||
)
|
||||
),
|
||||
context)
|
||||
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")
|
||||
}
|
||||
|
||||
+11
-15
@@ -120,18 +120,16 @@ internal suspend fun generateEmbeddedFrontendLaunchData(
|
||||
os: OsFamily,
|
||||
ideContext: BuildContext,
|
||||
vmOptionsFilePath: (BuildContext) -> String
|
||||
): CustomCommandLaunchData? {
|
||||
return createFrontendContextForLaunchers(ideContext)?.let { clientContext ->
|
||||
CustomCommandLaunchData(
|
||||
commands = listOf("thinClient", "thinClient-headless", "installFrontendPlugins"),
|
||||
vmOptionsFilePath = vmOptionsFilePath(clientContext),
|
||||
bootClassPathJarNames = clientContext.bootClassPathJarNames,
|
||||
additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS,
|
||||
mainClass = clientContext.ideMainClassName,
|
||||
envVarBaseName = "JETBRAINS_CLIENT",
|
||||
dataDirectoryName = clientContext.systemSelector,
|
||||
)
|
||||
}
|
||||
): CustomCommandLaunchData? = createFrontendContextForLaunchers(ideContext)?.let { clientContext ->
|
||||
CustomCommandLaunchData(
|
||||
commands = listOf("thinClient", "thinClient-headless", "installFrontendPlugins"),
|
||||
vmOptionsFilePath = vmOptionsFilePath(clientContext),
|
||||
bootClassPathJarNames = clientContext.bootClassPathJarNames,
|
||||
additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS,
|
||||
mainClass = clientContext.ideMainClassName,
|
||||
envVarBaseName = "JETBRAINS_CLIENT",
|
||||
dataDirectoryName = clientContext.systemSelector,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,6 +137,4 @@ internal suspend fun generateEmbeddedFrontendLaunchData(
|
||||
*
|
||||
* E.g., if [this] is `installer.tag.gz`, returned Path will be `installer.tag.gz.product-info.json`.
|
||||
*/
|
||||
internal fun Path.resolveProductInfoJsonSibling(): Path {
|
||||
return resolveSibling("${this.fileName}.$PRODUCT_INFO_FILE_NAME")
|
||||
}
|
||||
internal fun Path.resolveProductInfoJsonSibling(): Path = resolveSibling("${this.fileName}.$PRODUCT_INFO_FILE_NAME")
|
||||
|
||||
@@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@@ -43,7 +43,7 @@ class ProductInfoData private constructor(
|
||||
val flavors: List<ProductFlavorData> = emptyList(),
|
||||
|
||||
// not used by the launcher; must be at the end
|
||||
@Internal
|
||||
@ApiStatus.Internal
|
||||
val layout: List<ProductInfoLayoutItem> = emptyList(),
|
||||
) {
|
||||
companion object {
|
||||
@@ -52,7 +52,7 @@ class ProductInfoData private constructor(
|
||||
* Some properties that are nullable in the primary constructor are deliberately marked as not-null in this function to state that they
|
||||
* are required in the current version, and internal clients may rely on their presence.
|
||||
*/
|
||||
@Internal
|
||||
@ApiStatus.Internal
|
||||
@JvmStatic
|
||||
fun create(
|
||||
name: String,
|
||||
@@ -72,32 +72,15 @@ class ProductInfoData private constructor(
|
||||
fileExtensions: List<String>,
|
||||
flavors: List<ProductFlavorData>,
|
||||
layout: List<ProductInfoLayoutItem>,
|
||||
): ProductInfoData {
|
||||
return ProductInfoData(
|
||||
name = name,
|
||||
version = version,
|
||||
versionSuffix = versionSuffix,
|
||||
buildNumber = buildNumber,
|
||||
productCode = productCode,
|
||||
envVarBaseName = envVarBaseName,
|
||||
dataDirectoryName = dataDirectoryName,
|
||||
svgIconPath = svgIconPath,
|
||||
productVendor = productVendor,
|
||||
majorVersionReleaseDate = majorVersionReleaseDate,
|
||||
launch = launch,
|
||||
customProperties = customProperties,
|
||||
bundledPlugins = bundledPlugins,
|
||||
modules = modules,
|
||||
fileExtensions = fileExtensions,
|
||||
flavors = flavors,
|
||||
layout = layout
|
||||
)
|
||||
}
|
||||
): ProductInfoData = ProductInfoData(
|
||||
name, version, versionSuffix, buildNumber, productCode, envVarBaseName, dataDirectoryName, svgIconPath, productVendor,
|
||||
majorVersionReleaseDate, launch, customProperties, bundledPlugins, modules, fileExtensions, flavors, layout
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class ProductFlavorData @Internal constructor(@JvmField val id: String)
|
||||
class ProductFlavorData @ApiStatus.Internal constructor(@JvmField val id: String)
|
||||
|
||||
/**
|
||||
* Describes 'launch' section in [product-info.json][ProductInfoData] file.
|
||||
@@ -121,7 +104,7 @@ class ProductInfoLaunchData private constructor(
|
||||
* Some properties that are nullable in the primary constructor are deliberately marked as not-null in this function to state that they
|
||||
* are required in the current version, and internal clients may rely on their presence.
|
||||
*/
|
||||
@Internal
|
||||
@ApiStatus.Internal
|
||||
@JvmStatic
|
||||
fun create(
|
||||
os: String,
|
||||
@@ -134,25 +117,16 @@ class ProductInfoLaunchData private constructor(
|
||||
mainClass: String,
|
||||
startupWmClass: String? = null,
|
||||
customCommands: List<CustomCommandLaunchData> = emptyList(),
|
||||
): ProductInfoLaunchData {
|
||||
return ProductInfoLaunchData(
|
||||
os = os,
|
||||
arch = arch,
|
||||
launcherPath = launcherPath,
|
||||
javaExecutablePath = javaExecutablePath,
|
||||
vmOptionsFilePath = vmOptionsFilePath,
|
||||
startupWmClass = startupWmClass,
|
||||
bootClassPathJarNames = bootClassPathJarNames,
|
||||
additionalJvmArguments = additionalJvmArguments,
|
||||
mainClass = mainClass,
|
||||
customCommands = customCommands
|
||||
)
|
||||
}
|
||||
): ProductInfoLaunchData = ProductInfoLaunchData(
|
||||
os, arch, launcherPath, javaExecutablePath, vmOptionsFilePath, startupWmClass, bootClassPathJarNames, additionalJvmArguments,
|
||||
mainClass, customCommands
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class CustomCommandLaunchData @Internal constructor(
|
||||
@Suppress("unused")
|
||||
class CustomCommandLaunchData @ApiStatus.Internal constructor(
|
||||
val commands: List<String>,
|
||||
val vmOptionsFilePath: String? = null,
|
||||
val bootClassPathJarNames: List<String> = emptyList(),
|
||||
@@ -163,20 +137,18 @@ class CustomCommandLaunchData @Internal constructor(
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class CustomProperty @Internal constructor(
|
||||
class CustomProperty @ApiStatus.Internal constructor(
|
||||
val key: String,
|
||||
val value: String,
|
||||
)
|
||||
|
||||
@Serializer(forClass = LocalDate::class)
|
||||
private object LocalDateSerializer : KSerializer<LocalDate> {
|
||||
private val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
private val formatter = DateTimeFormatter.ofPattern(@Suppress("SpellCheckingInspection") "yyyyMMdd")
|
||||
|
||||
override fun serialize(encoder: Encoder, value: LocalDate) {
|
||||
encoder.encodeString(value.format(formatter))
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): LocalDate {
|
||||
return LocalDate.parse(decoder.decodeString(), formatter)
|
||||
}
|
||||
override fun deserialize(decoder: Decoder): LocalDate = LocalDate.parse(decoder.decodeString(), formatter)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user