Snap for 8189365 from a181fe59a34803a1ba7300bd1a32532b6dc3e9fb to tm-frc-resolv-release
Change-Id: I0a015f3e70741dba10ce17ca40f75972fb294886
diff --git a/.gitignore b/.gitignore
index 8f8ed69..14e1cbc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,5 @@
.gradle
/build/
-/buildSrc/build/
-/curl/build/
-/googletest/build/
-/jsoncpp/build/
-/openssl/build/
# Ignore Gradle GUI config
gradle-app.setting
@@ -48,11 +43,11 @@
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
-.idea/modules.xml
-.idea/*.iml
-.idea/modules
-*.iml
-*.ipr
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
# CMake
cmake-build-*/
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 93ae7ac..e3439a9 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -10,7 +10,6 @@
</JetCodeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
- <option name="KEEP_LINE_BREAKS" value="false" />
<option name="WRAP_ON_TYPING" value="0" />
</codeStyleSettings>
</code_scheme>
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 443b5d2..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="CompilerConfiguration">
- <bytecodeTargetLevel target="1.6" />
- </component>
-</project>
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index 6fde95a..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="RemoteRepositoriesConfiguration">
- <remote-repository>
- <option name="id" value="central" />
- <option name="name" value="Maven Central repository" />
- <option name="url" value="https://repo1.maven.org/maven2" />
- </remote-repository>
- <remote-repository>
- <option name="id" value="jboss.community" />
- <option name="name" value="JBoss Community repository" />
- <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
- </remote-repository>
- <remote-repository>
- <option name="id" value="MavenRepo" />
- <option name="name" value="MavenRepo" />
- <option name="url" value="https://repo.maven.apache.org/maven2/" />
- </remote-repository>
- <remote-repository>
- <option name="id" value="maven" />
- <option name="name" value="maven" />
- <option name="url" value="https://dl.bintray.com/s1m0nw1/KtsRunner" />
- </remote-repository>
- <remote-repository>
- <option name="id" value="BintrayJCenter" />
- <option name="name" value="BintrayJCenter" />
- <option name="url" value="https://jcenter.bintray.com/" />
- </remote-repository>
- <remote-repository>
- <option name="id" value="Google" />
- <option name="name" value="Google" />
- <option name="url" value="https://dl.google.com/dl/android/maven2/" />
- </remote-repository>
- </component>
-</project>
\ No newline at end of file
diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml
index e56386c..a6fe551 100644
--- a/.idea/kotlinScripting.xml
+++ b/.idea/kotlinScripting.xml
@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinScriptingSettings">
- <scriptDefinition className="org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate" definitionName="KotlinBuildScript">
- <order>2147483647</order>
- <autoReloadConfigurations>true</autoReloadConfigurations>
- </scriptDefinition>
+ <option name="isAutoReloadEnabled" value="true" />
</component>
</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 15b559a..bc8d0a3 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..347b2d7
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/ndkports.iml" filepath="$PROJECT_DIR$/.idea/ndkports.iml" />
+ </modules>
+ </component>
+</project>
\ No newline at end of file
diff --git a/.idea/ndkports.iml b/.idea/ndkports.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/ndkports.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 899b2f1..73193ea 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -27,34 +27,6 @@
<option name="issueRegexp" value="\bcs/([^\s]+[\w$])" />
<option name="linkRegexp" value="https://cs.corp.google.com/search/?q=$1" />
</IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\bb/(\d+)(#\w+)?\b" />
- <option name="linkRegexp" value="https://buganizer.corp.google.com/issues/$1$2" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\b(?:BUG=|FIXED=)(\d+)\b" />
- <option name="linkRegexp" value="https://buganizer.corp.google.com/issues/$1" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\b(?:cl/|cr/|OCL=|DIFFBASE=|ROLLBACK_OF=)(\d+)\b" />
- <option name="linkRegexp" value="https://critique.corp.google.com/$1" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\bomg/(\d+)\b" />
- <option name="linkRegexp" value="https://omg.corp.google.com/$1" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\b(?:go/|goto/)([^,.<>()"\s]+(?:[.,][^,.<>()"\s]+)*)" />
- <option name="linkRegexp" value="https://goto.google.com/$1" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="\bcs/([^\s]+[\w$])" />
- <option name="linkRegexp" value="https://cs.corp.google.com/search/?q=$1" />
- </IssueNavigationLink>
- <IssueNavigationLink>
- <option name="issueRegexp" value="(LINT\.IfChange)|(LINT\.ThenChange)" />
- <option name="linkRegexp" value="https://goto.google.com/ifthisthenthatlint" />
- </IssueNavigationLink>
</list>
</option>
</component>
diff --git a/Dockerfile b/Dockerfile
index ac011ef..aba9898 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,20 +1,15 @@
-FROM gcr.io/cloud-builders/javac:8
+FROM gcr.io/cloud-builders/gradle:5.6.2-jdk-8
-RUN apt-get update && apt-get install -y \
- cmake \
- curl \
- ninja-build \
- python3-pip
+RUN apt-get update
+RUN apt-get install -y curl
+RUN apt-get install -y ninja-build
+RUN apt-get install -y python3-pip
RUN pip3 install meson
RUN curl -o ndk.zip \
- https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip
+ https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip
RUN unzip ndk.zip
-RUN mv android-ndk-r21e /ndk
-RUN curl -L -o platform-tools.zip \
- https://dl.google.com/android/repository/platform-tools-latest-linux.zip
-RUN unzip platform-tools.zip platform-tools/adb
-RUN mv platform-tools/adb /usr/bin/adb
+RUN mv android-ndk-r20b /ndk
WORKDIR /src
ENTRYPOINT ["./gradlew"]
-CMD ["--stacktrace", "-PndkPath=/ndk", "release"]
+CMD ["-PndkPath=/ndk", "release"]
diff --git a/build.gradle.kts b/build.gradle.kts
index f217598..a00d626 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,47 +1,113 @@
-buildscript {
- val snapshotSuffix = if (hasProperty("release")) {
- // We're still tagging releases as betas until we have more thorough
- // test automation.
- "-beta-1"
- } else {
- "-SNAPSHOT"
- }
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
- extra.apply {
- set("snapshotSuffix", snapshotSuffix)
- }
+plugins {
+ kotlin("jvm") version "1.3.72"
+ application
}
group = "com.android"
-version = "1.0.0${extra.get("snapshotSuffix")}"
-
-plugins {
- distribution
-}
+version = "1.0.0-SNAPSHOT"
repositories {
mavenCentral()
jcenter()
google()
+ maven(url = "https://dl.bintray.com/s1m0nw1/KtsRunner")
+}
+
+dependencies {
+ implementation(kotlin("stdlib", "1.3.72"))
+ implementation(kotlin("reflect", "1.3.72"))
+
+ implementation("com.google.prefab:api:1.0.0")
+
+ implementation("com.github.ajalt:clikt:2.2.0")
+ implementation("de.swirtz:ktsRunner:0.0.7")
+ implementation("org.apache.maven:maven-core:3.6.2")
+ implementation("org.redundent:kotlin-xml-builder:1.5.3")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+ testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
+ testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0-M1")
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0-M1")
+}
+
+application {
+ // Define the main class for the application.
+ mainClassName = "com.android.ndkports.CliKt"
+}
+
+tasks.withType<KotlinCompile> {
+ kotlinOptions.jvmTarget = "1.8"
+ kotlinOptions.freeCompilerArgs += listOf(
+ "-progressive",
+ "-Xuse-experimental=kotlinx.serialization.ImplicitReflectionSerializer"
+ )
+}
+
+val portsBuildDir = buildDir.resolve("ports")
+
+val allPorts = listOf("openssl", "curl", "jsoncpp")
+
+// Can be specified in ~/.gradle/gradle.properties:
+//
+// ndkPath=/path/to/ndk
+//
+// Or on the command line:
+//
+// ./gradlew -PndkPath=/path/to/ndk run
+val ndkPath: String by project
+tasks.named<JavaExec>("run") {
+ // Order matters since we don't do any dependency sorting, so we can't just
+ // use the directory list.
+ args = listOf("--ndk", ndkPath, "-o", portsBuildDir.toString()) + allPorts
+}
+
+for (port in allPorts) {
+ distributions {
+ create(port) {
+ contents {
+ includeEmptyDirs = false
+ from(portsBuildDir.resolve(port)) {
+ include("**/*.aar")
+ include("**/*.pom")
+ }
+ }
+ }
+ }
+
+ tasks.named("${port}DistTar") {
+ dependsOn(":run")
+ }
+
+ tasks.named("${port}DistZip") {
+ dependsOn(":run")
+ }
}
distributions {
- main {
+ create("all") {
contents {
- from("${rootProject.buildDir}/repository")
- include("**/*.aar")
- include("**/*.pom")
+ includeEmptyDirs = false
+ from(portsBuildDir) {
+ include("**/*.aar")
+ include("**/*.pom")
+ }
}
}
}
-tasks {
- distZip {
- dependsOn(project.getTasksByName("publish", true))
- }
+tasks.named("allDistTar") {
+ dependsOn(":run")
+}
+
+tasks.named("allDistZip") {
+ dependsOn(":run")
}
tasks.register("release") {
- dependsOn(project.getTasksByName("test", true))
- dependsOn(":distZip")
+ dependsOn(":allDistZip")
+ for (port in allPorts) {
+ dependsOn(":${port}DistZip")
+ }
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
deleted file mode 100644
index 4de21c7..0000000
--- a/buildSrc/build.gradle.kts
+++ /dev/null
@@ -1,62 +0,0 @@
-val kotlinVersion = "1.4.20"
-
-plugins {
- id("org.jetbrains.kotlin.jvm") version "1.4.20"
- id("java-gradle-plugin")
- id("maven-publish")
-}
-
-group = "com.android.ndkports"
-version = "1.0.0-SNAPSHOT"
-
-repositories {
- mavenCentral()
- jcenter()
- google()
-}
-
-dependencies {
- implementation(kotlin("stdlib", kotlinVersion))
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1")
-
- implementation("com.google.prefab:api:1.1.2")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0")
- implementation("org.redundent:kotlin-xml-builder:1.6.1")
-
- testImplementation(kotlin("test", kotlinVersion))
- testImplementation(kotlin("test-junit", kotlinVersion))
- testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
- testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0")
-}
-
-tasks {
- compileJava {
- @Suppress("UnstableApiUsage")
- options.release.set(8)
- }
-
- compileKotlin {
- kotlinOptions.jvmTarget = "1.8"
- }
-
- compileTestKotlin {
- kotlinOptions.jvmTarget = "1.8"
- }
-}
-
-gradlePlugin {
- plugins {
- create("ndkports") {
- id = "com.android.ndkports.NdkPorts"
- implementationClass = "com.android.ndkports.NdkPortsPlugin"
- }
- }
-}
-
-publishing {
- repositories {
- maven {
- url = uri("${rootProject.buildDir}/repository")
- }
- }
-}
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
deleted file mode 100644
index e69de29..0000000
--- a/buildSrc/settings.gradle.kts
+++ /dev/null
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/Abi.kt b/buildSrc/src/main/kotlin/com/android/ndkports/Abi.kt
deleted file mode 100644
index 155c59c..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/Abi.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ndkports
-
-import java.util.Collections.max
-
-enum class Abi(
- val archName: String,
- val abiName: String,
- val triple: String,
- val minSupportedVersion: Int
-) {
- Arm("arm", "armeabi-v7a", "arm-linux-androideabi", 16),
- Arm64("arm64", "arm64-v8a", "aarch64-linux-android", 21),
- X86("x86", "x86", "i686-linux-android", 16),
- X86_64("x86_64", "x86_64", "x86_64-linux-android", 21);
-
- fun adjustMinSdkVersion(minSdkVersion: Int) =
- max(listOf(minSdkVersion, minSupportedVersion))
-
- companion object {
- fun fromAbiName(name: String) = values().find { it.abiName == name }
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/AdHocPortTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/AdHocPortTask.kt
deleted file mode 100644
index 4c9fcbc..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/AdHocPortTask.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ndkports
-
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
-import java.io.File
-
-open class RunBuilder {
- val cmd = mutableListOf<String>()
- fun arg(arg: String) = cmd.add(arg)
- fun args(vararg args: String) = cmd.addAll(args)
-
- val env = mutableMapOf<String, String>()
- fun env(key: String, value: String) = env.set(key, value)
-}
-
-class AdHocBuilder(
- val sourceDirectory: File,
- val buildDirectory: File,
- val installDirectory: File,
- val toolchain: Toolchain,
- val sysroot: File,
- val ncpus: Int,
-) {
- val runs = mutableListOf<RunBuilder>()
- fun run(block: RunBuilder.() -> Unit) {
- runs.add(RunBuilder().apply { block() })
- }
-}
-
-abstract class AdHocPortTask : PortTask() {
- @get:Input
- abstract val builder: Property<AdHocBuilder.() -> Unit>
-
- fun builder(block: AdHocBuilder.() -> Unit) = builder.set(block)
-
- override fun buildForAbi(
- toolchain: Toolchain,
- workingDirectory: File,
- buildDirectory: File,
- installDirectory: File
- ) {
- buildDirectory.mkdirs()
-
- val builderBlock = builder.get()
- val builder = AdHocBuilder(
- sourceDirectory.get().asFile,
- buildDirectory,
- installDirectory,
- toolchain,
- prefabGenerated.get().asFile,
- ncpus,
- )
- builder.builderBlock()
-
- for (run in builder.runs) {
- executeSubprocess(
- run.cmd, buildDirectory, additionalEnvironment = run.env
- )
- }
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/AutoconfPortTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/AutoconfPortTask.kt
deleted file mode 100644
index e288e33..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/AutoconfPortTask.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ndkports
-
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
-import java.io.File
-
-class AutoconfBuilder(val toolchain: Toolchain, val sysroot: File) :
- RunBuilder()
-
-abstract class AutoconfPortTask : PortTask() {
- @get:Input
- abstract val autoconf: Property<AutoconfBuilder.() -> Unit>
-
- fun autoconf(block: AutoconfBuilder.() -> Unit) = autoconf.set(block)
-
- override fun buildForAbi(
- toolchain: Toolchain,
- workingDirectory: File,
- buildDirectory: File,
- installDirectory: File
- ) {
- buildDirectory.mkdirs()
-
- val autoconfBlock = autoconf.get()
- val builder = AutoconfBuilder(
- toolchain,
- prefabGenerated.get().asFile.resolve(toolchain.abi.triple)
- )
- builder.autoconfBlock()
-
- executeSubprocess(listOf(
- "${sourceDirectory.get().asFile.absolutePath}/configure",
- "--host=${toolchain.binutilsTriple}",
- "--prefix=${installDirectory.absolutePath}"
- ) + builder.cmd,
- buildDirectory,
- additionalEnvironment = mutableMapOf(
- "AR" to toolchain.ar.absolutePath,
- "CC" to toolchain.clang.absolutePath,
- "CXX" to toolchain.clangxx.absolutePath,
- "RANLIB" to toolchain.ranlib.absolutePath,
- "STRIP" to toolchain.strip.absolutePath,
- "PATH" to "${toolchain.binDir}:${System.getenv("PATH")}"
- ).apply { putAll(builder.env) })
-
- executeSubprocess(listOf("make", "-j$ncpus"), buildDirectory)
-
- executeSubprocess(
- listOf("make", "-j$ncpus", "install"), buildDirectory
- )
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/CMakePortTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/CMakePortTask.kt
deleted file mode 100644
index dba2017..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/CMakePortTask.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ndkports
-
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
-import java.io.File
-
-class CMakeBuilder(val toolchain: Toolchain, val sysroot: File) :
- RunBuilder()
-
-abstract class CMakePortTask : PortTask() {
- @get:Input
- abstract val cmake: Property<CMakeBuilder.() -> Unit>
-
- fun cmake(block: CMakeBuilder.() -> Unit) = cmake.set(block)
-
- override fun buildForAbi(
- toolchain: Toolchain,
- workingDirectory: File,
- buildDirectory: File,
- installDirectory: File
- ) {
- configure(toolchain, buildDirectory, installDirectory)
- build(buildDirectory)
- install(buildDirectory)
- }
-
- private fun configure(
- toolchain: Toolchain, buildDirectory: File, installDirectory: File
- ) {
- val cmakeBlock = cmake.get()
- val builder = CMakeBuilder(
- toolchain,
- prefabGenerated.get().asFile.resolve(toolchain.abi.triple)
- )
- builder.cmakeBlock()
-
- val toolchainFile =
- toolchain.ndk.path.resolve("build/cmake/android.toolchain.cmake")
-
- buildDirectory.mkdirs()
- executeSubprocess(
- listOf(
- "cmake",
- "-DCMAKE_TOOLCHAIN_FILE=${toolchainFile.absolutePath}",
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
- "-DCMAKE_INSTALL_PREFIX=${installDirectory.absolutePath}",
- "-DANDROID_ABI=${toolchain.abi.abiName}",
- "-DANDROID_API_LEVEL=${toolchain.api}",
- "-GNinja",
- sourceDirectory.get().asFile.absolutePath,
- ) + builder.cmd, buildDirectory, builder.env
- )
- }
-
- private fun build(buildDirectory: File) =
- executeSubprocess(listOf("ninja", "-v"), buildDirectory)
-
- private fun install(buildDirectory: File) =
- executeSubprocess(listOf("ninja", "-v", "install"), buildDirectory)
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/Devices.kt b/buildSrc/src/main/kotlin/com/android/ndkports/Devices.kt
deleted file mode 100644
index 3ed1d9a..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/Devices.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.android.ndkports
-
-import java.io.File
-
-data class AdbException(val args: Iterable<String>, val output: String) :
- RuntimeException("${formatCmd(args)}:\n$output") {
- val cmd: String by lazy { formatCmd(args) }
-
- companion object {
- fun formatCmd(args: Iterable<String>) = args.joinToString(" ")
- }
-}
-
-private fun adb(args: Iterable<String>, serial: String? = null): String {
- val adbCmd = if (serial == null) {
- listOf("adb")
- } else {
- listOf("adb", "-s", serial)
- }
- val result = ProcessBuilder(adbCmd + args).redirectErrorStream(true).start()
- val output = result.inputStream.bufferedReader().use { it.readText() }
- if (result.waitFor() != 0) {
- throw AdbException(args, output)
- }
- return output
-}
-
-data class Device(val serial: String) {
- private val abis: List<Abi> by lazy {
- val abiProps = listOf(
- "ro.product.cpu.abi",
- "ro.product.cpu.abi2",
- "ro.product.cpu.abilist",
- )
- val abiSet = mutableSetOf<Abi>()
- for (abiProp in abiProps) {
- for (abiName in getProp(abiProp).trim().split(",")) {
- Abi.fromAbiName(abiName)?.let { abiSet.add(it) }
- }
- }
- abiSet.toList().sortedBy { it.abiName }
- }
-
- private val version: Int by lazy {
- getProp("ro.build.version.sdk").trim().toInt()
- }
-
- fun compatibleWith(abi: Abi, minSdkVersion: Int) =
- abi in abis && minSdkVersion <= version
-
- fun push(src: File, dest: File) =
- run(listOf("push", src.toString(), dest.toString()))
-
- fun shell(cmd: Iterable<String>) = run(listOf("shell") + cmd)
-
- private fun getProp(name: String): String = shell(listOf("getprop", name))
-
- private fun run(args: Iterable<String>): String = adb(args, serial)
-}
-
-class DeviceFleet {
- private fun lineHasUsableDevice(line: String): Boolean {
- if (line.isBlank()) {
- return false
- }
- if (line == "List of devices attached") {
- return false
- }
- if (line.contains("offline")) {
- return false
- }
- if (line.contains("unauthorized")) {
- return false
- }
- if (line.startsWith("* daemon")) {
- return false
- }
- return true
- }
-
- private val devices: List<Device> by lazy {
- adb(listOf("devices")).lines().filter { lineHasUsableDevice(it) }.map {
- Device(it.split("\\s".toRegex()).first())
- }
- }
-
- fun findDeviceFor(abi: Abi, minSdkVersion: Int): Device? =
- devices.find { it.compatibleWith(abi, minSdkVersion) }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/NdkPortsPlugin.kt b/buildSrc/src/main/kotlin/com/android/ndkports/NdkPortsPlugin.kt
deleted file mode 100644
index ff629c0..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/NdkPortsPlugin.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-package com.android.ndkports
-
-import org.gradle.api.InvalidUserDataException
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.attributes.Attribute
-import org.gradle.api.component.SoftwareComponentFactory
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.file.RegularFileProperty
-import org.gradle.api.model.ObjectFactory
-import org.gradle.api.plugins.BasePlugin
-import org.gradle.api.provider.Property
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.bundling.Zip
-import javax.inject.Inject
-
-abstract class NdkPortsExtension {
- abstract val source: RegularFileProperty
-
- abstract val ndkPath: DirectoryProperty
-
- abstract val minSdkVersion: Property<Int>
-}
-
-class NdkPortsPluginImpl(
- private val project: Project,
- private val softwareComponentFactory: SoftwareComponentFactory,
- objects: ObjectFactory,
-) {
- private val topBuildDir = project.buildDir.resolve("port")
-
- private val extension =
- project.extensions.create("ndkPorts", NdkPortsExtension::class.java)
-
- private var portTaskAdded: Boolean = false
- private val portTask = objects.property(PortTask::class.java)
- private lateinit var prefabTask: Provider<PrefabTask>
- private lateinit var extractTask: Provider<SourceExtractTask>
- private lateinit var packageTask: Provider<PackageBuilderTask>
- private lateinit var aarTask: Provider<Zip>
-
- private lateinit var implementation: Configuration
- private lateinit var exportedAars: Configuration
- private lateinit var consumedAars: Configuration
-
- private val artifactType = Attribute.of("artifactType", String::class.java)
-
- private fun createConfigurations() {
- implementation = project.configurations.create("implementation") {
- it.isCanBeResolved = false
- it.isCanBeConsumed = false
- }
-
- exportedAars = project.configurations.create("exportedAars") {
- it.isCanBeResolved = false
- it.isCanBeConsumed = true
- it.extendsFrom(implementation)
- it.attributes { attributes ->
- with(attributes) {
- attribute(artifactType, "aar")
- }
- }
- }
-
- consumedAars = project.configurations.create("consumedAars") {
- it.isCanBeResolved = true
- it.isCanBeConsumed = false
- it.extendsFrom(implementation)
- it.attributes { attributes ->
- with(attributes) {
- attribute(artifactType, "aar")
- }
- }
- }
- }
-
- private fun createTasks() {
- prefabTask = project.tasks.register("prefab", PrefabTask::class.java) {
- with(it) {
- aars = consumedAars.incoming.artifacts.artifactFiles
- outputDirectory.set(topBuildDir.resolve("dependencies"))
- ndkPath.set(extension.ndkPath)
- minSdkVersion.set(extension.minSdkVersion)
- }
- }
-
- extractTask = project.tasks.register(
- "extractSrc", SourceExtractTask::class.java
- ) {
- with(it) {
- source.set(extension.source)
- outDir.set(topBuildDir.resolve("src"))
- }
- }
-
- packageTask = project.tasks.register(
- "prefabPackage", PackageBuilderTask::class.java
- ) {
- if (!portTask.isPresent) {
- throw InvalidUserDataException(
- "The ndkports plugin was applied but no port task was " +
- "registered. A task deriving from NdkPortsTask " +
- "must be registered."
- )
- }
- with(it) {
- sourceDirectory.set(extractTask.get().outDir)
- outDir.set(topBuildDir)
- ndkPath.set(extension.ndkPath)
- installDirectory.set(portTask.get().installDir)
- minSdkVersion.set(extension.minSdkVersion)
- }
- }
-
- aarTask = project.tasks.register("packageAar", Zip::class.java) {
- it.from(packageTask.get().intermediatesDirectory)
- it.archiveExtension.set("aar")
- it.dependsOn(packageTask)
- }
-
- project.artifacts.add(exportedAars.name, aarTask)
-
- val portTasks = project.tasks.withType(PortTask::class.java)
- portTasks.whenTaskAdded { portTask ->
- if (portTaskAdded) {
- throw InvalidUserDataException(
- "Cannot define multiple port tasks for a single module"
- )
- }
- portTaskAdded = true
- this.portTask.set(portTask)
-
- with (portTask) {
- sourceDirectory.set(extractTask.get().outDir)
- ndkPath.set(extension.ndkPath)
- buildDir.set(topBuildDir)
- minSdkVersion.set(extension.minSdkVersion)
- prefabGenerated.set(prefabTask.get().generatedDirectory)
- }
- }
-
- val testTasks =
- project.tasks.withType(AndroidExecutableTestTask::class.java)
- testTasks.whenTaskAdded { testTask ->
- with (testTask) {
- dependsOn(aarTask)
- minSdkVersion.set(extension.minSdkVersion)
- ndkPath.set(extension.ndkPath)
- }
- project.tasks.getByName("check").dependsOn(testTask)
- }
- }
-
- private fun createComponents() {
- val adhocComponent = softwareComponentFactory.adhoc("prefab")
- project.components.add(adhocComponent)
- adhocComponent.addVariantsFromConfiguration(exportedAars) {
- it.mapToMavenScope("runtime")
- }
- }
-
- fun apply() {
- project.pluginManager.apply(BasePlugin::class.java)
- createConfigurations()
- createTasks()
- createComponents()
- }
-}
-
-@Suppress("UnstableApiUsage", "Unused")
-class NdkPortsPlugin @Inject constructor(
- private val objects: ObjectFactory,
- private val softwareComponentFactory: SoftwareComponentFactory,
-) : Plugin<Project> {
- override fun apply(project: Project) {
- NdkPortsPluginImpl(project, softwareComponentFactory, objects).apply()
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/PackageBuilderTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/PackageBuilderTask.kt
deleted file mode 100644
index a7c408d..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/PackageBuilderTask.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-package com.android.ndkports
-
-import org.gradle.api.DefaultTask
-import org.gradle.api.NamedDomainObjectContainer
-import org.gradle.api.Project
-import org.gradle.api.file.Directory
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.model.ObjectFactory
-import org.gradle.api.provider.ListProperty
-import org.gradle.api.provider.MapProperty
-import org.gradle.api.provider.Property
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.Nested
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-import javax.inject.Inject
-
-abstract class ModuleProperty @Inject constructor(
- objectFactory: ObjectFactory,
- @get:Input val name: String,
-) {
- @Suppress("UnstableApiUsage")
- @get:Input
- val static: Property<Boolean> =
- objectFactory.property(Boolean::class.java).convention(false)
-
- @Suppress("UnstableApiUsage")
- @get:Input
- val headerOnly: Property<Boolean> =
- objectFactory.property(Boolean::class.java).convention(false)
-
- @Suppress("UnstableApiUsage")
- @get:Input
- val includesPerAbi: Property<Boolean> =
- objectFactory.property(Boolean::class.java).convention(false)
-
- @Suppress("UnstableApiUsage")
- @get:Input
- val dependencies: ListProperty<String> =
- objectFactory.listProperty(String::class.java).convention(emptyList())
-}
-
-abstract class PackageBuilderTask @Inject constructor(
- objectFactory: ObjectFactory,
-) : DefaultTask() {
- /**
- * The name of the port. Will be used as the package name in prefab.json.
- */
- @Suppress("UnstableApiUsage")
- @get:Input
- val packageName: Property<String> =
- objectFactory.property(String::class.java).convention(project.name)
-
- /**
- * The version to encode in the prefab.json.
- *
- * This version must be compatible with CMake's `find_package` for
- * config-style packages. This means that it must be one to four decimal
- * separated integers. No other format is allowed.
- *
- * If not set, the default is [Project.getVersion] as interpreted by
- * [CMakeCompatibleVersion.parse].
- *
- * For example, OpenSSL 1.1.1g will set this value to
- * `CMakeCompatibleVersion(1, 1, 1, 7)`.
- */
- @get:Input
- abstract val version: Property<CMakeCompatibleVersion>
-
- @get:Input
- abstract val minSdkVersion: Property<Int>
-
- @get:Nested
- abstract val modules: NamedDomainObjectContainer<ModuleProperty>
-
- @Suppress("UnstableApiUsage")
- @get:Input
- val licensePath: Property<String> =
- objectFactory.property(String::class.java).convention("LICENSE")
-
- @Suppress("UnstableApiUsage")
- @get:Input
- abstract val dependencies: MapProperty<String, String>
-
- @get:InputDirectory
- abstract val sourceDirectory: DirectoryProperty
-
- @get:InputDirectory
- abstract val installDirectory: DirectoryProperty
-
- @get:Internal
- abstract val outDir: DirectoryProperty
-
- @get:OutputDirectory
- val intermediatesDirectory: Provider<Directory>
- get() = outDir.dir("aar")
-
- @get:InputDirectory
- abstract val ndkPath: DirectoryProperty
-
- private val ndk: Ndk
- get() = Ndk(ndkPath.asFile.get())
-
- @TaskAction
- fun run() {
- val modules = modules.asMap.values.map {
- ModuleDescription(
- it.name,
- it.static.get(),
- it.headerOnly.get(),
- it.includesPerAbi.get(),
- it.dependencies.get()
- )
- }
- PrefabPackageBuilder(
- PackageData(
- packageName.get(),
- project.version as String,
- version.get(),
- minSdkVersion.get(),
- licensePath.get(),
- modules,
- dependencies.get(),
- ),
- intermediatesDirectory.get().asFile,
- installDirectory.get().asFile,
- sourceDirectory.get().asFile,
- ndk,
- ).build()
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/PortTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/PortTask.kt
deleted file mode 100644
index 223afb0..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/PortTask.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.android.ndkports
-
-import org.gradle.api.DefaultTask
-import org.gradle.api.file.Directory
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.provider.Property
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-import java.io.File
-
-@Suppress("UnstableApiUsage")
-abstract class PortTask : DefaultTask() {
-
- @get:InputDirectory
- abstract val sourceDirectory: DirectoryProperty
-
- @get:OutputDirectory
- abstract val buildDir: DirectoryProperty
-
- @get:OutputDirectory
- val installDir: Provider<Directory>
- get() = buildDir.dir("install")
-
- @get:InputDirectory
- abstract val prefabGenerated: DirectoryProperty
-
- @get:Input
- abstract val minSdkVersion: Property<Int>
-
- @get:InputDirectory
- abstract val ndkPath: DirectoryProperty
-
- private val ndk: Ndk
- get() = Ndk(ndkPath.asFile.get())
-
- /**
- * The number of CPUs available for building.
- *
- * May be passed to the build system if required.
- */
- @Internal
- protected val ncpus = Runtime.getRuntime().availableProcessors()
-
- protected fun executeSubprocess(
- args: List<String>,
- workingDirectory: File,
- additionalEnvironment: Map<String, String>? = null
- ) {
- val pb = ProcessBuilder(args).redirectErrorStream(true)
- .directory(workingDirectory)
-
- if (additionalEnvironment != null) {
- pb.environment().putAll(additionalEnvironment)
- }
-
- val result = pb.start()
- val output = result.inputStream.bufferedReader().use { it.readText() }
- if (result.waitFor() != 0) {
- throw RuntimeException("Subprocess failed with:\n$output")
- }
- }
-
- @Suppress("MemberVisibilityCanBePrivate")
- fun buildDirectoryFor(abi: Abi): File =
- buildDir.asFile.get().resolve("build/$abi")
-
- @Suppress("MemberVisibilityCanBePrivate")
- fun installDirectoryFor(abi: Abi): File =
- installDir.get().asFile.resolve("$abi")
-
- @TaskAction
- fun run() {
- for (abi in Abi.values()) {
- val api = abi.adjustMinSdkVersion(minSdkVersion.get())
- buildForAbi(
- Toolchain(ndk, abi, api),
- buildDir.asFile.get(),
- buildDirectory = buildDirectoryFor(abi),
- installDirectory = installDirectoryFor(abi),
- )
- }
- }
-
- abstract fun buildForAbi(
- toolchain: Toolchain,
- workingDirectory: File,
- buildDirectory: File,
- installDirectory: File
- )
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt b/buildSrc/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt
deleted file mode 100644
index 27be792..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ndkports
-
-import com.google.prefab.api.AndroidAbiMetadata
-import com.google.prefab.api.ModuleMetadataV1
-import com.google.prefab.api.PackageMetadataV1
-import kotlinx.serialization.encodeToString
-import kotlinx.serialization.json.Json
-import org.redundent.kotlin.xml.xml
-import java.io.File
-import java.io.Serializable
-
-data class PackageData(
- val name: String,
- val mavenVersion: String,
- val prefabVersion: CMakeCompatibleVersion,
- val minSdkVersion: Int,
- val licensePath: String,
- val modules: List<ModuleDescription>,
- val dependencies: Map<String, String>,
-)
-
-/**
- * A module exported by the package.
- *
- * As currently implemented by ndkports, one module is exactly one library.
- * Prefab supports header-only libraries, but ndkports does not support these
- * yet.
- *
- * Static libraries are not currently supported by ndkports.
- *
- * @property[name] The name of the module. Note that currently the name of the
- * installed library file must be exactly `lib$name.so`.
- * @property[includesPerAbi] Set to true if a different set of headers should be
- * exposed per-ABI. Not currently implemented.
- * @property[dependencies] A list of other modules required by this module, in
- * the format described by https://google.github.io/prefab/.
- */
-data class ModuleDescription(
- val name: String,
- val static: Boolean,
- val headerOnly: Boolean,
- val includesPerAbi: Boolean,
- val dependencies: List<String>,
-) : Serializable
-
-class PrefabPackageBuilder(
- private val packageData: PackageData,
- private val packageDirectory: File,
- private val directory: File,
- private val sourceDirectory: File,
- private val ndk: Ndk,
-) {
- private val prefabDirectory = packageDirectory.resolve("prefab")
- private val modulesDirectory = prefabDirectory.resolve("modules")
-
- // TODO: Get from gradle.
- private val packageName = "com.android.ndk.thirdparty.${packageData.name}"
-
- private fun preparePackageDirectory() {
- if (packageDirectory.exists()) {
- packageDirectory.deleteRecursively()
- }
- modulesDirectory.mkdirs()
- }
-
- private fun makePackageMetadata() {
- prefabDirectory.resolve("prefab.json").writeText(
- Json.encodeToString(
- PackageMetadataV1(
- packageData.name,
- schemaVersion = 1,
- dependencies = packageData.dependencies.keys.toList(),
- version = packageData.prefabVersion.toString()
- )
- )
- )
- }
-
- private fun makeModuleMetadata(module: ModuleDescription, moduleDirectory: File) {
- moduleDirectory.resolve("module.json").writeText(
- Json.encodeToString(
- ModuleMetadataV1(
- exportLibraries = module.dependencies
- )
- )
- )
- }
-
- private fun installLibForAbi(module: ModuleDescription, abi: Abi, libsDir: File) {
- val extension = if (module.static) "a" else "so"
- val libName = "lib${module.name}.${extension}"
- val installDirectory = libsDir.resolve("android.${abi.abiName}").apply {
- mkdirs()
- }
-
- directory.resolve("$abi/lib/$libName")
- .copyTo(installDirectory.resolve(libName))
-
- installDirectory.resolve("abi.json").writeText(
- Json.encodeToString(
- AndroidAbiMetadata(
- abi = abi.abiName,
- api = abi.adjustMinSdkVersion(packageData.minSdkVersion),
- ndk = ndk.version.major,
- stl = "c++_shared"
- )
- )
- )
- }
-
- private fun installLicense() {
- val src = sourceDirectory.resolve(packageData.licensePath)
- val dest = packageDirectory.resolve("META-INF")
- .resolve(File(packageData.licensePath).name)
- src.copyTo(dest)
- }
-
- private fun createAndroidManifest() {
- packageDirectory.resolve("AndroidManifest.xml")
- .writeText(xml("manifest") {
- attributes(
- "xmlns:android" to "http://schemas.android.com/apk/res/android",
- "package" to packageName,
- "android:versionCode" to 1,
- "android:versionName" to "1.0"
- )
-
- "uses-sdk" {
- attributes(
- "android:minSdkVersion" to packageData.minSdkVersion,
- "android:targetSdkVersion" to 29
- )
- }
- }.toString())
- }
-
- fun build() {
- preparePackageDirectory()
- makePackageMetadata()
- for (module in packageData.modules) {
- val moduleDirectory = modulesDirectory.resolve(module.name).apply {
- mkdirs()
- }
-
- makeModuleMetadata(module, moduleDirectory)
-
- if (module.includesPerAbi) {
- TODO()
- } else {
- // TODO: Check that headers are actually identical across ABIs.
- directory.resolve("${Abi.Arm}/include")
- .copyRecursively(moduleDirectory.resolve("include"))
- }
-
- if (!module.headerOnly) {
- val libsDir = moduleDirectory.resolve("libs").apply { mkdirs() }
- for (abi in Abi.values()) {
- installLibForAbi(module, abi, libsDir)
- }
- }
- }
-
- installLicense()
-
- createAndroidManifest()
- }
-}
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabSysrootPlugin.kt b/buildSrc/src/main/kotlin/com/android/ndkports/PrefabSysrootPlugin.kt
deleted file mode 100644
index 2828764..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabSysrootPlugin.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.android.ndkports
-
-import com.google.prefab.api.BuildSystemInterface
-import com.google.prefab.api.Module
-import com.google.prefab.api.Package
-import com.google.prefab.api.PlatformDataInterface
-import java.io.File
-
-class PrefabSysrootPlugin(
- override val outputDirectory: File, override val packages: List<Package>
-) : BuildSystemInterface {
-
- override fun generate(requirements: Collection<PlatformDataInterface>) {
- prepareOutputDirectory(outputDirectory)
-
- for (pkg in packages) {
- for (module in pkg.modules) {
- for (requirement in requirements) {
- installModule(module, requirement)
- }
- }
- }
- }
-
- private fun installModule(
- module: Module, requirement: PlatformDataInterface
- ) {
- val installDir = outputDirectory.resolve(requirement.targetTriple)
- val includeDir = installDir.resolve("include")
-
- if (module.isHeaderOnly) {
- installHeaders(module.includePath.toFile(), includeDir)
- return
- }
-
- val library = module.getLibraryFor(requirement)
- installHeaders(module.includePath.toFile(), includeDir)
- val libDir = installDir.resolve("lib").apply {
- mkdirs()
- }
- library.path.toFile().apply { copyTo(libDir.resolve(name)) }
- }
-
- private fun installHeaders(src: File, dest: File) {
- src.copyRecursively(dest) { file, exception ->
- if (exception !is FileAlreadyExistsException) {
- throw exception
- }
-
- if (!file.readBytes().contentEquals(exception.file.readBytes())) {
- val path = file.relativeTo(dest)
- throw RuntimeException(
- "Found duplicate headers with non-equal contents: $path"
- )
- }
-
- OnErrorAction.SKIP
- }
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/PrefabTask.kt
deleted file mode 100644
index d58f1fa..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/PrefabTask.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.android.ndkports
-
-import com.google.prefab.api.Android
-import com.google.prefab.api.BuildSystemInterface
-import com.google.prefab.api.Package
-import org.gradle.api.DefaultTask
-import org.gradle.api.file.Directory
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.file.FileCollection
-import org.gradle.api.provider.Property
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.Optional
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-import java.io.File
-import java.util.zip.ZipFile
-
-abstract class PrefabTask : DefaultTask() {
- @InputFiles
- lateinit var aars: FileCollection
-
- @get:OutputDirectory
- abstract val outputDirectory: DirectoryProperty
-
- @get:OutputDirectory
- val generatedDirectory: Provider<Directory>
- get() = outputDirectory.dir("generated")
-
- @get:Optional
- @get:Input
- abstract val generator: Property<Class<out BuildSystemInterface>>
-
- @get:InputDirectory
- abstract val ndkPath: DirectoryProperty
-
- @get:Input
- abstract val minSdkVersion: Property<Int>
-
- private val ndk: Ndk
- get() = Ndk(ndkPath.asFile.get())
-
- @TaskAction
- fun run() {
- if (!generator.isPresent) {
- // Creating the generated directory even if we have no generator
- // makes it easier to write tasks that *might* consume prefab
- // packages.
- generatedDirectory.get().asFile.mkdirs()
- return
- }
-
- val outDir = outputDirectory.get().asFile
- val packages = mutableListOf<Package>()
- for (aar in aars) {
- val packagePath = outDir.resolve(aar.nameWithoutExtension)
- extract(aar, packagePath)
- packages.add(Package(packagePath.toPath().resolve("prefab")))
- }
- generateSysroot(packages, minSdkVersion.get(), ndk.version.major)
- }
-
- private fun extract(aar: File, extractDir: File) {
- ZipFile(aar).use { zip ->
- zip.entries().asSequence().forEach { entry ->
- zip.getInputStream(entry).use { input ->
- val outFile = extractDir.resolve(entry.name)
- if (entry.isDirectory) {
- outFile.mkdirs()
- } else {
- outFile.outputStream().use { output ->
- input.copyTo(output)
- }
- }
- }
- }
- }
- }
-
- private fun generateSysroot(
- packages: List<Package>, osVersion: Int, ndkVersion: Int
- ) {
- val generatorType = generator.get()
- val constructor =
- generatorType.getConstructor(File::class.java, List::class.java)
- val buildSystemIntegration =
- constructor.newInstance(generatedDirectory.get().asFile, packages)
-
- buildSystemIntegration.generate(Android.Abi.values().map {
- Android(it, osVersion, Android.Stl.CxxShared, ndkVersion)
- })
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/SourceExtractTask.kt b/buildSrc/src/main/kotlin/com/android/ndkports/SourceExtractTask.kt
deleted file mode 100644
index 4f2660f..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/SourceExtractTask.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.android.ndkports
-
-import org.gradle.api.DefaultTask
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.file.RegularFileProperty
-import org.gradle.api.tasks.InputFile
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-
-abstract class SourceExtractTask : DefaultTask() {
- @get:InputFile
- abstract val source: RegularFileProperty
-
- @get:OutputDirectory
- abstract val outDir: DirectoryProperty
-
- @TaskAction
- fun run() {
- val pb = ProcessBuilder(
- listOf(
- "tar",
- "xf",
- source.get().asFile.absolutePath,
- "--strip-components=1"
- )
- ).redirectErrorStream(true).directory(outDir.get().asFile)
-
- val result = pb.start()
- val output = result.inputStream.bufferedReader().use { it.readText() }
- if (result.waitFor() != 0) {
- throw RuntimeException("Subprocess failed with:\n$output")
- }
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/Testing.kt b/buildSrc/src/main/kotlin/com/android/ndkports/Testing.kt
deleted file mode 100644
index 203e04f..0000000
--- a/buildSrc/src/main/kotlin/com/android/ndkports/Testing.kt
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.android.ndkports
-
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.SendChannel
-import kotlinx.coroutines.channels.toList
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import org.gradle.api.DefaultTask
-import org.gradle.api.file.DirectoryProperty
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.TaskAction
-import java.io.File
-
-sealed class TestResult(val name: String, val abi: Abi) {
- class Success(name: String, abi: Abi) : TestResult(name, abi) {
- override fun toString(): String = "PASS $abi $name"
- }
-
- class Failure(name: String, abi: Abi, private val output: String) :
- TestResult(name, abi) {
- override fun toString(): String = "FAIL $abi $name: $output"
- }
-}
-
-private val BASE_DEVICE_DIRECTORY = File("/data/local/tmp/ndkports")
-
-data class PushSpec(val src: File, val dest: File)
-
-class PushBuilder(val abi: Abi, val toolchain: Toolchain) {
- val pushSpecs = mutableListOf<PushSpec>()
-
- fun push(src: File, dest: File) = pushSpecs.add(PushSpec(src, dest))
-}
-
-data class ShellTestSpec(val name: String, val cmd: Iterable<String>)
-
-class ShellTestBuilder(val deviceDirectory: File, val abi: Abi) {
- val runSpecs = mutableListOf<ShellTestSpec>()
-
- fun shellTest(name: String, cmd: Iterable<String>) =
- runSpecs.add(ShellTestSpec(name, cmd))
-}
-
-abstract class AndroidExecutableTestTask : DefaultTask() {
- @get:InputDirectory
- abstract val ndkPath: DirectoryProperty
-
- private val ndk: Ndk
- get() = Ndk(ndkPath.asFile.get())
-
- @get:Input
- abstract val minSdkVersion: Property<Int>
-
- @get:Input
- abstract val push: Property<PushBuilder.() -> Unit>
-
- fun push(block: PushBuilder.() -> Unit) = push.set(block)
-
- @get:Input
- abstract val run: Property<ShellTestBuilder.() -> Unit>
-
- fun run(block: ShellTestBuilder.() -> Unit) = run.set(block)
-
- private fun deviceDirectoryForAbi(abi: Abi): File =
- BASE_DEVICE_DIRECTORY.resolve(project.name).resolve(abi.toString())
-
- private suspend fun runTests(
- device: Device, abi: Abi, resultChannel: SendChannel<TestResult>
- ) = coroutineScope {
- val deviceDirectory = deviceDirectoryForAbi(abi)
-
- val pushBlock = push.get()
- val runBlock = run.get()
-
- val pushBuilder =
- PushBuilder(abi, Toolchain(ndk, abi, minSdkVersion.get()))
- pushBuilder.pushBlock()
- coroutineScope {
- pushBuilder.pushSpecs.forEach {
- launch(Dispatchers.IO) {
- device.push(
- it.src, deviceDirectory.resolve(it.dest)
- )
- }
- }
- }
-
- val runBuilder = ShellTestBuilder(deviceDirectory, abi)
- runBuilder.runBlock()
- runBuilder.runSpecs.forEach {
- launch(Dispatchers.IO) {
- val result = try {
- device.shell(it.cmd)
- TestResult.Success(it.name, abi)
- } catch (ex: AdbException) {
- TestResult.Failure(it.name, abi, "${ex.cmd}\n${ex.output}")
- }
-
- resultChannel.send(result)
- }
- }
- }
-
- @Suppress("UnstableApiUsage")
- @TaskAction
- fun runTask() = runBlocking {
- val fleet = DeviceFleet()
- val warningChannel = Channel<String>(Channel.UNLIMITED)
- val resultChannel = Channel<TestResult>(Channel.UNLIMITED)
- coroutineScope {
- for (abi in Abi.values()) {
- launch {
- val device = fleet.findDeviceFor(
- abi, abi.adjustMinSdkVersion(minSdkVersion.get())
- )
- if (device == null) {
- warningChannel.send(
- "No device capable of running tests for $abi " +
- "minSdkVersion 21"
- )
- return@launch
- }
- device.shell(
- listOf(
- "rm", "-rf", deviceDirectoryForAbi(abi).toString()
- )
- )
- runTests(device, abi, resultChannel)
- }
- }
- }
- warningChannel.close()
- resultChannel.close()
-
- for (warning in warningChannel) {
- logger.warn(warning)
- }
-
- val failures =
- resultChannel.toList().filterIsInstance<TestResult.Failure>()
- if (failures.isNotEmpty()) {
- throw RuntimeException(
- "Tests failed:\n${failures.joinToString("\n")}"
- )
- }
- }
-}
\ No newline at end of file
diff --git a/curl/build.gradle.kts b/curl/build.gradle.kts
deleted file mode 100644
index 089ef04..0000000
--- a/curl/build.gradle.kts
+++ /dev/null
@@ -1,106 +0,0 @@
-import com.android.ndkports.AutoconfPortTask
-import com.android.ndkports.CMakeCompatibleVersion
-import com.android.ndkports.PrefabSysrootPlugin
-
-val portVersion = "7.79.1"
-
-group = "com.android.ndk.thirdparty"
-version = "$portVersion${rootProject.extra.get("snapshotSuffix")}"
-
-plugins {
- id("maven-publish")
- id("com.android.ndkports.NdkPorts")
-}
-
-dependencies {
- implementation(project(":openssl"))
-}
-
-ndkPorts {
- ndkPath.set(File(project.findProperty("ndkPath") as String))
- source.set(project.file("src.tar.gz"))
- minSdkVersion.set(16)
-}
-
-tasks.prefab {
- generator.set(PrefabSysrootPlugin::class.java)
-}
-
-tasks.register<AutoconfPortTask>("buildPort") {
- autoconf {
- args(
- "--disable-ntlm-wb",
- "--enable-ipv6",
- "--with-zlib",
- "--with-ca-path=/system/etc/security/cacerts",
- "--with-ssl=$sysroot"
- )
-
- // aarch64 still defaults to bfd which transitively checks libraries.
- // When curl is linking one of its own libraries which depends on
- // openssl, it doesn't pass -rpath-link to be able to find the SSL
- // libraries and fails to build because of it.
- //
- // TODO: Switch to lld once we're using r21.
- env("LDFLAGS", "-fuse-ld=gold")
- }
-}
-
-tasks.prefabPackage {
- version.set(CMakeCompatibleVersion.parse(portVersion))
-
- licensePath.set("COPYING")
-
- @Suppress("UnstableApiUsage") dependencies.set(
- mapOf(
- "openssl" to "1.1.1k"
- )
- )
-
- modules {
- create("curl") {
- dependencies.set(
- listOf(
- "//openssl:crypto", "//openssl:ssl"
- )
- )
- }
- }
-}
-
-publishing {
- publications {
- create<MavenPublication>("maven") {
- from(components["prefab"])
- pom {
- name.set("curl")
- description.set("The ndkports AAR for curl.")
- url.set(
- "https://android.googlesource.com/platform/tools/ndkports"
- )
- licenses {
- license {
- name.set("The curl License")
- url.set("https://curl.haxx.se/docs/copyright.html")
- distribution.set("repo")
- }
- }
- developers {
- developer {
- name.set("The Android Open Source Project")
- }
- }
- scm {
- url.set("https://android.googlesource.com/platform/tools/ndkports")
- connection.set("scm:git:https://android.googlesource.com/platform/tools/ndkports")
- }
- }
- }
- }
-
- repositories {
- maven {
- url = uri("${rootProject.buildDir}/repository")
- }
- }
-}
diff --git a/curl/src.tar.gz b/curl/src.tar.gz
deleted file mode 100644
index b6d3b85..0000000
--- a/curl/src.tar.gz
+++ /dev/null
Binary files differ
diff --git a/googletest/build.gradle.kts b/googletest/build.gradle.kts
deleted file mode 100644
index c365519..0000000
--- a/googletest/build.gradle.kts
+++ /dev/null
@@ -1,124 +0,0 @@
-import com.android.ndkports.AndroidExecutableTestTask
-import com.android.ndkports.CMakeCompatibleVersion
-import com.android.ndkports.CMakePortTask
-
-val portVersion = "1.11.0"
-
-group = "com.android.ndk.thirdparty"
-version = "$portVersion${rootProject.extra.get("snapshotSuffix")}"
-
-plugins {
- id("maven-publish")
- id("com.android.ndkports.NdkPorts")
-}
-
-ndkPorts {
- ndkPath.set(File(project.findProperty("ndkPath") as String))
- source.set(project.file("src.tar.gz"))
- minSdkVersion.set(16)
-}
-
-val buildTask = tasks.register<CMakePortTask>("buildPort") {
- cmake {
- arg("-Dgtest_build_tests=ON")
- arg("-Dgmock_build_tests=ON")
- }
-}
-
-tasks.prefabPackage {
- version.set(CMakeCompatibleVersion.parse(portVersion))
-
- modules {
- create("gtest") {
- static.set(true)
- }
- create("gtest_main") {
- static.set(true)
- }
- create("gmock") {
- static.set(true)
- }
- create("gmock_main") {
- static.set(true)
- }
- }
-}
-
-fun findTests(directory: File) = directory.listFiles()!!.filter {
- // There are also many tests that end with test_, but those require running
- // Python on the device.
- it.name.endsWith("test")
-}
-
-tasks.register<AndroidExecutableTestTask>("test") {
- push {
- val buildDir = buildTask.get().buildDirectoryFor(abi)
- findTests(buildDir.resolve("googlemock")).forEach { test ->
- push(test, File("googlemock").resolve(test.name))
- }
- findTests(buildDir.resolve("googletest")).forEach { test ->
- push(test, File("googletest").resolve(test.name))
- }
- }
-
- run {
- val buildDir = buildTask.get().buildDirectoryFor(abi)
- findTests(buildDir.resolve("googlemock")).forEach { test ->
- shellTest(
- test.name, listOf(
- "cd",
- deviceDirectory.resolve("googlemock").toString(),
- "&&",
- "./${test.name}"
- )
- )
- }
- findTests(buildDir.resolve("googletest")).forEach { test ->
- shellTest(
- test.name, listOf(
- "cd",
- deviceDirectory.resolve("googletest").toString(),
- "&&",
- "./${test.name}"
- )
- )
- }
- }
-}
-
-publishing {
- publications {
- create<MavenPublication>("maven") {
- from(components["prefab"])
- pom {
- name.set("GoogleTest")
- description.set("The ndkports AAR for GoogleTest.")
- url.set(
- "https://android.googlesource.com/platform/tools/ndkports"
- )
- licenses {
- license {
- name.set("BSD-3-Clause License")
- url.set("https://github.com/google/googletest/blob/master/LICENSE")
- distribution.set("repo")
- }
- }
- developers {
- developer {
- name.set("The Android Open Source Project")
- }
- }
- scm {
- url.set("https://android.googlesource.com/platform/tools/ndkports")
- connection.set("scm:git:https://android.googlesource.com/platform/tools/ndkports")
- }
- }
- }
- }
-
- repositories {
- maven {
- url = uri("${rootProject.buildDir}/repository")
- }
- }
-}
diff --git a/googletest/src.tar.gz b/googletest/src.tar.gz
deleted file mode 100644
index 8163d74..0000000
--- a/googletest/src.tar.gz
+++ /dev/null
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c..94336fc 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index da9702f..7c4388a 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 4f906e0..cccdd3d 100755
--- a/gradlew
+++ b/gradlew
@@ -1,21 +1,5 @@
#!/usr/bin/env sh
-#
-# Copyright 2015 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
##############################################################################
##
## Gradle start up script for UN*X
@@ -44,7 +28,7 @@
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -82,7 +66,6 @@
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -126,11 +109,10 @@
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -156,19 +138,19 @@
else
eval `echo args$i`="\"$arg\""
fi
- i=`expr $i + 1`
+ i=$((i+1))
done
case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -177,9 +159,14 @@
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
-APP_ARGS=`save "$@"`
+APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..f955316 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,19 +1,3 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -29,18 +13,15 @@
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +35,7 @@
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto execute
+if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,14 +45,28 @@
goto fail
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
diff --git a/jsoncpp/build.gradle.kts b/jsoncpp/build.gradle.kts
deleted file mode 100644
index 29ffc66..0000000
--- a/jsoncpp/build.gradle.kts
+++ /dev/null
@@ -1,103 +0,0 @@
-import com.android.ndkports.AndroidExecutableTestTask
-import com.android.ndkports.CMakeCompatibleVersion
-import com.android.ndkports.MesonPortTask
-
-val portVersion = "1.9.5"
-
-group = "com.android.ndk.thirdparty"
-version = "$portVersion${rootProject.extra.get("snapshotSuffix")}"
-
-plugins {
- id("maven-publish")
- id("com.android.ndkports.NdkPorts")
-}
-
-ndkPorts {
- ndkPath.set(File(project.findProperty("ndkPath") as String))
- source.set(project.file("src.tar.gz"))
- minSdkVersion.set(16)
-}
-
-tasks.extractSrc {
- doLast {
- // jsoncpp has a "version" file on the include path that conflicts with
- // https://en.cppreference.com/w/cpp/header/version. Remove it so we can
- // build.
- outDir.get().asFile.resolve("version").delete()
- }
-}
-
-val buildTask = tasks.register<MesonPortTask>("buildPort")
-
-tasks.prefabPackage {
- version.set(CMakeCompatibleVersion.parse(portVersion))
-
- modules {
- create("jsoncpp")
- }
-}
-
-tasks.register<AndroidExecutableTestTask>("test") {
- push {
- push(
- buildTask.get().buildDirectoryFor(abi).resolve("jsoncpp_test"),
- File("jsoncpp_test")
- )
- push(
- buildTask.get().installDirectoryFor(abi)
- .resolve("lib/libjsoncpp.so"), File("libjsoncpp.so")
- )
- push(
- toolchain.sysrootLibs.resolve("libc++_shared.so"),
- File("libc++_shared.so")
- )
- }
-
- run {
- // JsonCpp has other tests, but they require running Python on the
- // device.
- shellTest(
- "jsoncpp_test", listOf(
- "LD_LIBRARY_PATH=$deviceDirectory",
- deviceDirectory.resolve("jsoncpp_test").toString()
- )
- )
- }
-}
-
-publishing {
- publications {
- create<MavenPublication>("maven") {
- from(components["prefab"])
- pom {
- name.set("JsonCpp")
- description.set("The ndkports AAR for JsonCpp.")
- url.set(
- "https://android.googlesource.com/platform/tools/ndkports"
- )
- licenses {
- license {
- name.set("The JsonCpp License")
- url.set("https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE")
- distribution.set("repo")
- }
- }
- developers {
- developer {
- name.set("The Android Open Source Project")
- }
- }
- scm {
- url.set("https://android.googlesource.com/platform/tools/ndkports")
- connection.set("scm:git:https://android.googlesource.com/platform/tools/ndkports")
- }
- }
- }
- }
-
- repositories {
- maven {
- url = uri("${rootProject.buildDir}/repository")
- }
- }
-}
diff --git a/jsoncpp/src.tar.gz b/jsoncpp/src.tar.gz
deleted file mode 100644
index 35052af..0000000
--- a/jsoncpp/src.tar.gz
+++ /dev/null
Binary files differ
diff --git a/openssl/build.gradle.kts b/openssl/build.gradle.kts
deleted file mode 100644
index b7c7a48..0000000
--- a/openssl/build.gradle.kts
+++ /dev/null
@@ -1,180 +0,0 @@
-import com.android.ndkports.AdHocPortTask
-import com.android.ndkports.AndroidExecutableTestTask
-import com.android.ndkports.CMakeCompatibleVersion
-
-fun openSslVersionToCMakeVersion(openSslVersion: String): CMakeCompatibleVersion {
- val (major, minor, microAndLetter) = openSslVersion.split(".")
- val letter = microAndLetter.last()
- val micro = microAndLetter.substringBefore(letter)
- val tweak = if (letter.isDigit()) {
- // 1.1.1 is 1.1.1.0.
- 0
- } else {
- // 1.1.1a is 1.1.1.1.
- letter.toInt() - 'a'.toInt() + 1
- }
-
- return CMakeCompatibleVersion(
- major.toInt(), minor.toInt(), micro.toInt(), tweak
- )
-}
-
-val portVersion = "1.1.1l"
-val prefabVersion = openSslVersionToCMakeVersion(portVersion)
-
-group = "com.android.ndk.thirdparty"
-version = "$portVersion${rootProject.extra.get("snapshotSuffix")}"
-
-plugins {
- id("maven-publish")
- id("com.android.ndkports.NdkPorts")
-}
-
-ndkPorts {
- ndkPath.set(File(project.findProperty("ndkPath") as String))
- source.set(project.file("src.tar.gz"))
- minSdkVersion.set(16)
-}
-
-val buildTask = tasks.register<AdHocPortTask>("buildPort") {
- builder {
- run {
- args(
- sourceDirectory.resolve("Configure").absolutePath,
- "android-${toolchain.abi.archName}",
- "-D__ANDROID_API__=${toolchain.api}",
- "--prefix=${installDirectory.absolutePath}",
- "--openssldir=${installDirectory.absolutePath}",
- "no-sctp",
- "shared"
- )
-
- env("ANDROID_NDK", toolchain.ndk.path.absolutePath)
- env("PATH", "${toolchain.binDir}:${System.getenv("PATH")}")
- }
-
- run {
- args("make", "-j$ncpus", "SHLIB_EXT=.so")
-
- env("ANDROID_NDK", toolchain.ndk.path.absolutePath)
- env("PATH", "${toolchain.binDir}:${System.getenv("PATH")}")
- }
-
- run {
- args("make", "install_sw", "SHLIB_EXT=.so")
-
- env("ANDROID_NDK", toolchain.ndk.path.absolutePath)
- env("PATH", "${toolchain.binDir}:${System.getenv("PATH")}")
- }
- }
-}
-
-tasks.prefabPackage {
- version.set(prefabVersion)
-
- modules {
- create("crypto")
- create("ssl")
- }
-}
-
-tasks.register<AndroidExecutableTestTask>("test") {
- val srcDir = tasks.extractSrc.get().outDir.asFile.get()
- val testSrc = srcDir.resolve("test/ssl-tests")
- val deviceTestRelPath = File("testconf")
-
- val unsupportedTests = listOf(
- // This test is empty and appears to just be broken in 1.1.1k.
- "16-certstatus.conf",
- // zlib support is not enabled.
- "22-compression.conf",
- // Android does not support SCTP sockets and this test requires them.
- "29-dtls-sctp-label-bug.conf"
- )
-
- push {
- val ignoredExtensions = listOf("o", "d")
- val buildDirectory = buildTask.get().buildDirectoryFor(abi)
- push(
- srcDir.resolve("test/ct/log_list.conf"), File("log_list.conf")
- )
- for (file in buildDirectory.walk()) {
- if (!file.isFile) {
- continue
- }
-
- if (file.extension in ignoredExtensions) {
- continue
- }
-
- push(file, file.relativeTo(buildDirectory))
- }
- for (file in testSrc.walk()) {
- if (file.extension == "conf") {
- push(
- file, deviceTestRelPath.resolve(file.relativeTo(testSrc))
- )
- }
- }
- push(srcDir.resolve("test/certs"), File("certs"))
- }
-
- run {
- // https://github.com/openssl/openssl/blob/master/test/README.ssltest.md
- val sslTest = deviceDirectory.resolve("test/ssl_test")
- val ctlogFile = deviceDirectory.resolve("log_list.conf")
- val testCertDir = deviceDirectory.resolve("certs")
- for (file in testSrc.walk()) {
- val test = deviceDirectory.resolve(deviceTestRelPath)
- .resolve(file.relativeTo(testSrc))
- if (file.extension == "conf" && file.name !in unsupportedTests) {
- shellTest(
- file.relativeTo(testSrc).toString(), listOf(
- "LD_LIBRARY_PATH=$deviceDirectory",
- "CTLOG_FILE=$ctlogFile",
- "TEST_CERTS_DIR=$testCertDir",
- sslTest.toString(),
- test.toString()
- )
- )
- }
- }
- }
-}
-
-publishing {
- publications {
- create<MavenPublication>("maven") {
- from(components["prefab"])
- pom {
- name.set("OpenSSL")
- description.set("The ndkports AAR for OpenSSL.")
- url.set(
- "https://android.googlesource.com/platform/tools/ndkports"
- )
- licenses {
- license {
- name.set("Dual OpenSSL and SSLeay License")
- url.set("https://www.openssl.org/source/license-openssl-ssleay.txt")
- distribution.set("repo")
- }
- }
- developers {
- developer {
- name.set("The Android Open Source Project")
- }
- }
- scm {
- url.set("https://android.googlesource.com/platform/tools/ndkports")
- connection.set("scm:git:https://android.googlesource.com/platform/tools/ndkports")
- }
- }
- }
- }
-
- repositories {
- maven {
- url = uri("${rootProject.buildDir}/repository")
- }
- }
-}
diff --git a/openssl/src.tar.gz b/openssl/src.tar.gz
deleted file mode 100644
index 81be7f9..0000000
--- a/openssl/src.tar.gz
+++ /dev/null
Binary files differ
diff --git a/ports/curl/port.kts b/ports/curl/port.kts
new file mode 100644
index 0000000..a870a86
--- /dev/null
+++ b/ports/curl/port.kts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+
+object : AutoconfPort() {
+ override val name = "curl"
+ override val version = "7.69.1"
+ override val mavenVersion = "$version-alpha-1"
+ override val licensePath = "COPYING"
+
+ override val license = License(
+ "The curl License", "https://curl.haxx.se/docs/copyright.html"
+ )
+
+ override val dependencies = listOf("openssl")
+
+ override val modules = listOf(
+ Module(
+ "curl",
+ dependencies = listOf("//openssl:crypto", "//openssl:ssl")
+ )
+ )
+
+ override fun configureArgs(
+ workingDirectory: File,
+ toolchain: Toolchain
+ ): List<String> {
+ val sslPrefix = installDirectoryForPort(
+ "openssl",
+ workingDirectory,
+ toolchain
+ ).absolutePath
+ return listOf(
+ "--disable-ntlm-wb",
+ "--enable-ipv6",
+ "--with-zlib",
+ "--with-ca-path=/system/etc/security/cacerts",
+ "--with-ssl=$sslPrefix"
+ )
+ }
+
+ override fun configureEnv(
+ workingDirectory: File,
+ toolchain: Toolchain
+ ): Map<String, String> = mapOf(
+ // aarch64 still defaults to bfd which transitively checks libraries.
+ // When curl is linking one of its own libraries which depends on
+ // openssl, it doesn't pass -rpath-link to be able to find the SSL
+ // libraries and fails to build because of it.
+ //
+ // TODO: Switch to lld once we're using r21.
+ "LDFLAGS" to "-fuse-ld=gold"
+ )
+}
diff --git a/ports/curl/src.tar.gz b/ports/curl/src.tar.gz
new file mode 100644
index 0000000..b0da690
--- /dev/null
+++ b/ports/curl/src.tar.gz
Binary files differ
diff --git a/ports/jsoncpp/port.kts b/ports/jsoncpp/port.kts
new file mode 100644
index 0000000..8a3e1ba
--- /dev/null
+++ b/ports/jsoncpp/port.kts
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+
+object : MesonPort() {
+ override val name = "jsoncpp"
+ override val version = "1.8.4"
+ override val mavenVersion = "$version-alpha-1"
+
+ override val license = License(
+ "The JsonCpp License",
+ "https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE"
+ )
+
+ override val modules = listOf(
+ Module("jsoncpp")
+ )
+
+ override fun extractSource(
+ sourceTarball: File,
+ sourceDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> =
+ super.extractSource(sourceTarball, sourceDirectory, workingDirectory)
+ .onSuccess {
+ // jsoncpp has a "version" file on the include path that
+ // conflicts with
+ // https://en.cppreference.com/w/cpp/header/version. Remove it
+ // so we can build.
+ sourceDirectory.resolve("version").delete()
+ }
+}
diff --git a/ports/jsoncpp/src.tar.gz b/ports/jsoncpp/src.tar.gz
new file mode 100644
index 0000000..7f3cd4b
--- /dev/null
+++ b/ports/jsoncpp/src.tar.gz
Binary files differ
diff --git a/ports/openssl/port.kts b/ports/openssl/port.kts
new file mode 100644
index 0000000..45b5206
--- /dev/null
+++ b/ports/openssl/port.kts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+
+object : Port() {
+ override val name = "openssl"
+ override val version = "1.1.1g"
+ override val mavenVersion = "$version-alpha-1"
+ override val prefabVersion = CMakeCompatibleVersion(1, 1, 1, 7)
+
+ override val license = License(
+ "Dual OpenSSL and SSLeay License",
+ "https://www.openssl.org/source/license-openssl-ssleay.txt"
+ )
+
+ override val modules = listOf(
+ Module("crypto"),
+ Module("ssl")
+ )
+
+ override fun configure(
+ toolchain: Toolchain,
+ sourceDirectory: File,
+ buildDirectory: File,
+ installDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> {
+ buildDirectory.mkdirs()
+ return executeProcessStep(
+ listOf(
+ sourceDirectory.resolve("Configure").absolutePath,
+ "android-${toolchain.abi.archName}",
+ "-D__ANDROID_API__=${toolchain.api}",
+ "--prefix=${installDirectory.absolutePath}",
+ "--openssldir=${installDirectory.absolutePath}",
+ "shared"
+ ),
+ buildDirectory,
+ additionalEnvironment = mapOf(
+ "ANDROID_NDK" to toolchain.ndk.path.absolutePath,
+ "PATH" to "${toolchain.binDir}:${System.getenv("PATH")}"
+ )
+ )
+ }
+
+ override fun build(
+ toolchain: Toolchain,
+ buildDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(
+ listOf(
+ "make",
+ "-j$ncpus",
+ "SHLIB_EXT=.so"
+ ), buildDirectory,
+ additionalEnvironment = mapOf(
+ "ANDROID_NDK" to toolchain.ndk.path.absolutePath,
+ "PATH" to "${toolchain.binDir}:${System.getenv("PATH")}"
+ )
+ )
+
+ override fun install(
+ toolchain: Toolchain,
+ buildDirectory: File,
+ installDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(
+ listOf("make", "install_sw", "SHLIB_EXT=.so"), buildDirectory,
+ additionalEnvironment = mapOf(
+ "ANDROID_NDK" to toolchain.ndk.path.absolutePath,
+ "PATH" to "${toolchain.binDir}:${System.getenv("PATH")}"
+ )
+ )
+}
diff --git a/ports/openssl/src.tar.gz b/ports/openssl/src.tar.gz
new file mode 100644
index 0000000..e768f9e
--- /dev/null
+++ b/ports/openssl/src.tar.gz
Binary files differ
diff --git a/scripts/build.sh b/scripts/build.sh
new file mode 100755
index 0000000..e7c16b6
--- /dev/null
+++ b/scripts/build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+docker build -t ndkports .
+docker run --rm -v $(pwd):/src ndkports
diff --git a/scripts/build_release.sh b/scripts/build_release.sh
deleted file mode 100755
index f99e223..0000000
--- a/scripts/build_release.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-set -e
-docker build -t ndkports .
-# We need to specify the full argument list for gradle explicitly because
-# there's no way to append to docker's CMD. This should be kept the same as the
-# default, but adding -Prelease.
-docker run --rm -v $(pwd):/src ndkports \
- --stacktrace -PndkPath=/ndk -Prelease release
diff --git a/scripts/build_snapshot.sh b/scripts/build_snapshot.sh
deleted file mode 100755
index 4c9d767..0000000
--- a/scripts/build_snapshot.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -e
-docker build -t ndkports .
-# Default command for the docker image handles the NDK location, --stacktrace,
-# task list, etc.
-docker run --rm -v $(pwd):/src ndkports
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 726326c..4549d2e 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -8,9 +8,4 @@
}
}
}
-}
-
-include("curl")
-include("googletest")
-include("jsoncpp")
-include("openssl")
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/android/ndkports/Abi.kt b/src/main/kotlin/com/android/ndkports/Abi.kt
new file mode 100644
index 0000000..58981a2
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/Abi.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+enum class Abi(val archName: String, val abiName: String) {
+ Arm("arm", "armeabi-v7a"),
+ Arm64("arm64", "arm64-v8a"),
+ X86("x86", "x86"),
+ X86_64("x86_64", "x86_64"),
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/android/ndkports/AutoconfPort.kt b/src/main/kotlin/com/android/ndkports/AutoconfPort.kt
new file mode 100644
index 0000000..1c009cb
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/AutoconfPort.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+
+abstract class AutoconfPort : Port() {
+ open fun configureArgs(
+ workingDirectory: File,
+ toolchain: Toolchain
+ ): List<String> = emptyList()
+
+ open fun configureEnv(
+ workingDirectory: File,
+ toolchain: Toolchain
+ ): Map<String, String> = emptyMap()
+
+ override fun configure(
+ toolchain: Toolchain,
+ sourceDirectory: File,
+ buildDirectory: File,
+ installDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> {
+ buildDirectory.mkdirs()
+ return executeProcessStep(
+ listOf(
+ "${sourceDirectory.absolutePath}/configure",
+ "--host=${toolchain.binutilsTriple}",
+ "--prefix=${installDirectory.absolutePath}"
+ ) + configureArgs(workingDirectory, toolchain),
+ buildDirectory,
+ additionalEnvironment = mutableMapOf(
+ "AR" to toolchain.ar.absolutePath,
+ "CC" to toolchain.clang.absolutePath,
+ "CXX" to toolchain.clangxx.absolutePath,
+ "RANLIB" to toolchain.ranlib.absolutePath,
+ "STRIP" to toolchain.strip.absolutePath,
+ "PATH" to "${toolchain.binDir}:${System.getenv("PATH")}"
+ ).apply { putAll(configureEnv(workingDirectory, toolchain)) }
+ )
+ }
+
+ override fun build(
+ toolchain: Toolchain,
+ buildDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(
+ listOf("make", "-j$ncpus"), buildDirectory
+ )
+
+ override fun install(
+ toolchain: Toolchain,
+ buildDirectory: File,
+ installDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(
+ listOf("make", "-j$ncpus", "install"), buildDirectory
+ )
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt b/src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt
similarity index 97%
rename from buildSrc/src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt
rename to src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt
index ba58ccb..6d3ee45 100644
--- a/buildSrc/src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt
+++ b/src/main/kotlin/com/android/ndkports/CMakeCompatibleVersion.kt
@@ -16,7 +16,7 @@
package com.android.ndkports
-import java.io.Serializable
+import java.io.File
/**
* A version number that is compatible with CMake's package version format.
@@ -31,7 +31,7 @@
val minor: Int?,
val patch: Int?,
val tweak: Int?
-) : Serializable {
+) {
init {
if (tweak != null) {
require(patch != null)
diff --git a/src/main/kotlin/com/android/ndkports/Cli.kt b/src/main/kotlin/com/android/ndkports/Cli.kt
new file mode 100644
index 0000000..e2a5879
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/Cli.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.multiple
+import com.github.ajalt.clikt.parameters.arguments.validate
+import com.github.ajalt.clikt.parameters.options.convert
+import com.github.ajalt.clikt.parameters.options.default
+import com.github.ajalt.clikt.parameters.options.flag
+import com.github.ajalt.clikt.parameters.options.option
+import com.github.ajalt.clikt.parameters.options.required
+import com.github.ajalt.clikt.parameters.types.file
+import de.swirtz.ktsrunner.objectloader.KtsObjectLoader
+import java.io.File
+import java.io.FileNotFoundException
+import java.lang.RuntimeException
+import kotlin.system.exitProcess
+
+class Cli : CliktCommand(help = "ndkports") {
+ private val outDir: File by option(
+ "-o",
+ "--out",
+ help = "Build directory."
+ ).file().default(File("out"))
+
+ private val publishToMavenLocal: Boolean by option(
+ help = "Publish AARs to the local Maven repository (~/.m2/repository)"
+ ).flag()
+
+ private val packages: List<String> by argument(
+ help = "Names of packages to build."
+ ).multiple().validate {
+ require(it.isNotEmpty()) { "must provide at least one package" }
+ }
+
+ private val ndk: Ndk by option().convert { Ndk(File(it)) }.required()
+
+ private fun portDirectoryFor(name: String): File =
+ File("ports").resolve(name)
+
+ private fun loadPort(name: String): Port {
+ val portDir = portDirectoryFor(name).also {
+ if (!it.exists()) {
+ throw FileNotFoundException("Could not find ${it.path}")
+ }
+ }
+
+ val portFile = portDir.resolve("port.kts").also {
+ if (!it.exists()) {
+ throw FileNotFoundException("Could not find ${it.path}")
+ }
+ }
+
+ return KtsObjectLoader().load(portFile.reader())
+ }
+
+ override fun run() {
+ println("Building packages: ${packages.joinToString(", ")}")
+ val portsByName = packages.map { loadPort(it) }.associateBy { it.name }
+ for (port in portsByName.values) {
+ val workingDirectory =
+ outDir.resolve(port.name).also { it.mkdirs() }
+
+ val sourceDirectory = workingDirectory.resolve("src")
+ val sourceTarball =
+ portDirectoryFor(port.name).resolve("src.tar.gz")
+
+ port.extractSource(sourceTarball, sourceDirectory, workingDirectory)
+
+ val apiForAbi = mapOf(
+ Abi.Arm to 16,
+ Abi.Arm64 to 21,
+ Abi.X86 to 16,
+ Abi.X86_64 to 21
+ )
+ for (abi in Abi.values()) {
+ val api = apiForAbi.getOrElse(abi) {
+ throw RuntimeException(
+ "No API level specified for ${abi.abiName}"
+ )
+ }
+ val toolchain = Toolchain(ndk, abi, api)
+
+ val buildDirectory = workingDirectory.resolve("build/$abi")
+ val installDirectory = installDirectoryForPort(
+ port.name, workingDirectory, toolchain
+ )
+
+ port.run(
+ toolchain,
+ sourceDirectory,
+ buildDirectory,
+ installDirectory,
+ workingDirectory
+ ).onFailure {
+ println(it)
+ exitProcess(1)
+ }
+ }
+
+ PrefabPackageBuilder(
+ port,
+ workingDirectory,
+ sourceDirectory,
+ publishToMavenLocal,
+ ndk,
+ apiForAbi,
+ portsByName
+ ).build()
+ }
+ }
+}
+
+fun main(args: Array<String>) {
+ Cli().main(args)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/android/ndkports/License.kt b/src/main/kotlin/com/android/ndkports/License.kt
new file mode 100644
index 0000000..8ec639f
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/License.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+data class License(val name: String, val url: String)
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/MesonPortTask.kt b/src/main/kotlin/com/android/ndkports/MesonPort.kt
similarity index 61%
rename from buildSrc/src/main/kotlin/com/android/ndkports/MesonPortTask.kt
rename to src/main/kotlin/com/android/ndkports/MesonPort.kt
index 6be9b9e..8c1f706 100644
--- a/buildSrc/src/main/kotlin/com/android/ndkports/MesonPortTask.kt
+++ b/src/main/kotlin/com/android/ndkports/MesonPort.kt
@@ -16,41 +16,24 @@
package com.android.ndkports
-import org.gradle.api.model.ObjectFactory
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
import java.io.File
-import javax.inject.Inject
-@Suppress("UnstableApiUsage")
-abstract class MesonPortTask @Inject constructor(objects: ObjectFactory) :
- PortTask() {
+abstract class MesonPort : Port() {
enum class DefaultLibraryType(val argument: String) {
- Both("both"), Shared("shared"), Static("static")
+ Both("both"),
+ Shared("shared"),
+ Static("static")
}
- @get:Input
- val defaultLibraryType: Property<DefaultLibraryType> =
- objects.property(DefaultLibraryType::class.java)
- .convention(DefaultLibraryType.Shared)
+ open val defaultLibraryType: DefaultLibraryType = DefaultLibraryType.Shared
- override fun buildForAbi(
+ override fun configure(
toolchain: Toolchain,
- workingDirectory: File,
+ sourceDirectory: File,
buildDirectory: File,
- installDirectory: File
- ) {
- configure(toolchain, workingDirectory, buildDirectory, installDirectory)
- build(buildDirectory)
- install(buildDirectory)
- }
-
- private fun configure(
- toolchain: Toolchain,
- workingDirectory: File,
- buildDirectory: File,
- installDirectory: File
- ) {
+ installDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> {
val cpuFamily = when (toolchain.abi) {
Abi.Arm -> "arm"
Abi.Arm64 -> "aarch64"
@@ -66,8 +49,7 @@
}
val crossFile = workingDirectory.resolve("cross_file.txt").apply {
- writeText(
- """
+ writeText("""
[binaries]
ar = '${toolchain.ar}'
c = '${toolchain.clang}'
@@ -79,11 +61,10 @@
cpu_family = '$cpuFamily'
cpu = '$cpu'
endian = 'little'
- """.trimIndent()
- )
+ """.trimIndent())
}
- executeSubprocess(
+ return executeProcessStep(
listOf(
"meson",
"--cross-file",
@@ -93,16 +74,23 @@
"--prefix",
installDirectory.absolutePath,
"--default-library",
- defaultLibraryType.get().argument,
- sourceDirectory.get().asFile.absolutePath,
+ defaultLibraryType.argument,
+ sourceDirectory.absolutePath,
buildDirectory.absolutePath
), workingDirectory
)
}
- private fun build(buildDirectory: File) =
- executeSubprocess(listOf("ninja", "-v"), buildDirectory)
+ override fun build(
+ toolchain: Toolchain,
+ buildDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(listOf("ninja", "-v"), buildDirectory)
- private fun install(buildDirectory: File) =
- executeSubprocess(listOf("ninja", "-v", "install"), buildDirectory)
+ override fun install(
+ toolchain: Toolchain,
+ buildDirectory: File,
+ installDirectory: File
+ ): Result<Unit, String> =
+ executeProcessStep(listOf("ninja", "-v", "install"), buildDirectory)
}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/Ndk.kt b/src/main/kotlin/com/android/ndkports/Ndk.kt
similarity index 94%
rename from buildSrc/src/main/kotlin/com/android/ndkports/Ndk.kt
rename to src/main/kotlin/com/android/ndkports/Ndk.kt
index 7ccd255..af66cb5 100644
--- a/buildSrc/src/main/kotlin/com/android/ndkports/Ndk.kt
+++ b/src/main/kotlin/com/android/ndkports/Ndk.kt
@@ -17,6 +17,7 @@
package com.android.ndkports
import java.io.File
+import java.lang.RuntimeException
class Ndk(val path: File) {
val version = NdkVersion.fromNdk(path)
@@ -35,5 +36,4 @@
private val toolchainDirectory = llvmBaseDir.resolve(hostTag)
val toolchainBinDirectory = toolchainDirectory.resolve("bin")
- val sysrootDirectory = toolchainDirectory.resolve("sysroot")
}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/NdkVersion.kt b/src/main/kotlin/com/android/ndkports/NdkVersion.kt
similarity index 100%
rename from buildSrc/src/main/kotlin/com/android/ndkports/NdkVersion.kt
rename to src/main/kotlin/com/android/ndkports/NdkVersion.kt
diff --git a/src/main/kotlin/com/android/ndkports/Port.kt b/src/main/kotlin/com/android/ndkports/Port.kt
new file mode 100644
index 0000000..2e0433f
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/Port.kt
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+
+@Suppress("unused")
+fun executeProcessStep(
+ args: List<String>,
+ workingDirectory: File,
+ additionalEnvironment: Map<String, String>? = null
+): Result<Unit, String> {
+ val pb = ProcessBuilder(args)
+ .redirectOutput(ProcessBuilder.Redirect.INHERIT)
+ .redirectError(ProcessBuilder.Redirect.INHERIT)
+ .directory(workingDirectory)
+
+ if (additionalEnvironment != null) {
+ pb.environment().putAll(additionalEnvironment)
+ }
+
+ return pb.start()
+ .waitFor().let {
+ if (it == 0) {
+ Result.Ok(Unit)
+ } else {
+ Result.Error("Process failed with exit code $it")
+ }
+ }
+}
+
+fun installDirectoryForPort(
+ name: String,
+ workingDirectory: File,
+ toolchain: Toolchain
+): File = workingDirectory.parentFile.resolve("$name/install/${toolchain.abi}")
+
+/**
+ * A module exported by the package.
+ *
+ * As currently implemented by ndkports, one module is exactly one library.
+ * Prefab supports header-only libraries, but ndkports does not support these
+ * yet.
+ *
+ * Static libraries are not currently supported by ndkports.
+ *
+ * @property[name] The name of the module. Note that currently the name of the
+ * installed library file must be exactly `lib$name.so`.
+ * @property[includesPerAbi] Set to true if a different set of headers should be
+ * exposed per-ABI. Not currently implemented.
+ * @property[dependencies] A list of other modules required by this module, in
+ * the format described by https://google.github.io/prefab/.
+ */
+data class Module(
+ val name: String,
+ val includesPerAbi: Boolean = false,
+ val dependencies: List<String> = emptyList()
+)
+
+/**
+ * The base class for all ports.
+ */
+abstract class Port {
+ /**
+ * The name of the port. Will be used as the package name in prefab.json.
+ */
+ abstract val name: String
+
+ /**
+ * The version of the package.
+ *
+ * Used as the default for [prefabVersion] and [mavenVersion] when
+ * appropriate.
+ */
+ abstract val version: String
+
+ /**
+ * The version to encode in the prefab.json.
+ *
+ * This version must be compatible with CMake's `find_package` for
+ * config-style packages. This means that it must be one to four decimal
+ * separated integers. No other format is allowed.
+ *
+ * If not set, the default is [version] as interpreted by
+ * [CMakeCompatibleVersion.parse].
+ *
+ * For example, OpenSSL 1.1.1g will set this value to
+ * `CMakeCompatibleVersion(1, 1, 1, 7)`.
+ */
+ open val prefabVersion: CMakeCompatibleVersion
+ get() = CMakeCompatibleVersion.parse(version)
+
+ /**
+ * The version to use for the maven package.
+ *
+ * This field allows versioning the maven package differently from the
+ * package itself, which is sometimes necessary given CMake's strict version
+ * format requirements.
+ *
+ * If not set, the default is [version].
+ *
+ * For example, this could be set to `"$name-$version-alpha-1"` to
+ * distribute an alpha of the package.
+ */
+ open val mavenVersion: String
+ get() = version
+
+ /**
+ * The relative path to the license file of this package.
+ *
+ * This file will be packaged in the AAR in the META-INF directory.
+ */
+ open val licensePath: String = "LICENSE"
+
+ /**
+ * A description of the license (name and URL) for use in the pom.xml.
+ */
+ abstract val license: License
+
+ /**
+ * A list of dependencies for this package.
+ *
+ * For example, curl depends on `listOf("openssl")`.
+ */
+ open val dependencies: List<String> = emptyList()
+
+ /**
+ * A list of modules exported by this package.
+ */
+ abstract val modules: List<Module>
+
+ /**
+ * The number of CPUs available for building.
+ *
+ * May be passed to the build system if required.
+ */
+ protected val ncpus = Runtime.getRuntime().availableProcessors()
+
+ fun run(
+ toolchain: Toolchain,
+ sourceDirectory: File,
+ buildDirectory: File,
+ installDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> {
+ configure(
+ toolchain,
+ sourceDirectory,
+ buildDirectory,
+ installDirectory,
+ workingDirectory
+ ).onFailure { return Result.Error(it) }
+
+ build(toolchain, buildDirectory).onFailure { return Result.Error(it) }
+
+ install(
+ toolchain,
+ buildDirectory,
+ installDirectory
+ ).onFailure { return Result.Error(it) }
+
+ return Result.Ok(Unit)
+ }
+
+ /**
+ * Overridable build step for extracting the source package.
+ *
+ * @param[sourceTarball] The path to the source tarball.
+ * @param[sourceDirectory] The destination directory for the extracted
+ * source.
+ * @param[workingDirectory] The working top-level directory for this
+ * package.
+ * @return A [Result<Unit, String>][Result] describing the result of the
+ * operation. On failure, [Result.Error<String>][Result.Error] containing an
+ * error message is returned.
+ */
+ open fun extractSource(
+ sourceTarball: File,
+ sourceDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> {
+ sourceDirectory.mkdirs()
+ return executeProcessStep(
+ listOf(
+ "tar",
+ "xf",
+ sourceTarball.absolutePath,
+ "--strip-components=1"
+ ), sourceDirectory
+ )
+ }
+
+ /**
+ * Overridable build step for configuring the build.
+ *
+ * Any pre-build steps should be run here.
+ *
+ * In an autoconf build, this runs `configure`.
+ *
+ * @param[toolchain] The toolchain used for this build.
+ * @param[sourceDirectory] The directory containing the extracted package
+ * source.
+ * @param[buildDirectory] The directory to use for building.
+ * @param[installDirectory] The destination directory for this package's
+ * installed headers and libraries.
+ * @param[workingDirectory] The top-level working directory for this
+ * package.
+ * @return A [Result<Unit, String>][Result] describing the result of the
+ * operation. On failure, [Result.Error<String>][Result.Error] containing an
+ * error message is returned.
+ */
+ open fun configure(
+ toolchain: Toolchain,
+ sourceDirectory: File,
+ buildDirectory: File,
+ installDirectory: File,
+ workingDirectory: File
+ ): Result<Unit, String> = Result.Ok(Unit)
+
+ /**
+ * Overridable build step for building the package.
+ *
+ * In an autoconf build, this runs `make`.
+ *
+ * @param[toolchain] The toolchain used for this build.
+ * @param[buildDirectory] The directory to use for building.
+ * @return A [Result<Unit, String>][Result] describing the result of the
+ * operation. On failure, [Result.Error<String>][Result.Error] containing an
+ * error message is returned.
+ */
+ open fun build(
+ toolchain: Toolchain,
+ buildDirectory: File
+ ): Result<Unit, String> = Result.Ok(Unit)
+
+ /**
+ * Overridable build step for installing built artifacts for packaging.
+ *
+ * The install step is expected to install headers and libraries to the
+ * [installDirectory] with the following layout:
+ *
+ * [installDirectory]
+ * include/
+ * <package headers>
+ * lib/
+ * <package libraries>
+ *
+ * A matching `lib${module.name}.so` must be present in the `lib` directory
+ * for every item in [modules].
+ *
+ * Note that it is expected for all modules to use the same headers. This is
+ * currently the case for all ports currently maintained, but could change
+ * in the future.
+ *
+ * In an autoconf build, this runs `make install`.
+ *
+ * @param[toolchain] The toolchain used for this build.
+ * @param[buildDirectory] The directory containing build artifacts.
+ * @param[installDirectory] The destination directory for this package's
+ * installed headers and libraries.
+ * @return A [Result<Unit, String>][Result] describing the result of the
+ * operation. On failure, [Result.Error<String>][Result.Error] containing an
+ * error message is returned.
+ */
+ open fun install(
+ toolchain: Toolchain,
+ buildDirectory: File,
+ installDirectory: File
+ ): Result<Unit, String> = Result.Ok(Unit)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt b/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt
new file mode 100644
index 0000000..1a58f5a
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/PrefabPackageBuilder.kt
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import com.google.prefab.api.AndroidAbiMetadata
+import com.google.prefab.api.ModuleMetadataV1
+import com.google.prefab.api.PackageMetadataV1
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.stringify
+import org.apache.maven.model.Dependency
+import org.apache.maven.model.Developer
+import org.apache.maven.model.License
+import org.apache.maven.model.Scm
+import org.apache.maven.model.io.DefaultModelWriter
+import org.apache.maven.project.MavenProject
+import org.redundent.kotlin.xml.xml
+import java.io.File
+
+class PrefabPackageBuilder(
+ private val port: Port,
+ private val directory: File,
+ private val sourceDirectory: File,
+ private val publishToMavenLocal: Boolean,
+ private val ndk: Ndk,
+ private val abiToApiMap: Map<Abi, Int>,
+ private val portsByName: Map<String, Port>
+) {
+ private val packageDirectory = directory.resolve("aar")
+ private val prefabDirectory = packageDirectory.resolve("prefab")
+ private val modulesDirectory = prefabDirectory.resolve("modules")
+
+ private val packageComponents = listOf(
+ "com",
+ "android",
+ "ndk",
+ "thirdparty",
+ port.name
+ )
+
+ private val packageName = packageComponents.joinToString(".")
+ private val groupComponents = packageComponents.dropLast(1)
+ private val groupId = groupComponents.joinToString(".")
+ private val artifactId = packageComponents.last()
+
+ private val mavenProject = MavenProject().also {
+ it.name = port.name
+ it.description = "The ndkports AAR for ${port.name}."
+ it.url = "https://android.googlesource.com/platform/tools/ndkports"
+ it.groupId = groupId
+ it.artifactId = artifactId
+ it.version = port.mavenVersion
+ it.packaging = "aar"
+ it.licenses = listOf(
+ License().also { license ->
+ license.name = port.license.name
+ license.url = port.license.url
+ license.distribution = "repo"
+ }
+ )
+ it.developers = listOf(
+ Developer().also { developer ->
+ developer.name = "The Android Open Source Project"
+ }
+ )
+ it.scm = Scm().also { scm ->
+ scm.url = "https://android.googlesource.com/platform/tools/ndkports"
+ scm.connection = "scm:git:https://android.googlesource.com/platform/tools/ndkports"
+ }
+ it.dependencies = port.dependencies.map { depName ->
+ val depPort = portsByName[depName] ?: throw RuntimeException(
+ "${port.name} depends on unknown port: $depName"
+ )
+ Dependency().also { dep ->
+ dep.artifactId = depPort.name
+ dep.groupId = groupId
+ dep.version = depPort.mavenVersion
+ dep.type = "aar"
+ // TODO: Make this an option in the Port.
+ // We currently only have one dependency from curl to OpenSSL,
+ // and that's (from the perspective of the AAR consumer), a
+ // runtime dependency. If we ever have compile dependencies,
+ // we'll want to make it possible for each port to customize its
+ // scope.
+ dep.scope = "runtime"
+ }
+ }
+ // TODO: Issue management?
+ }
+
+ private fun preparePackageDirectory() {
+ if (packageDirectory.exists()) {
+ packageDirectory.deleteRecursively()
+ }
+ modulesDirectory.mkdirs()
+ }
+
+ private fun makePackageMetadata() {
+ prefabDirectory.resolve("prefab.json").writeText(
+ Json.stringify(
+ PackageMetadataV1(
+ port.name,
+ schemaVersion = 1,
+ dependencies = port.dependencies,
+ version = port.prefabVersion.toString()
+ )
+ )
+ )
+ }
+
+ private fun makeModuleMetadata(module: Module, moduleDirectory: File) {
+ moduleDirectory.resolve("module.json").writeText(
+ Json.stringify(
+ ModuleMetadataV1(
+ exportLibraries = module.dependencies
+ )
+ )
+ )
+ }
+
+ private fun installLibForAbi(module: Module, abi: Abi, libsDir: File) {
+ val libName = "lib${module.name}.so"
+ val installDirectory = libsDir.resolve("android.${abi.abiName}").apply {
+ mkdirs()
+ }
+
+ directory.resolve("install/$abi/lib/$libName")
+ .copyTo(installDirectory.resolve(libName))
+
+ val api = abiToApiMap.getOrElse(abi) {
+ throw RuntimeException(
+ "No API level specified for ${abi.abiName}"
+ )
+ }
+
+ installDirectory.resolve("abi.json").writeText(
+ Json.stringify(
+ AndroidAbiMetadata(
+ abi = abi.abiName,
+ api = api,
+ ndk = ndk.version.major,
+ stl = "c++_shared"
+ )
+ )
+ )
+ }
+
+ private fun installLicense() {
+ val src = sourceDirectory.resolve(port.licensePath)
+ val dest = packageDirectory.resolve("META-INF")
+ .resolve(File(port.licensePath).name)
+ src.copyTo(dest)
+ }
+
+ private fun createAndroidManifest() {
+ packageDirectory.resolve("AndroidManifest.xml")
+ .writeText(xml("manifest") {
+ attributes(
+ "xmlns:android" to "http://schemas.android.com/apk/res/android",
+ "package" to packageName,
+ "android:versionCode" to 1,
+ "android:versionName" to "1.0"
+ )
+
+ "uses-sdk" {
+ attributes(
+ "android:minSdkVersion" to 16,
+ "android:targetSdkVersion" to 29
+ )
+ }
+ }.toString())
+ }
+
+ private fun createPom(pomFile: File) {
+ DefaultModelWriter().write(pomFile, null, mavenProject.model)
+ }
+
+ private fun installToLocalMaven(archive: File, pomFile: File) {
+ val pb = ProcessBuilder(
+ listOf(
+ "mvn",
+ "install:install-file",
+ "-Dfile=$archive",
+ "-DpomFile=$pomFile"
+ )
+ )
+ .redirectOutput(ProcessBuilder.Redirect.INHERIT)
+ .redirectError(ProcessBuilder.Redirect.INHERIT)
+
+ return pb.start()
+ .waitFor().let {
+ if (it != 0) {
+ throw RuntimeException(
+ "Failed to install archive to local maven " +
+ "repository: $archive $pomFile"
+ )
+ }
+ }
+ }
+
+ private fun createArchive() {
+ val archive = directory.resolve("${port.name}-${port.mavenVersion}.aar")
+ val pomFile = directory.resolve("${port.name}-${port.mavenVersion}.pom")
+ createZipFromDirectory(archive, packageDirectory)
+ createPom(pomFile)
+ if (publishToMavenLocal) {
+ installToLocalMaven(archive, pomFile)
+ }
+ }
+
+ fun build() {
+ preparePackageDirectory()
+ makePackageMetadata()
+ for (module in port.modules) {
+ val moduleDirectory = modulesDirectory.resolve(module.name).apply {
+ mkdirs()
+ }
+
+ makeModuleMetadata(module, moduleDirectory)
+
+ if (module.includesPerAbi) {
+ TODO()
+ } else {
+ // TODO: Perform sanity check.
+ directory.resolve("install/${Abi.Arm}/include")
+ .copyRecursively(moduleDirectory.resolve("include"))
+ }
+
+ val libsDir = moduleDirectory.resolve("libs").apply { mkdirs() }
+ for (abi in Abi.values()) {
+ installLibForAbi(module, abi, libsDir)
+ }
+ }
+
+ installLicense()
+
+ createAndroidManifest()
+ createArchive()
+ }
+}
diff --git a/src/main/kotlin/com/android/ndkports/Result.kt b/src/main/kotlin/com/android/ndkports/Result.kt
new file mode 100644
index 0000000..21c203e
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/Result.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+sealed class Result<out T, out E> {
+ data class Ok<T>(val value: T) : Result<T, Nothing>()
+ data class Error<E>(val error: E) : Result<Nothing, E>()
+
+ inline fun onSuccess(block: (T) -> Unit): Result<T, E> {
+ if (this is Ok<T>) {
+ block(value)
+ }
+ return this
+ }
+
+ inline fun onFailure(block: (E) -> Unit): Result<T, E> {
+ if (this is Error<E>) {
+ block(error)
+ }
+ return this
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/com/android/ndkports/Toolchain.kt b/src/main/kotlin/com/android/ndkports/Toolchain.kt
similarity index 94%
rename from buildSrc/src/main/kotlin/com/android/ndkports/Toolchain.kt
rename to src/main/kotlin/com/android/ndkports/Toolchain.kt
index 1293ecb..d42e8d1 100644
--- a/buildSrc/src/main/kotlin/com/android/ndkports/Toolchain.kt
+++ b/src/main/kotlin/com/android/ndkports/Toolchain.kt
@@ -29,8 +29,6 @@
else -> "$binutilsTriple$api"
}
- val sysrootLibs = ndk.sysrootDirectory.resolve("usr/lib/$binutilsTriple")
-
val binDir = ndk.toolchainBinDirectory
val ar = binDir.resolve("$binutilsTriple-ar")
val clang = binDir.resolve("$clangTriple-clang")
diff --git a/src/main/kotlin/com/android/ndkports/Zip.kt b/src/main/kotlin/com/android/ndkports/Zip.kt
new file mode 100644
index 0000000..a23ff90
--- /dev/null
+++ b/src/main/kotlin/com/android/ndkports/Zip.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.util.zip.ZipEntry
+import java.util.zip.ZipOutputStream
+
+private fun zipDirectory(name: String, zipOut: ZipOutputStream) {
+ zipOut.putNextEntry(ZipEntry("$name/"))
+ zipOut.closeEntry()
+}
+
+private fun zipFile(file: File, name: String, zipOut: ZipOutputStream) {
+ zipOut.putNextEntry(ZipEntry(name))
+ FileInputStream(file).use {
+ it.copyTo(zipOut)
+ }
+}
+
+private fun zip(file: File, name: String, zipOut: ZipOutputStream) {
+ if (file.isDirectory) {
+ zipDirectory(name, zipOut)
+ } else {
+ zipFile(file, name, zipOut)
+ }
+}
+
+fun createZipFromDirectory(output: File, input: File) {
+ FileOutputStream(output).use { fos ->
+ ZipOutputStream(fos).use { zos ->
+ input.walk().filter { it != input }.forEach {
+ zip(it, it.relativeTo(input).path, zos)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/test/kotlin/com/android/ndkports/CMakeCompatibleVersionTest.kt b/src/test/kotlin/com/android/ndkports/CMakeCompatibleVersionTest.kt
similarity index 100%
rename from buildSrc/src/test/kotlin/com/android/ndkports/CMakeCompatibleVersionTest.kt
rename to src/test/kotlin/com/android/ndkports/CMakeCompatibleVersionTest.kt
diff --git a/buildSrc/src/test/kotlin/com/android/ndkports/NdkVersionTest.kt b/src/test/kotlin/com/android/ndkports/NdkVersionTest.kt
similarity index 100%
rename from buildSrc/src/test/kotlin/com/android/ndkports/NdkVersionTest.kt
rename to src/test/kotlin/com/android/ndkports/NdkVersionTest.kt
diff --git a/src/test/kotlin/com/android/ndkports/ResultTest.kt b/src/test/kotlin/com/android/ndkports/ResultTest.kt
new file mode 100644
index 0000000..0abef18
--- /dev/null
+++ b/src/test/kotlin/com/android/ndkports/ResultTest.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ndkports
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+class ResultTest {
+ @Test
+ fun `onFailure executes block on failure`() {
+ val result = Result.Error("foo")
+ result.onFailure {
+ assertEquals("foo", it)
+ return
+ }
+ fail()
+ }
+
+ @Test
+ fun `onFailure does not execute block on success`() {
+ val result = Result.Ok(Unit)
+ result.onFailure { fail() }
+ }
+
+ @Test
+ fun `onFailure returns same result object`() {
+ val result = Result.Error(Unit)
+ assertEquals(result, result.onFailure {})
+ }
+
+ @Test
+ fun `onSuccess executes block on success`() {
+ val result = Result.Ok("foo")
+ result.onSuccess {
+ assertEquals("foo", it)
+ return
+ }
+ fail()
+ }
+
+ @Test
+ fun `onSuccess does not execute block on failure`() {
+ val result = Result.Error(Unit)
+ result.onSuccess { fail() }
+ }
+
+ @Test
+ fun `onSuccess returns same result object`() {
+ val result = Result.Ok(Unit)
+ assertEquals(result, result.onSuccess {})
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/test/resources/junit-platform.properties b/src/test/resources/junit-platform.properties
similarity index 100%
rename from buildSrc/src/test/resources/junit-platform.properties
rename to src/test/resources/junit-platform.properties