Skip to content

Commit

Permalink
Merge branch 'master' into ClassHierarchyToJson
Browse files Browse the repository at this point in the history
  • Loading branch information
msridhar authored Aug 15, 2024
2 parents 1595369 + d98c973 commit 9b8ac2e
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 140 deletions.
118 changes: 57 additions & 61 deletions build-logic/src/main/kotlin/com/ibm/wala/gradle/cast/helpers.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.ibm.wala.gradle.cast

import java.io.File
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskInstantiationException
import org.gradle.api.tasks.TaskProvider
import org.gradle.internal.jvm.Jvm
import org.gradle.kotlin.dsl.closureOf
import org.gradle.kotlin.dsl.extra
Expand All @@ -18,74 +20,68 @@ import org.gradle.nativeplatform.tasks.LinkSharedLibrary
// helpers for building native CAst components
//

fun addCastLibrary(binary: CppBinary, linkTask: AbstractLinkTask, project: Project) {
linkTask.configure(
project.closureOf<AbstractLinkTask> {
/**
* Configures the provided [Task] using the given action.
*
* [TaskProvider] already offers a [TaskProvider.configure] method that is compatible with Gradle's
* [task configuration avoidance APIs](https://docs.gradle.org/current/userguide/task_configuration_avoidance.html).
* Unfortunately, many of the APIs for native compilation provide access only to [Provider]<[Task]>
* instances, which have no configuration-avoiding `configure` method. Instead, the best we can do
* is to [get][Provider.get] the provided [Task], then configure it using [Task.configure].
*
* @param action The configuration action to be applied to the task.
*/
fun <T : Task> Provider<T>.configure(action: T.() -> Unit) {
get().configure(closureOf(action))
}

fun AbstractLinkTask.addCastLibrary(binary: CppBinary) {
configure(
closureOf<AbstractLinkTask> {
project.project(":cast:cast").tasks.named(name, LinkSharedLibrary::class.java) {
addRpath(linkTask, nativeLibraryOutput)
this@addCastLibrary.addRpath(nativeLibraryOutput)
}
addJvmLibrary(binary, linkTask, project)
addJvmLibrary(binary)
})
}

fun findJvmLibrary(
project: Project,
extension: String,
currentJavaHome: File,
subdirs: List<String>
) = subdirs.map { project.file("$currentJavaHome/$it/libjvm.$extension") }.find { it.exists() }!!
private fun File.findJvmLibrary(extension: String, subdirs: List<String>) =
subdirs.map { resolve("$it/libjvm.$extension") }.find { it.exists() }!!

fun AbstractLinkTask.addJvmLibrary(binary: CppBinary) {
project.dependencies(
closureOf<DependencyHandler> {
val currentJavaHome = Jvm.current().javaHome
val family = binary.targetMachine.operatingSystemFamily

fun addJvmLibrary(binary: CppBinary, linkTask: AbstractLinkTask, project: Project) =
project.dependencies(
project.closureOf<DependencyHandler> {
val currentJavaHome = Jvm.current().javaHome
val family = binary.targetMachine.operatingSystemFamily
val (osIncludeSubdir, libJVM) =
when (family.name) {
OperatingSystemFamily.LINUX ->
"linux" to
currentJavaHome.findJvmLibrary(
"so", listOf("jre/lib/amd64/server", "lib/amd64/server", "lib/server"))
OperatingSystemFamily.MACOS ->
"darwin" to
currentJavaHome.findJvmLibrary(
"dylib", listOf("jre/lib/server", "lib/server"))
OperatingSystemFamily.WINDOWS -> "win32" to currentJavaHome.resolve("lib/jvm.lib")
else ->
throw TaskInstantiationException(
"unrecognized operating system family \"$family\"")
}

data class Details(
val osIncludeSubdir: String,
val libJVM: File,
)
when (family.name) {
OperatingSystemFamily.LINUX ->
Details(
"linux",
findJvmLibrary(
project,
"so",
currentJavaHome,
listOf(
"jre/lib/amd64/server",
"lib/amd64/server",
"lib/server",
)))
OperatingSystemFamily.MACOS ->
Details(
"darwin",
findJvmLibrary(
project,
"dylib",
currentJavaHome,
listOf(
"jre/lib/server",
"lib/server",
)))
OperatingSystemFamily.WINDOWS ->
Details("win32", project.file("$currentJavaHome/lib/jvm.lib"))
else ->
throw TaskInstantiationException("unrecognized operating system family \"$family\"")
}.run {
val jniIncludeDir = "$currentJavaHome/include"
binary.compileTask
.get()
.includes(project.files(jniIncludeDir, "$jniIncludeDir/$osIncludeSubdir"))
add((binary.linkLibraries as Configuration).name, project.files(libJVM))
addRpath(linkTask, libJVM)
}
})
val jniIncludeDir = "$currentJavaHome/include"
binary.compileTask
.get()
.includes(project.files(jniIncludeDir, "$jniIncludeDir/$osIncludeSubdir"))
add((binary.linkLibraries as Configuration).name, project.files(libJVM))
addRpath(libJVM)
})
}

fun addRpath(linkTask: AbstractLinkTask, library: File) {
if (!(linkTask.project.rootProject.extra["isWindows"] as Boolean)) {
linkTask.linkerArgs.add("-Wl,-rpath,${library.parent}")
fun AbstractLinkTask.addRpath(library: File) {
if (!(project.rootProject.extra["isWindows"] as Boolean)) {
linkerArgs.add("-Wl,-rpath,${library.parent}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ repositories.mavenCentral()

// workaround for <https://github.com/gradle/gradle/issues/4802>
eclipse.classpath.file.whenMerged {
(this as Classpath).run {
entries.forEach {
if (it is AbstractClasspathEntry && it.entryAttributes["gradle_used_by_scope"] == "test")
it.entryAttributes["test"] = true
}
this as Classpath
entries.forEach {
if (it is AbstractClasspathEntry && it.entryAttributes["gradle_used_by_scope"] == "test")
it.entryAttributes["test"] = true
}
}

Expand Down
18 changes: 8 additions & 10 deletions cast/cast/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import com.ibm.wala.gradle.cast.addJvmLibrary
import com.ibm.wala.gradle.cast.configure
import com.ibm.wala.gradle.cast.nativeLibraryOutput

plugins {
Expand All @@ -9,17 +10,14 @@ plugins {

library {
binaries.whenElementFinalized {
compileTask.get().configure(closureOf<CppCompile> { macros["BUILD_CAST_DLL"] = "1" })
compileTask.configure { macros["BUILD_CAST_DLL"] = "1" }

this as CppSharedLibrary
linkTask
.get()
.configure(
closureOf<LinkSharedLibrary> {
if (targetMachine.operatingSystemFamily.isMacOs) {
linkerArgs.add("-Wl,-install_name,@rpath/${nativeLibraryOutput.name}")
}
addJvmLibrary(this@whenElementFinalized, this, project)
})
linkTask.configure {
if (targetMachine.operatingSystemFamily.isMacOs) {
linkerArgs.add("-Wl,-install_name,@rpath/${nativeLibraryOutput.name}")
}
addJvmLibrary(this@whenElementFinalized)
}
}
}
113 changes: 55 additions & 58 deletions cast/smoke_main/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import com.ibm.wala.gradle.cast.addCastLibrary
import com.ibm.wala.gradle.cast.addRpath
import com.ibm.wala.gradle.cast.configure
import org.gradle.api.attributes.LibraryElements.CLASSES
import org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE
import org.gradle.api.attributes.LibraryElements.RESOURCES
Expand Down Expand Up @@ -59,65 +60,61 @@ application {
}

binaries.whenElementFinalized {
(this as CppExecutable)
.linkTask
.get()
.configure(
closureOf<LinkExecutable> {
val libxlatorTest =
(if (isOptimized) xlatorTestReleaseSharedLibraryConfig
else xlatorTestDebugSharedLibraryConfig)
.singleFile
addRpath(this, libxlatorTest)
addCastLibrary(this@whenElementFinalized, this, project)

if (isDebuggable && !isOptimized) {
val checkSmokeMain by
tasks.registering(Exec::class) {
notCompatibleWithConfigurationCache(
"https://github.com/gradle/gradle/issues/13485")

// main executable to run for test
inputs.file(linkedFile)
executable(
object {
val toString by lazy { linkedFile.get().asFile.toString() }

override fun toString() = toString
})

// xlator Java bytecode + implementation of native methods
val pathElements = project.objects.listProperty<File>()
pathElements.addAll(files("../build/classes/java/test", libxlatorTest.parent))

// "primordial.txt" resource loaded during test
pathElements.add(coreResources.singleFile)
inputs.files(coreResources)

// additional supporting Java class files
inputs.files(smokeMainExtraPathElements)
pathElements.addAll(smokeMainExtraPathElements)

// all combined as a colon-delimited path list
argumentProviders.add { listOf(pathElements.get().joinToString(":")) }

// log output to file, although we don"t validate it
val outFile = project.layout.buildDirectory.file("${name}.log")
outputs.file(outFile)
doFirst {
outFile.get().asFile.outputStream().let {
standardOutput = it
errorOutput = it
}
}
}

if (!(rootProject.extra["isWindows"] as Boolean)) {
// Known to be broken on Windows, but not intentionally so. Please fix if you
// know how! <https://github.com/wala/WALA/issues/608>
tasks.named("check").configure { dependsOn(checkSmokeMain) }
this as CppExecutable
linkTask.configure {
val libxlatorTest =
(if (isOptimized) xlatorTestReleaseSharedLibraryConfig
else xlatorTestDebugSharedLibraryConfig)
.singleFile
addRpath(libxlatorTest)
addCastLibrary(this@whenElementFinalized)

if (isDebuggable && !isOptimized) {
val checkSmokeMain by
tasks.registering(Exec::class) {
notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13485")

// main executable to run for test
inputs.file(linkedFile)
executable(
object {
val toString by lazy { linkedFile.get().asFile.toString() }

override fun toString() = toString
})

// xlator Java bytecode + implementation of native methods
val pathElements = project.objects.listProperty<File>()
pathElements.addAll(files("../build/classes/java/test", libxlatorTest.parent))

// "primordial.txt" resource loaded during test
pathElements.add(coreResources.singleFile)
inputs.files(coreResources)

// additional supporting Java class files
inputs.files(smokeMainExtraPathElements)
pathElements.addAll(smokeMainExtraPathElements)

// all combined as a colon-delimited path list
argumentProviders.add { listOf(pathElements.get().joinToString(":")) }

// log output to file, although we don"t validate it
val outFile = project.layout.buildDirectory.file("${name}.log")
outputs.file(outFile)
doFirst {
outFile.get().asFile.outputStream().let {
standardOutput = it
errorOutput = it
}
}
})
}

if (!(rootProject.extra["isWindows"] as Boolean)) {
// Known to be broken on Windows, but not intentionally so. Please fix if you
// know how! <https://github.com/wala/WALA/issues/608>
tasks.named("check").configure { dependsOn(checkSmokeMain) }
}
}
}
}
}
3 changes: 2 additions & 1 deletion cast/xlator_test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ library {
dependencies { implementation(projects.cast.cast) }

binaries.whenElementFinalized {
addCastLibrary(this, (this as CppSharedLibrary).linkTask.get(), project)
this as CppSharedLibrary
linkTask.get().addCastLibrary(this)
}
}
9 changes: 4 additions & 5 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ plugins {
eclipse {
project.natures("org.eclipse.pde.PluginNature")
classpath.file.whenMerged {
(this as Classpath).run {
entries.forEach {
if (it is AbstractClasspathEntry && it.path == "src/testSubjects/java") {
it.entryAttributes["ignore_optional_problems"] = true
}
this as Classpath
entries.forEach {
if (it is AbstractClasspathEntry && it.path == "src/testSubjects/java") {
it.entryAttributes["ignore_optional_problems"] = true
}
}
}
Expand Down

0 comments on commit 9b8ac2e

Please sign in to comment.