Skip to content

Commit

Permalink
RUM-7461: supporting custom ndk symbols path
Browse files Browse the repository at this point in the history
  • Loading branch information
satween committed Jan 10, 2025
1 parent f5e5a4f commit c74ab9a
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ class DdAndroidGradlePlugin @Inject constructor(
) {
val isObfuscationEnabled = isObfuscationEnabled(variant, datadogExtension)
val isNativeBuildRequired = variant.isNativeBuildEnabled
val isNativeSymbolsTaskRequired =
isNativeBuildRequired || datadogExtension.additionalSymbolFilesLocations?.isNotEmpty() == true

if (isObfuscationEnabled || isNativeBuildRequired) {
if (isObfuscationEnabled || isNativeBuildRequired || isNativeSymbolsTaskRequired) {
val buildIdGenerationTask =
configureBuildIdGenerationTask(target, variant)

Expand All @@ -115,7 +117,7 @@ class DdAndroidGradlePlugin @Inject constructor(
LOGGER.info("Minifying disabled for variant ${variant.name}, no mapping file upload task created")
}

if (isNativeBuildRequired) {
if (isNativeSymbolsTaskRequired) {
configureNdkSymbolUploadTask(
target,
datadogExtension,
Expand All @@ -126,6 +128,7 @@ class DdAndroidGradlePlugin @Inject constructor(
} else {
LOGGER.info(
"No native build tasks found for variant ${variant.name}," +
" no additionalSymbolFilesLocations provided, " +
" no NDK symbol file upload task created."
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,30 @@ open class DdExtensionConfiguration(
*/
var ignoreDatadogCiFileConfig: Boolean = false

/**
* Additional locations that Gradle plugin will check for `.so` files during `uploadNdkSymbolFiles` task.
* Directory structure should follow pattern: `/path/to/location/obj/{arch}/libname.so`.
*
* In case of above `additionalSymbolFilesLocations` should be equal to:
*
* ```
* datadog {
* additionalSymbolFilesLocations = listOf("/path/to/location/obj")
* }
* ```
*
* Note that each `.so` file should be placed inside the directory with architecture name (e.g. x86).
*/
var additionalSymbolFilesLocations: List<String>? = null

internal fun updateWith(config: DdExtensionConfiguration) {
config.versionName?.let { versionName = it }
config.serviceName?.let { serviceName = it }
config.site?.let { site = it }
config.remoteRepositoryUrl?.let { remoteRepositoryUrl = it }
config.checkProjectDependencies?.let { checkProjectDependencies = it }
config.mappingFilePath?.let { mappingFilePath = it }
config.additionalSymbolFilesLocations?.let { additionalSymbolFilesLocations = it }
mappingFilePackageAliases = config.mappingFilePackageAliases
mappingFileTrimIndents = config.mappingFileTrimIndents
ignoreDatadogCiFileConfig = config.ignoreDatadogCiFileConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ internal abstract class NdkSymbolFileUploadTask @Inject constructor(

task.datadogCiFile = TaskUtils.findDatadogCiFile(project.rootDir)
task.repositoryFile = TaskUtils.resolveDatadogRepositoryFile(project)
extensionConfiguration.additionalSymbolFilesLocations?.let {
task.searchDirectories.from(it.toTypedArray())
}
task.configureWith(
apiKey,
extensionConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,118 @@ internal class DdAndroidGradlePluginFunctionalTest {
assertThat(result).hasNoNdkSymbolUploadTasks()
}

@Test
fun `M try to upload with additional symbol files W custom filepath provided`(forge: Forge) {
// Given
stubGradleBuildFromResourceFile(
"native_gradle_files/build_with_custom_ndk.gradle",
appBuildGradleFile
)

stubNativeFiles()
gradleRunner { withArguments("--info", ":samples:app:assembleRelease") }
.build()

val arch = forge.anElementFrom(NdkSymbolFileUploadTask.SUPPORTED_ARCHS).arch
val customNdkDir = File(appRootDir, "custom/$arch").apply { mkdirs() }
val customSoFile = File(customNdkDir, "libexpected.so")
// Stubbing custom .so file that not present inside default build directories
stubFile(customSoFile, "some_content")

val color = forge.anElementFrom(colors)
val version = forge.anElementFrom(versions)
val variant = "${version.lowercase()}$color"
val variantVersionName = version.lowercase()
val taskName = resolveNdkSymbolUploadTask(variant)

val result = gradleRunner {
withArguments(
taskName,
"--info",
"--stacktrace",
"-PDD_API_KEY=fakekey",
"-Pdd-emulate-upload-call"
)
}
.build()

// Then
val buildIdInOriginFile = testProjectDir.findBuildIdInOriginFile(variant)

// verifying that .so files from default build directories are uploaded
assertThat(result).containsInOutput(
"Uploading file libplaceholder.so with tags " +
"`service:com.example.variants.$variantVersionName`, " +
"`version:1.0-$variantVersionName`, " +
"`version_code:1`, " +
"`variant:$variant`, " +
"`build_id:$buildIdInOriginFile` (site=datadoghq.com):"
)

// verifying that .so files from custom (provided via additionalSymbolFilesLocations)
// build directories are uploaded
assertThat(result).containsInOutput(
"Uploading file libexpected.so with tags " +
"`service:com.example.variants.$variantVersionName`, " +
"`version:1.0-$variantVersionName`, " +
"`version_code:1`, " +
"`variant:$variant`, " +
"`build_id:$buildIdInOriginFile` (site=datadoghq.com):"
)
}

@Test
fun `M try to upload with additional symbol files W custom filepath provided { no externalNativeBuild enabled }`(
forge: Forge
) {
// Given
stubGradleBuildFromResourceFile(
"native_gradle_files/build_with_custom_ndk_no_externalNativeBuild.gradle",
appBuildGradleFile
)

stubNativeFiles()
gradleRunner { withArguments("--info", ":samples:app:assembleRelease") }
.build()

val arch = forge.anElementFrom(NdkSymbolFileUploadTask.SUPPORTED_ARCHS).arch
val customNdkDir = File(appRootDir, "custom/$arch").apply { mkdirs() }
val customSoFile = File(customNdkDir, "libexpected.so")
// Stubbing custom .so file that not present inside default build directories
stubFile(customSoFile, "some_content")

val color = forge.anElementFrom(colors)
val version = forge.anElementFrom(versions)
val variant = "${version.lowercase()}$color"
val variantVersionName = version.lowercase()
val taskName = resolveNdkSymbolUploadTask(variant)

val result = gradleRunner {
withArguments(
taskName,
"--info",
"--stacktrace",
"-PDD_API_KEY=fakekey",
"-Pdd-emulate-upload-call"
)
}
.build()

// Then
val buildIdInOriginFile = testProjectDir.findBuildIdInOriginFile(variant)

// verifying that .so files from custom (provided via additionalSymbolFilesLocations)
// build directories are uploaded even if there is no externalNativeBuild instruction in build.gradle file
assertThat(result).containsInOutput(
"Uploading file libexpected.so with tags " +
"`service:com.example.variants.$variantVersionName`, " +
"`version:1.0-$variantVersionName`, " +
"`version_code:1`, " +
"`variant:$variant`, " +
"`build_id:$buildIdInOriginFile` (site=datadoghq.com):"
)
}

@Test
fun `M try to upload the symbol file W upload { using a fake API_KEY }`(forge: Forge) {
// Given
Expand Down Expand Up @@ -1205,6 +1317,7 @@ internal class DdAndroidGradlePluginFunctionalTest {
// region Internal

private fun resolveMappingUploadTask(variantName: String) = "uploadMapping${variantName.capitalize()}Release"

private fun resolveNdkSymbolUploadTask(
variantName: String
) = "uploadNdkSymbolFiles${variantName.capitalize()}Release"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
plugins {
id("com.android.application")
id("kotlin-android")
id("com.datadoghq.dd-sdk-android-gradle-plugin")
}

repositories {
google()
mavenCentral()
}

android {
compileSdkVersion = rootProject.ext.targetSdkVersion
buildToolsVersion = rootProject.ext.buildToolsVersion

defaultConfig {
applicationId "com.example.variants"
minSdkVersion 21
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled = true
}

namespace = "com.example.variants"

compileOptions {
sourceCompatibility = rootProject.ext.jvmTarget
targetCompatibility = rootProject.ext.jvmTarget
}

kotlinOptions {
jvmTarget = rootProject.ext.jvmTarget
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.22.1'
}
}

flavorDimensions("version", "colour")
productFlavors {
demo {
dimension "version"
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
versionNameSuffix "-full"
}

green {
dimension "colour"
}
blue {
dimension "colour"
}
}
}

dependencies {
implementation(rootProject.ext.datadogSdkDependency)
}

datadog {
additionalSymbolFilesLocations = [
"custom"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
plugins {
id("com.android.application")
id("kotlin-android")
id("com.datadoghq.dd-sdk-android-gradle-plugin")
}

repositories {
google()
mavenCentral()
}

android {
compileSdkVersion = rootProject.ext.targetSdkVersion
buildToolsVersion = rootProject.ext.buildToolsVersion

defaultConfig {
applicationId "com.example.variants"
minSdkVersion 21
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
multiDexEnabled = true
}

namespace = "com.example.variants"

compileOptions {
sourceCompatibility = rootProject.ext.jvmTarget
targetCompatibility = rootProject.ext.jvmTarget
}

kotlinOptions {
jvmTarget = rootProject.ext.jvmTarget
}

flavorDimensions("version", "colour")
productFlavors {
demo {
dimension "version"
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
versionNameSuffix "-full"
}

green {
dimension "colour"
}
blue {
dimension "colour"
}
}
}

dependencies {
implementation(rootProject.ext.datadogSdkDependency)
}

datadog {
additionalSymbolFilesLocations = [
"custom"
]
}

0 comments on commit c74ab9a

Please sign in to comment.