org.gradle.language.cpp.CppApplicationPublishingIntegrationTest.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2017 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
*
* 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 org.gradle.language.cpp
import org.gradle.integtests.fixtures.FeaturePreviewsFixture
import org.gradle.language.VariantContext
import org.gradle.nativeplatform.fixtures.RequiresInstalledToolChain
import org.gradle.nativeplatform.fixtures.ToolChainRequirement
import org.gradle.nativeplatform.fixtures.app.CppApp
import org.gradle.nativeplatform.fixtures.app.CppAppWithLibrary
import org.gradle.nativeplatform.fixtures.app.CppLogger
import org.gradle.test.fixtures.file.TestFile
import org.gradle.util.Requires
import org.gradle.util.TestPrecondition
import static org.gradle.nativeplatform.MachineArchitecture.ARCHITECTURE_ATTRIBUTE
import static org.gradle.nativeplatform.MachineArchitecture.X86
import static org.gradle.nativeplatform.MachineArchitecture.X86_64
import static org.gradle.nativeplatform.OperatingSystemFamily.LINUX
import static org.gradle.nativeplatform.OperatingSystemFamily.MACOS
import static org.gradle.nativeplatform.OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE
import static org.gradle.nativeplatform.OperatingSystemFamily.WINDOWS
class CppApplicationPublishingIntegrationTest extends AbstractCppPublishingIntegrationTest implements CppTaskNames {
def consumer = file("consumer").createDir()
def setup() {
when:
FeaturePreviewsFixture.enableGradleMetadata(consumer.file("settings.gradle"))
consumer.file("build.gradle") << """
apply plugin: 'cpp-application'
repositories {
maven {
url '${mavenRepo.uri}'
}
}
configurations {
install {
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, 'native-runtime'))
attributes.attribute(Attribute.of('org.gradle.native.debuggable', Boolean), true)
attributes.attribute(Attribute.of('org.gradle.native.optimized', Boolean), false)
}
}
// HACK to install the executable from a repository
def binary = application.developmentBinary
task install(type: InstallExecutable) {
targetPlatform.set(binary.map { it.compileTask.get().targetPlatform.get() })
toolChain.set(binary.map { it.toolChain })
installDirectory = layout.projectDirectory.dir("install")
lib(configurations.install)
executableFile = layout.file(provider {
def appFile = configurations.install.files[0]
appFile.executable = true
appFile
})
}
"""
}
def "can publish the binaries of an application to a Maven repository"() {
def app = new CppApp()
given:
buildFile << """
apply plugin: 'cpp-application'
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
application {
baseName = 'test'
}
publishing {
repositories { maven { url '$mavenRepo.uri' } }
}
"""
app.writeToProject(testDirectory)
when:
run('publish')
then:
result.assertTasksExecuted(
tasks.debug.allToLink,
tasks.release.allToLink,
tasks.release.strip,
":generatePomFileForMainDebugPublication",
":generateMetadataFileForMainDebugPublication",
":publishMainDebugPublicationToMavenRepository",
":generatePomFileForMainPublication",
":generateMetadataFileForMainPublication",
":publishMainPublicationToMavenRepository",
":generatePomFileForMainReleasePublication",
":generateMetadataFileForMainReleasePublication",
":publishMainReleasePublicationToMavenRepository",
":publish")
def main = mavenRepo.module('some.group', 'test', '1.2')
main.assertPublished()
main.assertArtifactsPublished("test-1.2.pom", "test-1.2.module")
main.parsedPom.scopes.isEmpty()
def mainMetadata = main.parsedModuleMetadata
mainMetadata.variants.size() == 2
mainMetadata.variant("debugRuntime").availableAt.coords == "some.group:test_debug:1.2"
mainMetadata.variant("releaseRuntime").availableAt.coords == "some.group:test_release:1.2"
def debug = mavenRepo.module('some.group', 'test_debug', '1.2')
debug.assertPublished()
debug.assertArtifactsPublished(executableName("test_debug-1.2"), "test_debug-1.2.pom", "test_debug-1.2.module")
debug.artifactFile(type: executableExtension).assertIsCopyOf(executable("build/exe/main/debug/test").file)
debug.parsedPom.scopes.isEmpty()
def debugMetadata = debug.parsedModuleMetadata
debugMetadata.variants.size() == 1
def debugRuntime = debugMetadata.variant("debugRuntime")
debugRuntime.dependencies.empty
debugRuntime.files.size() == 1
debugRuntime.files[0].name == executableName('test')
debugRuntime.files[0].url == executableName("test_debug-1.2")
def release = mavenRepo.module('some.group', 'test_release', '1.2')
release.assertPublished()
release.assertArtifactsPublished(executableName("test_release-1.2"), "test_release-1.2.pom", "test_release-1.2.module")
release.artifactFile(type: executableExtension).assertIsCopyOf(executable("build/exe/main/release/test").strippedRuntimeFile)
release.parsedPom.scopes.isEmpty()
def releaseMetadata = release.parsedModuleMetadata
releaseMetadata.variants.size() == 1
def releaseRuntime = releaseMetadata.variant("releaseRuntime")
releaseRuntime.dependencies.empty
releaseRuntime.files.size() == 1
releaseRuntime.files[0].name == executableName('test')
releaseRuntime.files[0].url == executableName("test_release-1.2")
when:
consumer.file("build.gradle") << """
dependencies {
install 'some.group:test:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
def "can publish an executable and library to a Maven repository"() {
def app = new CppAppWithLibrary()
given:
settingsFile << "include 'greeter', 'app'"
buildFile << """
subprojects {
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
publishing {
repositories { maven { url '${mavenRepo.uri}' } }
}
}
project(':app') {
apply plugin: 'cpp-application'
dependencies {
implementation project(':greeter')
}
}
project(':greeter') {
apply plugin: 'cpp-library'
}
"""
app.greeter.writeToProject(file('greeter'))
app.main.writeToProject(file('app'))
when:
run('publish')
then:
def appModule = mavenRepo.module('some.group', 'app', '1.2')
appModule.assertPublished()
def appDebugModule = mavenRepo.module('some.group', 'app_debug', '1.2')
appDebugModule.assertPublished()
appDebugModule.parsedPom.scopes.size() == 1
appDebugModule.parsedPom.scopes.runtime.assertDependsOn("some.group:greeter:1.2")
def appDebugMetadata = appDebugModule.parsedModuleMetadata
def appDebugRuntime = appDebugMetadata.variant("debugRuntime")
appDebugRuntime.dependencies.size() == 1
appDebugRuntime.dependencies[0].coords == 'some.group:greeter:1.2'
def appReleaseModule = mavenRepo.module('some.group', 'app_release', '1.2')
appReleaseModule.assertPublished()
appReleaseModule.parsedPom.scopes.size() == 1
appReleaseModule.parsedPom.scopes.runtime.assertDependsOn("some.group:greeter:1.2")
def appReleaseMetadata = appReleaseModule.parsedModuleMetadata
def appReleaseRuntime = appReleaseMetadata.variant("releaseRuntime")
appReleaseRuntime.dependencies.size() == 1
appReleaseRuntime.dependencies[0].coords == 'some.group:greeter:1.2'
def greeterModule = mavenRepo.module('some.group', 'greeter', '1.2')
greeterModule.assertPublished()
def greeterDebugModule = mavenRepo.module('some.group', 'greeter_debug', '1.2')
greeterDebugModule.assertPublished()
def greeterReleaseModule = mavenRepo.module('some.group', 'greeter_release', '1.2')
greeterReleaseModule.assertPublished()
when:
def consumer = file("consumer").createDir()
consumer.file("settings.gradle") << ''
consumer.file("build.gradle") << """
dependencies {
install 'some.group:app:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
def "can publish an executable and a binary-specific dependency to a Maven repository"() {
def app = new CppAppWithLibrary()
def logger = new CppLogger().asLib()
given:
settingsFile << "include 'greeter', 'app', 'logger'"
buildFile << """
subprojects {
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
publishing {
repositories { maven { url '${mavenRepo.uri}' } }
}
}
project(':app') {
apply plugin: 'cpp-application'
dependencies {
implementation project(':greeter')
}
application {
binaries.configureEach {
dependencies {
if (!optimized) {
implementation project(':logger')
}
}
}
}
}
project(':greeter') {
apply plugin: 'cpp-library'
}
project(':logger') {
apply plugin: 'cpp-library'
}
"""
app.greeter.writeToProject(file('greeter'))
app.main.writeToProject(file('app'))
logger.writeToProject(file('logger'))
when:
run('publish')
then:
def appModule = mavenRepo.module('some.group', 'app', '1.2')
appModule.assertPublished()
def appDebugModule = mavenRepo.module('some.group', 'app_debug', '1.2')
appDebugModule.assertPublished()
appDebugModule.parsedPom.scopes.size() == 1
appDebugModule.parsedPom.scopes.runtime.assertDependsOn("some.group:greeter:1.2", "some.group:logger:1.2")
def appDebugMetadata = appDebugModule.parsedModuleMetadata
def appDebugRuntime = appDebugMetadata.variant("debugRuntime")
appDebugRuntime.dependencies.size() == 2
appDebugRuntime.dependencies.collect { it.coords } == [ 'some.group:logger:1.2', 'some.group:greeter:1.2' ]
def appReleaseModule = mavenRepo.module('some.group', 'app_release', '1.2')
appReleaseModule.assertPublished()
appReleaseModule.parsedPom.scopes.size() == 1
appReleaseModule.parsedPom.scopes.runtime.assertDependsOn("some.group:greeter:1.2")
def appReleaseMetadata = appReleaseModule.parsedModuleMetadata
def appReleaseRuntime = appReleaseMetadata.variant("releaseRuntime")
appReleaseRuntime.dependencies.size() == 1
appReleaseRuntime.dependencies[0].coords == 'some.group:greeter:1.2'
mavenRepo.module('some.group', 'greeter', '1.2').assertPublished()
mavenRepo.module('some.group', 'greeter_debug', '1.2').assertPublished()
mavenRepo.module('some.group', 'greeter_release', '1.2').assertPublished()
mavenRepo.module('some.group', 'logger', '1.2').assertPublished()
mavenRepo.module('some.group', 'logger_debug', '1.2').assertPublished()
mavenRepo.module('some.group', 'logger_release', '1.2').assertPublished()
when:
def consumer = file("consumer").createDir()
consumer.file("settings.gradle") << ''
consumer.file("build.gradle") << """
dependencies {
install 'some.group:app:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
def "uses the basename to calculate the coordinates"() {
def app = new CppAppWithLibrary()
given:
settingsFile << "include 'greeter', 'app'"
buildFile << """
subprojects {
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
publishing {
repositories { maven { url '${mavenRepo.uri}' } }
}
}
project(':app') {
apply plugin: 'cpp-application'
application.baseName = 'testApp'
dependencies {
implementation project(':greeter')
}
}
project(':greeter') {
apply plugin: 'cpp-library'
library.baseName = 'appGreeter'
}
"""
app.greeter.writeToProject(file('greeter'))
app.main.writeToProject(file('app'))
when:
run('publish')
then:
def appModule = mavenRepo.module('some.group', 'testApp', '1.2')
appModule.assertPublished()
def appDebugModule = mavenRepo.module('some.group', 'testApp_debug', '1.2')
appDebugModule.assertPublished()
def appDebugMetadata = appDebugModule.parsedModuleMetadata
def appDebugRuntime = appDebugMetadata.variant("debugRuntime")
appDebugRuntime.dependencies.size() == 1
appDebugRuntime.dependencies[0].coords == 'some.group:appGreeter:1.2'
def appReleaseModule = mavenRepo.module('some.group', 'testApp_release', '1.2')
appReleaseModule.assertPublished()
def appReleaseMetadata = appReleaseModule.parsedModuleMetadata
def appReleaseRuntime = appReleaseMetadata.variant("releaseRuntime")
appReleaseRuntime.dependencies.size() == 1
appReleaseRuntime.dependencies[0].coords == 'some.group:appGreeter:1.2'
def greeterModule = mavenRepo.module('some.group', 'appGreeter', '1.2')
greeterModule.assertPublished()
def greeterDebugModule = mavenRepo.module('some.group', 'appGreeter_debug', '1.2')
greeterDebugModule.assertPublished()
def greeterReleaseModule = mavenRepo.module('some.group', 'appGreeter_release', '1.2')
greeterReleaseModule.assertPublished()
when:
def consumer = file("consumer").createDir()
consumer.file("settings.gradle") << ''
consumer.file("build.gradle") << """
dependencies {
install 'some.group:testApp:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
def "can publish the binaries of an application with multiple target operating systems to a Maven repository"() {
def app = new CppApp()
def targetMachines = [machine(WINDOWS, X86), machine(LINUX, X86), machine(MACOS, X86_64)]
given:
buildFile << """
apply plugin: 'cpp-application'
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
application {
baseName = 'test'
targetMachines = [machines.windows.x86, machines.linux.x86, machines.macOS.x86_64]
}
publishing {
repositories { maven { url '$mavenRepo.uri' } }
}
"""
app.writeToProject(testDirectory)
when:
run('publish')
then:
assertMainModuleIsPublished('some.group', 'test', '1.2', targetMachines)
assertVariantsArePublished('some.group', 'test', '1.2', ['debug', 'release'], targetMachines)
when:
consumer.file("build.gradle") << """
configurations {
install {
attributes.attribute(Attribute.of('org.gradle.native.operatingSystem', OperatingSystemFamily), objects.named(OperatingSystemFamily, '${currentOsFamilyName}'))
}
}
dependencies {
install 'some.group:test:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
// macOS can only build 64-bit under 10.14+
@Requires(TestPrecondition.NOT_MAC_OS_X)
@RequiresInstalledToolChain(ToolChainRequirement.SUPPORTS_32_AND_64)
def "can publish the binaries of an application with multiple target architectures to a Maven repository"() {
def app = new CppApp()
def targetMachines = [machine(currentOsFamilyName, X86), machine(currentOsFamilyName, X86_64)]
given:
buildFile << """
apply plugin: 'cpp-application'
apply plugin: 'maven-publish'
group = 'some.group'
version = '1.2'
application {
baseName = 'test'
targetMachines = [machines.os('${currentOsFamilyName}').x86, machines.os('${currentOsFamilyName}').x86_64]
}
publishing {
repositories { maven { url '$mavenRepo.uri' } }
}
"""
app.writeToProject(testDirectory)
when:
run('publish')
then:
assertMainModuleIsPublished('some.group', 'test', '1.2', targetMachines)
assertVariantsArePublished('some.group', 'test', '1.2', ['debug', 'release'], targetMachines)
when:
consumer.file("build.gradle") << """
configurations {
install {
attributes.attribute(Attribute.of('${OPERATING_SYSTEM_ATTRIBUTE}', OperatingSystemFamily), objects.named(OperatingSystemFamily, '${currentOsFamilyName}'))
attributes.attribute(Attribute.of('${ARCHITECTURE_ATTRIBUTE}', MachineArchitecture), objects.named(MachineArchitecture, '${X86}'))
}
}
dependencies {
install 'some.group:test:1.2'
}
"""
executer.inDirectory(consumer)
run("install")
then:
def installation = installation("consumer/install")
installation.exec().out == app.expectedOutput
}
@Override
List getLinkages() {
return ['Runtime']
}
@Override
List getMainModuleArtifacts(String module, String version) {
return ["${module}-${version}.pom", "${module}-${version}.module"]
}
@Override
List getVariantModuleArtifacts(String variantModuleNameWithVersion) {
return [executableName(variantModuleNameWithVersion), "${variantModuleNameWithVersion}.pom", "${variantModuleNameWithVersion}.module"]
}
@Override
TestFile getVariantSourceFile(String module, VariantContext variantContext) {
def executable = executable("build/exe/main/${variantContext.asPath}${module}")
return variantContext.buildType.name == 'release' ? executable.strippedRuntimeFile : executable.file
}
@Override
Map getVariantFileInformation(String linkage, String module, String variantModuleNameWithVersion) {
return [ name: executableName(module), url: executableName(variantModuleNameWithVersion), extension: executableExtension ]
}
@Override
int getVariantCount(List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy