working on c and cmake plugins
This commit is contained in:
parent
7ea6ca3d65
commit
d616184a2e
27 changed files with 1543 additions and 1 deletions
201
gradle-plugin-c/LICENSE.txt
Normal file
201
gradle-plugin-c/LICENSE.txt
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
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.
|
8
gradle-plugin-c/NOTICE.txt
Normal file
8
gradle-plugin-c/NOTICE.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
This work is derived from
|
||||
|
||||
https://github.com/jjohannes/plain-c
|
||||
|
||||
as of January 14, 2024
|
||||
|
||||
(Apache License 2.0)
|
81
gradle-plugin-c/README.md
Normal file
81
gradle-plugin-c/README.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
# C - Gradle plugin
|
||||
|
||||
An experimental plugin for customized **C** development with Gradle.
|
||||
It showcases how to use tasks that are provided by Gradle core for **C** development,
|
||||
such as `org.gradle.language.c.tasks.CCompile`, directly as part of a custom build system.
|
||||
This can make sense in a highly customized Gradle build system where specific (and multiple) **C** compilation/assembling/linking
|
||||
steps are part of a larger build pipeline with other custom Gradle tasks.
|
||||
|
||||
The plugin provides an extension called `c` to:
|
||||
|
||||
- Set the `targetPlatform` property of a task to a generic platform via `targetPlatform.set(c.platform())`
|
||||
- Set the `toolChain` property of a task to a locally installed tool via `toolChain.set(c.localTool("version", "/path/to/tool", ".o"))`
|
||||
- Set the `toolChain` property of a task to a tool located in a ZIP file in a Maven repository via `toolChain.set(c.repositoryTool("group", "name", "version", "path/in/zip", ".o"))`
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
plugins {
|
||||
id 'org.xbib.gradle.plugin.c"
|
||||
}
|
||||
|
||||
tasks.register<CCompile>("compileC") {
|
||||
toolChain.set(c.localTool("14.0.0", "/usr/bin/clang", ".o"))
|
||||
targetPlatform.set(c.platform())
|
||||
|
||||
source(layout.projectDirectory.files("src/c").asFileTree)
|
||||
includes(layout.projectDirectory.files("src/headers"))
|
||||
compilerArgs.add("-S")
|
||||
|
||||
objectFileDir.set(layout.buildDirectory.dir("out/o"))
|
||||
}
|
||||
|
||||
val compileC2 = tasks.register<CCompile>("compileC2") {
|
||||
toolChain.set(c.repositoryTool("com.example", "vendor-x", "1.2", "bin/xcc", ".src"))
|
||||
targetPlatform.set(c.platform())
|
||||
|
||||
source(layout.projectDirectory.files("src/c-special").asFileTree)
|
||||
includes(layout.projectDirectory.files("src/headers"))
|
||||
|
||||
objectFileDir.set(layout.buildDirectory.dir("out/src"))
|
||||
}
|
||||
|
||||
tasks.register<Assemble>("assembleC2") {
|
||||
toolChain.set(c.repositoryTool("com.example", "vendor-x", "1.2", "bin/xas", ".o"))
|
||||
targetPlatform.set(c.platform())
|
||||
|
||||
source(compileC2.map { it.objectFileDir.asFileTree })
|
||||
includes(layout.projectDirectory.files("src/headers"))
|
||||
assemblerArgs = listOf("-D")
|
||||
|
||||
objectFileDir = layout.buildDirectory.dir("out/o2").get().asFile
|
||||
}
|
||||
```
|
||||
|
||||
## How does this work?
|
||||
|
||||
In order to fully configure one of the native tasks of Gradle (such as `org.gradle.language.c.tasks.CCompile`),
|
||||
you require a **NativeToolchain** (instance of `org.gradle.nativeplatform.toolchain.NativeToolChain`)
|
||||
and a **TargetPlatform** (instance of `org.gradle.nativeplatform.platform.NativePlatform`).
|
||||
Gradle's own [native languages plugins](https://docs.gradle.org/current/userguide/plugin_reference.html#native_languages)
|
||||
pre-configure these task properties through the so-called _native toolchain registry_.
|
||||
This allows, for example, to compile the same code for multiple target platforms with different tools in the same build.
|
||||
This is great, if this is what you need. However, in a scenario where we do not care about this feature and would rather register
|
||||
tasks directly, we miss flexibility as the _native toolchain registry_ in Gradle is not very flexible right now and makes it difficult or impossible to register
|
||||
your own tools (and it has not been improved for several years).
|
||||
|
||||
The [CExtension.java](src/main/java/org/xbib/gradle/plugin/c/CExtension.java) class now allows you to
|
||||
set the `targetPlatform` and `toolChain` properties of any task without the _native toolchain registry_.
|
||||
It does so by utilising internal Gradle APIs to:
|
||||
- Construct a generic `NativePlatform` object. This is the same everywhere and will be ignored during tool selection.
|
||||
In our scenario, we do not care about different platforms.
|
||||
- Construct a `NativeToolChain` instance based on a concrete executable. Either by providing a concrete path to
|
||||
an executable (`localTool(...)`) or coordinates pointing at a ZIP file in a Maven repository (`repositoryTool(...)`).
|
||||
In the latter case, Gradle's dependency management is used to find, download, extract and cache the tool.
|
||||
|
||||
Behind the custom `NativeToolChain` implementation is a custom `PlatformToolProvider` implementation and extensions of
|
||||
Gradle's `NativeCompiler` implementations. This allows for more customization and extension of Gradle's functionality
|
||||
in this area. This uses a lot of APIs from `internal` packages. Which, however, have not been touched for years.
|
||||
|
||||
This showcase could help to determine which APIs in this area should probably be public.
|
||||
|
30
gradle-plugin-c/build.gradle
Normal file
30
gradle-plugin-c/build.gradle
Normal file
|
@ -0,0 +1,30 @@
|
|||
plugins {
|
||||
alias(libs.plugins.publish)
|
||||
}
|
||||
|
||||
apply plugin: 'com.gradle.plugin-publish'
|
||||
|
||||
apply from: rootProject.file('gradle/compile/groovy.gradle')
|
||||
apply from: rootProject.file('gradle/test/junit5.gradle')
|
||||
|
||||
dependencies {
|
||||
api gradleApi()
|
||||
testImplementation gradleTestKit()
|
||||
}
|
||||
|
||||
if (project.hasProperty('gradle.publish.key')) {
|
||||
gradlePlugin {
|
||||
website = 'https://xbib.org/joerg/gradle-plugins/src/branch/main/gradle-plugin-c'
|
||||
vcsUrl = 'https://xbib.org/joerg/gradle-plugins'
|
||||
plugins {
|
||||
cPlugin {
|
||||
id = 'org.xbib.gradle.plugin.c'
|
||||
implementationClass = 'org.xbib.gradle.plugin.c.CPlugin'
|
||||
version = project.version
|
||||
description = 'Gradle plugin for build with C'
|
||||
displayName = 'Gradle Plugin for build with C'
|
||||
tags.set(['c'])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
gradle-plugin-c/gradle.properties
Normal file
2
gradle-plugin-c/gradle.properties
Normal file
|
@ -0,0 +1,2 @@
|
|||
name = gradle-plugin-c
|
||||
version = 3.1.0
|
|
@ -0,0 +1,59 @@
|
|||
package org.xbib.gradle.plugin.c;
|
||||
|
||||
import java.io.File;
|
||||
import javax.inject.Inject;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler;
|
||||
import org.gradle.api.attributes.Attribute;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.nativeplatform.platform.NativePlatform;
|
||||
import org.gradle.nativeplatform.platform.internal.DefaultArchitecture;
|
||||
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform;
|
||||
import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem;
|
||||
import org.gradle.nativeplatform.toolchain.NativeToolChain;
|
||||
import org.xbib.gradle.plugin.c.toolchain.CNativeToolChain;
|
||||
|
||||
public abstract class CExtension {
|
||||
|
||||
static final Attribute<Boolean> EXTRACTED_TOOLS_ATTRIBUTE = Attribute.of("extracted-tools", Boolean.class);
|
||||
|
||||
static final NativePlatform GENERIC_NATIVE_PLATFORM = new DefaultNativePlatform(
|
||||
"generic_platform",
|
||||
new DefaultOperatingSystem("generic_os"),
|
||||
new DefaultArchitecture("generic_arch")
|
||||
);
|
||||
|
||||
public NativeToolChain localTool(String version, String location, String objectFileExtension) {
|
||||
File tool = new File(location);
|
||||
return getObjects().newInstance(CNativeToolChain.class, version, tool.getName(),
|
||||
getObjects().fileCollection().from(tool), objectFileExtension);
|
||||
}
|
||||
|
||||
public NativeToolChain repositoryTool(String group,
|
||||
String name,
|
||||
String version,
|
||||
String locationInZip,
|
||||
String objectFileExtension) {
|
||||
Configuration toolConfiguration = getConfigurations().detachedConfiguration(
|
||||
getDependencies().create(group + ":" + name + ":" + version + "@zip"));
|
||||
FileCollection tool = toolConfiguration.getIncoming().artifactView(a ->
|
||||
a.getAttributes().attribute(EXTRACTED_TOOLS_ATTRIBUTE, true))
|
||||
.getFiles().getAsFileTree().filter(file -> file.getPath().endsWith(locationInZip));
|
||||
return getObjects().newInstance(CNativeToolChain.class, name, version, tool, objectFileExtension);
|
||||
}
|
||||
|
||||
public NativePlatform platform() {
|
||||
return GENERIC_NATIVE_PLATFORM;
|
||||
}
|
||||
|
||||
@Inject
|
||||
abstract protected ObjectFactory getObjects();
|
||||
|
||||
@Inject
|
||||
abstract protected ConfigurationContainer getConfigurations();
|
||||
|
||||
@Inject
|
||||
abstract protected DependencyHandler getDependencies();
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.xbib.gradle.plugin.c;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.xbib.gradle.plugin.c.toolchain.transform.ExtractZipTransform;
|
||||
import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
abstract public class CPlugin implements Plugin<Project> {
|
||||
|
||||
@Override
|
||||
public void apply(final Project project) {
|
||||
// Register extension
|
||||
project.getExtensions().create("c", CExtension.class);
|
||||
// Make the ExtractZipTransform known
|
||||
project.getDependencies().getAttributesSchema().attribute(CExtension.EXTRACTED_TOOLS_ATTRIBUTE);
|
||||
project.getDependencies().getArtifactTypes().maybeCreate("zip")
|
||||
.getAttributes().attribute(CExtension.EXTRACTED_TOOLS_ATTRIBUTE, false);
|
||||
project.getDependencies().registerTransform(ExtractZipTransform.class, t -> {
|
||||
t.getFrom().attribute(CExtension.EXTRACTED_TOOLS_ATTRIBUTE, false).attribute(ARTIFACT_TYPE_ATTRIBUTE, "zip");
|
||||
t.getTo().attribute(CExtension.EXTRACTED_TOOLS_ATTRIBUTE, true).attribute(ARTIFACT_TYPE_ATTRIBUTE, "zip");
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.xbib.gradle.plugin.c.tasks;
|
||||
|
||||
import java.util.List;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
import org.gradle.api.tasks.CacheableTask;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.language.c.tasks.CCompile;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeCompileSpec;
|
||||
|
||||
/**
|
||||
* Extension of the 'org.gradle.language.c.tasks.CCompile' that supports defining different compiler arguments
|
||||
* for different source files.
|
||||
*/
|
||||
@CacheableTask
|
||||
public abstract class ExtendedCCompile extends CCompile {
|
||||
|
||||
@Input
|
||||
public abstract MapProperty<String, List<String>> getPerFileCompilerArgs();
|
||||
|
||||
@Override
|
||||
protected NativeCompileSpec createCompileSpec() {
|
||||
return new ExtendedCCompileSpec();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureSpec(NativeCompileSpec spec) {
|
||||
super.configureSpec(spec);
|
||||
ExtendedCCompileSpec extendedCCompileSpec = (ExtendedCCompileSpec) spec;
|
||||
extendedCCompileSpec.getPerFileCompilerArgs().putAll(getPerFileCompilerArgs().get());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.xbib.gradle.plugin.c.tasks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.gradle.language.c.internal.DefaultCCompileSpec;
|
||||
|
||||
public class ExtendedCCompileSpec extends DefaultCCompileSpec {
|
||||
|
||||
private final Map<String, List<String>> perFileCompilerArgs = new HashMap<>();
|
||||
|
||||
public Map<String, List<String>> getPerFileCompilerArgs() {
|
||||
return perFileCompilerArgs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package org.xbib.gradle.plugin.c.tasks;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.tasks.CacheableTask;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.WorkResult;
|
||||
import org.gradle.internal.operations.logging.BuildOperationLogger;
|
||||
import org.gradle.language.assembler.internal.DefaultAssembleSpec;
|
||||
import org.gradle.language.assembler.tasks.Assemble;
|
||||
import org.gradle.language.base.internal.compile.Compiler;
|
||||
import org.gradle.language.base.internal.tasks.StaleOutputCleaner;
|
||||
import org.gradle.nativeplatform.internal.BuildOperationLoggingCompilerDecorator;
|
||||
import org.gradle.nativeplatform.platform.internal.NativePlatformInternal;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeToolChainInternal;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.AssembleSpec;
|
||||
import org.gradle.work.ChangeType;
|
||||
import org.gradle.work.FileChange;
|
||||
import org.gradle.work.Incremental;
|
||||
import org.gradle.work.InputChanges;
|
||||
|
||||
/**
|
||||
* Incremental and cacheable version of the 'org.gradle.language.assembler.tasks.Assemble' task.
|
||||
*/
|
||||
@CacheableTask
|
||||
public abstract class IncrementalAssemble extends Assemble {
|
||||
|
||||
@Incremental
|
||||
@Override
|
||||
public ConfigurableFileCollection getSource() {
|
||||
return super.getSource();
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void assemble(InputChanges inputs) {
|
||||
// Copied from super class and adjusted for incremental assembling
|
||||
|
||||
BuildOperationLogger operationLogger = getOperationLoggerFactory().newOperationLogger(getName(), getTemporaryDir());
|
||||
|
||||
List<File> toDelete = new ArrayList<>();
|
||||
List<File> toAssemble = new ArrayList<>();
|
||||
|
||||
for (FileChange change : inputs.getFileChanges(super.getSource())) {
|
||||
if (change.getChangeType() == ChangeType.REMOVED) {
|
||||
toDelete.add(change.getFile());
|
||||
}
|
||||
if (change.getChangeType() != ChangeType.REMOVED) {
|
||||
toAssemble.add(change.getFile());
|
||||
}
|
||||
}
|
||||
|
||||
boolean cleanedOutputs = StaleOutputCleaner.cleanOutputs(
|
||||
getDeleter(),
|
||||
toDelete,
|
||||
getObjectFileDir()
|
||||
);
|
||||
|
||||
DefaultAssembleSpec spec = new DefaultAssembleSpec();
|
||||
spec.setTempDir(getTemporaryDir());
|
||||
|
||||
spec.setObjectFileDir(getObjectFileDir());
|
||||
spec.source(toAssemble);
|
||||
spec.include(getIncludes());
|
||||
spec.args(getAssemblerArgs());
|
||||
spec.setOperationLogger(operationLogger);
|
||||
|
||||
NativeToolChainInternal nativeToolChain = (NativeToolChainInternal) getToolChain().get();
|
||||
NativePlatformInternal nativePlatform = (NativePlatformInternal) getTargetPlatform().get();
|
||||
Compiler<AssembleSpec> compiler = nativeToolChain.select(nativePlatform).newCompiler(AssembleSpec.class);
|
||||
WorkResult result = BuildOperationLoggingCompilerDecorator.wrap(compiler).execute(spec);
|
||||
setDidWork(result.getDidWork() || cleanedOutputs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assemble() {
|
||||
// disable assemble() without 'inputs' argument
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.nativeplatform.platform.internal.NativePlatformInternal;
|
||||
import org.gradle.nativeplatform.toolchain.NativeToolChain;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeLanguage;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeToolChainInternal;
|
||||
import org.gradle.nativeplatform.toolchain.internal.PlatformToolProvider;
|
||||
|
||||
@NonNullApi
|
||||
public abstract class CNativeToolChain implements NativeToolChain, NativeToolChainInternal {
|
||||
|
||||
private final String toolName;
|
||||
|
||||
private final String toolVersion;
|
||||
|
||||
private final FileCollection tool;
|
||||
|
||||
private final String objectFileExtension;
|
||||
|
||||
@Inject
|
||||
public CNativeToolChain(String toolName,
|
||||
String toolVersion,
|
||||
FileCollection tool,
|
||||
String objectFileExtension) {
|
||||
this.toolName = toolName;
|
||||
this.toolVersion = toolVersion;
|
||||
this.tool = tool;
|
||||
this.objectFileExtension = objectFileExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return toolName + "_" + toolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformToolProvider select(NativePlatformInternal nativePlatform) {
|
||||
return getObjects().newInstance(CPlatformToolProvider.class, tool, toolVersion, objectFileExtension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformToolProvider select(NativeLanguage nativeLanguage, NativePlatformInternal nativePlatform) {
|
||||
return select(nativePlatform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutputType() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertSupported() {
|
||||
}
|
||||
|
||||
@Inject
|
||||
abstract protected ObjectFactory getObjects();
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.internal.logging.text.DiagnosticsVisitor;
|
||||
import org.gradle.internal.operations.BuildOperationExecutor;
|
||||
import org.gradle.internal.work.WorkerLeaseService;
|
||||
import org.gradle.language.base.internal.compile.CompileSpec;
|
||||
import org.gradle.language.base.internal.compile.Compiler;
|
||||
import org.gradle.language.base.internal.compile.DefaultCompilerVersion;
|
||||
import org.gradle.language.base.internal.compile.VersionAwareCompiler;
|
||||
import org.gradle.nativeplatform.internal.CompilerOutputFileNamingSchemeFactory;
|
||||
import org.gradle.nativeplatform.internal.LinkerSpec;
|
||||
import org.gradle.nativeplatform.internal.StaticLibraryArchiverSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationWorker;
|
||||
import org.gradle.nativeplatform.toolchain.internal.DefaultCommandLineToolInvocationWorker;
|
||||
import org.gradle.nativeplatform.toolchain.internal.DefaultMutableCommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.EmptySystemLibraries;
|
||||
import org.gradle.nativeplatform.toolchain.internal.OutputCleaningCompiler;
|
||||
import org.gradle.nativeplatform.toolchain.internal.PlatformToolProvider;
|
||||
import org.gradle.nativeplatform.toolchain.internal.SystemLibraries;
|
||||
import org.gradle.nativeplatform.toolchain.internal.ToolType;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.AssembleSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.CCompileSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.metadata.CompilerMetadata;
|
||||
import org.gradle.nativeplatform.toolchain.internal.tools.CommandLineToolSearchResult;
|
||||
import org.gradle.process.internal.ExecActionFactory;
|
||||
import org.gradle.util.internal.VersionNumber;
|
||||
import org.xbib.gradle.plugin.c.toolchain.tools.Assembler;
|
||||
import org.xbib.gradle.plugin.c.toolchain.tools.CCompiler;
|
||||
import org.xbib.gradle.plugin.c.toolchain.tools.Linker;
|
||||
import org.xbib.gradle.plugin.c.toolchain.tools.StaticLibraryArchiver;
|
||||
|
||||
public abstract class CPlatformToolProvider implements PlatformToolProvider {
|
||||
|
||||
private final FileCollection tool;
|
||||
|
||||
private final String toolVersion;
|
||||
|
||||
private final String objectFileExtension;
|
||||
|
||||
@Inject
|
||||
public CPlatformToolProvider(FileCollection tool, String toolVersion, String objectFileExtension) {
|
||||
this.tool = tool;
|
||||
this.toolVersion = toolVersion;
|
||||
this.objectFileExtension = objectFileExtension;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends CompileSpec> Compiler<T> newCompiler(Class<T> spec) {
|
||||
if (CCompileSpec.class.isAssignableFrom(spec)) {
|
||||
return (Compiler<T>) createCCompiler();
|
||||
}
|
||||
if (AssembleSpec.class.isAssignableFrom(spec)) {
|
||||
return (Compiler<T>) createAssembler();
|
||||
}
|
||||
if (LinkerSpec.class.isAssignableFrom(spec)) {
|
||||
return (Compiler<T>) createLinker();
|
||||
}
|
||||
if (StaticLibraryArchiverSpec.class.isAssignableFrom(spec)) {
|
||||
return (Compiler<T>) createStaticLibraryArchiver();
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("Don't know how to compile from a spec of type %s.",
|
||||
spec.getSimpleName()));
|
||||
}
|
||||
|
||||
protected Compiler<CCompileSpec> createCCompiler() {
|
||||
CCompiler cCompiler = new CCompiler(getBuildOperationExecutor(), getCompilerOutputFileNamingSchemeFactory(),
|
||||
commandLineTool("Compiler"), context(), objectFileExtension, getWorkerLeaseService());
|
||||
OutputCleaningCompiler<CCompileSpec> outputCleaningCompiler = new OutputCleaningCompiler<>(cCompiler,
|
||||
getCompilerOutputFileNamingSchemeFactory(), objectFileExtension);
|
||||
return versionAwareCompiler(outputCleaningCompiler, "C Compiler");
|
||||
}
|
||||
|
||||
protected Compiler<AssembleSpec> createAssembler() {
|
||||
return new Assembler(getBuildOperationExecutor(), getCompilerOutputFileNamingSchemeFactory(),
|
||||
commandLineTool("Assembler"), context(), objectFileExtension, getWorkerLeaseService());
|
||||
}
|
||||
|
||||
protected Compiler<LinkerSpec> createLinker() {
|
||||
Linker linker = new Linker(getBuildOperationExecutor(), commandLineTool("Linked"), context(),
|
||||
getWorkerLeaseService());
|
||||
return versionAwareCompiler(linker, "Linker");
|
||||
}
|
||||
|
||||
protected Compiler<StaticLibraryArchiverSpec> createStaticLibraryArchiver() {
|
||||
return new StaticLibraryArchiver(getBuildOperationExecutor(),
|
||||
commandLineTool("Static Library"), context(), getWorkerLeaseService());
|
||||
}
|
||||
|
||||
private <T extends CompileSpec> VersionAwareCompiler<T> versionAwareCompiler(Compiler<T> compiler, String toolType) {
|
||||
return new VersionAwareCompiler<>(compiler, new DefaultCompilerVersion(toolType,
|
||||
tool.getSingleFile().getName(), VersionNumber.parse(toolVersion)));
|
||||
}
|
||||
|
||||
private CommandLineToolInvocationWorker commandLineTool(String name) {
|
||||
return new DefaultCommandLineToolInvocationWorker(name, tool.getSingleFile(), getExecActionFactory());
|
||||
}
|
||||
|
||||
private CommandLineToolContext context() {
|
||||
return new DefaultMutableCommandLineToolContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutableName(String executablePath) {
|
||||
return executablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSharedLibraryName(String libraryPath) {
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImportLibraryName(String libraryPath) {
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSharedLibraryLinkFileName(String libraryPath) {
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStaticLibraryName(String libraryPath) {
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutableSymbolFileName(String executablePath) {
|
||||
return executablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibrarySymbolFileName(String libraryPath) {
|
||||
return libraryPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemLibraries getSystemLibraries(ToolType compilerType) {
|
||||
return new EmptySystemLibraries();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean producesImportLibrary() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresDebugBinaryStripping() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explain(DiagnosticsVisitor visitor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectFileExtension() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(Class<T> toolType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompilerMetadata getCompilerMetadata(ToolType compilerType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandLineToolSearchResult locateTool(ToolType compilerType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Inject
|
||||
protected abstract BuildOperationExecutor getBuildOperationExecutor();
|
||||
|
||||
@Inject
|
||||
protected abstract CompilerOutputFileNamingSchemeFactory getCompilerOutputFileNamingSchemeFactory();
|
||||
|
||||
@Inject
|
||||
protected abstract ExecActionFactory getExecActionFactory();
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerLeaseService getWorkerLeaseService();
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.gradle.internal.Transformers;
|
||||
import org.gradle.internal.operations.BuildOperationExecutor;
|
||||
import org.gradle.internal.process.ArgWriter;
|
||||
import org.gradle.internal.work.WorkerLeaseService;
|
||||
import org.gradle.nativeplatform.internal.CompilerOutputFileNamingSchemeFactory;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocation;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationWorker;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeCompiler;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.AssembleSpec;
|
||||
|
||||
public class Assembler extends NativeCompiler<AssembleSpec> {
|
||||
|
||||
private final String objectFileExtension;
|
||||
|
||||
public Assembler(BuildOperationExecutor buildOperationExecutor,
|
||||
CompilerOutputFileNamingSchemeFactory compilerOutputFileNamingSchemeFactory,
|
||||
CommandLineToolInvocationWorker commandLineTool,
|
||||
CommandLineToolContext invocationContext,
|
||||
String objectFileExtension,
|
||||
WorkerLeaseService workerLeaseService) {
|
||||
super(buildOperationExecutor, compilerOutputFileNamingSchemeFactory, commandLineTool, invocationContext,
|
||||
new AssemblerArgsTransformer(), Transformers.noOpTransformer(),
|
||||
objectFileExtension, true,
|
||||
workerLeaseService);
|
||||
|
||||
this.objectFileExtension = objectFileExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandLineToolInvocation createPerFileInvocation(List<String> genericArgs,
|
||||
File sourceFile,
|
||||
File objectDir,
|
||||
AssembleSpec spec) {
|
||||
List<String> sourceArgs = this.getSourceArgs(sourceFile);
|
||||
List<String> outputArgs = this.getOutputArgs(spec, this.getOutputFileDir(sourceFile, objectDir,
|
||||
objectFileExtension));
|
||||
List<String> pchArgs = this.maybeGetPCHArgs(spec, sourceFile);
|
||||
|
||||
// Changed order: put 'outputArgs' first
|
||||
return this.newInvocation("compiling ".concat(sourceFile.getName()), objectDir,
|
||||
this.buildPerFileArgs(outputArgs, genericArgs, sourceArgs, pchArgs), spec.getOperationLogger());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<String> buildPerFileArgs(List<String> genericArgs,
|
||||
List<String> sourceArgs,
|
||||
List<String> outputArgs,
|
||||
List<String> pchArgs) {
|
||||
if (pchArgs != null && !pchArgs.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Precompiled header arguments cannot be specified for an Assembler compiler.");
|
||||
}
|
||||
return super.buildPerFileArgs(genericArgs, sourceArgs, outputArgs, pchArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getOutputArgs(AssembleSpec spec, File outputFile) {
|
||||
return Arrays.asList("-o", outputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOptionsFileArgs(List<String> args, File tempDir) {
|
||||
ArrayList<String> originalArgs = new ArrayList<>(args);
|
||||
args.clear();
|
||||
args.addAll(ArgWriter.argsFileGenerator(new File(tempDir, "options.txt"),
|
||||
ArgWriter.unixStyleFactory()).transform(originalArgs));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getPCHArgs(AssembleSpec spec) {
|
||||
List<String> pchArgs = new ArrayList<>();
|
||||
if (spec.getPrefixHeaderFile() != null) {
|
||||
pchArgs.add("-include");
|
||||
pchArgs.add(spec.getPrefixHeaderFile().getAbsolutePath());
|
||||
}
|
||||
return pchArgs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.util.List;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.nativeplatform.toolchain.internal.ArgsTransformer;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.AssembleSpec;
|
||||
|
||||
@NonNullApi
|
||||
public class AssemblerArgsTransformer implements ArgsTransformer<AssembleSpec> {
|
||||
|
||||
@Override
|
||||
public List<String> transform(AssembleSpec assembleSpec) {
|
||||
return assembleSpec.getAllArgs();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.gradle.internal.Transformers;
|
||||
import org.gradle.internal.operations.BuildOperationExecutor;
|
||||
import org.gradle.internal.process.ArgWriter;
|
||||
import org.gradle.internal.work.WorkerLeaseService;
|
||||
import org.gradle.nativeplatform.internal.CompilerOutputFileNamingSchemeFactory;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocation;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationWorker;
|
||||
import org.gradle.nativeplatform.toolchain.internal.NativeCompiler;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.CCompileSpec;
|
||||
import org.xbib.gradle.plugin.c.tasks.ExtendedCCompileSpec;
|
||||
|
||||
public class CCompiler extends NativeCompiler<CCompileSpec> {
|
||||
|
||||
public CCompiler(BuildOperationExecutor buildOperationExecutor,
|
||||
CompilerOutputFileNamingSchemeFactory compilerOutputFileNamingSchemeFactory,
|
||||
CommandLineToolInvocationWorker commandLineToolInvocationWorker,
|
||||
CommandLineToolContext invocationContext,
|
||||
String objectFileExtension,
|
||||
WorkerLeaseService workerLeaseService) {
|
||||
super(buildOperationExecutor, compilerOutputFileNamingSchemeFactory, commandLineToolInvocationWorker, invocationContext,
|
||||
new CCompilerArgsTransformer(), Transformers.noOpTransformer(),
|
||||
objectFileExtension, true, workerLeaseService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getOutputArgs(CCompileSpec spec, File outputFile) {
|
||||
return Arrays.asList("-o", outputFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOptionsFileArgs(List<String> args, File tempDir) {
|
||||
ArrayList<String> originalArgs = new ArrayList<>(args);
|
||||
args.clear();
|
||||
args.addAll(ArgWriter.argsFileGenerator(new File(tempDir, "options.txt"),
|
||||
ArgWriter.unixStyleFactory()).transform(originalArgs));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getPCHArgs(CCompileSpec spec) {
|
||||
List<String> pchArgs = new ArrayList<>();
|
||||
if (spec.getPrefixHeaderFile() != null) {
|
||||
pchArgs.add("-include");
|
||||
pchArgs.add(spec.getPrefixHeaderFile().getAbsolutePath());
|
||||
}
|
||||
return pchArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandLineToolInvocation createPerFileInvocation(List<String> genericArgs,
|
||||
File sourceFile,
|
||||
File objectDir,
|
||||
CCompileSpec spec) {
|
||||
ExtendedCCompileSpec extendedCCompileSpec = (ExtendedCCompileSpec) spec;
|
||||
List<String> perFileArgs = extendedCCompileSpec.getPerFileCompilerArgs().get(sourceFile.getName());
|
||||
if (perFileArgs != null) {
|
||||
List<String> allPerFileArgs = new ArrayList<>(genericArgs);
|
||||
allPerFileArgs.addAll(perFileArgs);
|
||||
return super.createPerFileInvocation(allPerFileArgs, sourceFile, objectDir, spec);
|
||||
} else {
|
||||
return super.createPerFileInvocation(genericArgs, sourceFile, objectDir, spec);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.nativeplatform.toolchain.internal.ArgsTransformer;
|
||||
import org.gradle.nativeplatform.toolchain.internal.MacroArgsConverter;
|
||||
import org.gradle.nativeplatform.toolchain.internal.compilespec.CCompileSpec;
|
||||
|
||||
@NonNullApi
|
||||
public class CCompilerArgsTransformer implements ArgsTransformer<CCompileSpec> {
|
||||
|
||||
@Override
|
||||
public List<String> transform(CCompileSpec spec) {
|
||||
List<String> args = new ArrayList<>();
|
||||
|
||||
for (File file : spec.getIncludeRoots()) {
|
||||
args.add("-I");
|
||||
args.add(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
for (File file : spec.getSystemIncludeRoots()) {
|
||||
args.add("-isystem");
|
||||
args.add(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
for (String macroArg : new MacroArgsConverter().transform(spec.getMacros())) {
|
||||
args.add("-D" + macroArg);
|
||||
}
|
||||
args.addAll(spec.getAllArgs());
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.internal.operations.BuildOperationExecutor;
|
||||
import org.gradle.internal.operations.BuildOperationQueue;
|
||||
import org.gradle.internal.process.ArgWriter;
|
||||
import org.gradle.internal.work.WorkerLeaseService;
|
||||
import org.gradle.nativeplatform.internal.LinkerSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.AbstractCompiler;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocation;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationWorker;
|
||||
|
||||
public class Linker extends AbstractCompiler<LinkerSpec> {
|
||||
|
||||
public Linker(BuildOperationExecutor buildOperationExecutor,
|
||||
CommandLineToolInvocationWorker commandLineToolInvocationWorker,
|
||||
CommandLineToolContext invocationContext,
|
||||
WorkerLeaseService workerLeaseService) {
|
||||
super(buildOperationExecutor, commandLineToolInvocationWorker, invocationContext,
|
||||
new LinkerArgsTransformer(),
|
||||
true, workerLeaseService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action<BuildOperationQueue<CommandLineToolInvocation>> newInvocationAction(final LinkerSpec spec,
|
||||
List<String> args) {
|
||||
final CommandLineToolInvocation invocation = newInvocation("linking " + spec.getOutputFile().getName(),
|
||||
args, spec.getOperationLogger());
|
||||
return buildQueue -> {
|
||||
buildQueue.setLogLocation(spec.getOperationLogger().getLogLocation());
|
||||
buildQueue.add(invocation);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOptionsFileArgs(List<String> args, File tempDir) {
|
||||
ArrayList<String> originalArgs = new ArrayList<>(args);
|
||||
args.clear();
|
||||
args.addAll(ArgWriter.argsFileGenerator(new File(tempDir, "options.txt"),
|
||||
ArgWriter.unixStyleFactory()).transform(originalArgs));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.nativeplatform.internal.LinkerSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.ArgsTransformer;
|
||||
|
||||
@NonNullApi
|
||||
public class LinkerArgsTransformer implements ArgsTransformer<LinkerSpec> {
|
||||
|
||||
@Override
|
||||
public List<String> transform(LinkerSpec spec) {
|
||||
|
||||
List<String> args = new ArrayList<>(spec.getSystemArgs());
|
||||
|
||||
args.addAll(spec.getArgs());
|
||||
|
||||
for (File file : spec.getObjectFiles()) {
|
||||
args.add(file.getAbsolutePath());
|
||||
}
|
||||
for (File file : spec.getLibraries()) {
|
||||
args.add(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
args.add("-o");
|
||||
args.add(spec.getOutputFile().getAbsolutePath());
|
||||
|
||||
if (!spec.getLibraryPath().isEmpty()) {
|
||||
throw new UnsupportedOperationException("Library Path not yet supported");
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.tasks.WorkResult;
|
||||
import org.gradle.internal.operations.BuildOperationExecutor;
|
||||
import org.gradle.internal.operations.BuildOperationQueue;
|
||||
import org.gradle.internal.work.WorkerLeaseService;
|
||||
import org.gradle.nativeplatform.internal.StaticLibraryArchiverSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.AbstractCompiler;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolContext;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocation;
|
||||
import org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationWorker;
|
||||
|
||||
public class StaticLibraryArchiver extends AbstractCompiler<StaticLibraryArchiverSpec> {
|
||||
|
||||
public StaticLibraryArchiver(BuildOperationExecutor buildOperationExecutor,
|
||||
CommandLineToolInvocationWorker commandLineToolInvocationWorker,
|
||||
CommandLineToolContext invocationContext,
|
||||
WorkerLeaseService workerLeaseService) {
|
||||
super(buildOperationExecutor, commandLineToolInvocationWorker, invocationContext,
|
||||
new StaticLibraryArchiverArgsTransformer(), false, workerLeaseService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkResult execute(final StaticLibraryArchiverSpec spec) {
|
||||
deletePreviousOutput(spec);
|
||||
return super.execute(spec);
|
||||
}
|
||||
|
||||
private void deletePreviousOutput(StaticLibraryArchiverSpec spec) {
|
||||
// Need to delete the previous archive, otherwise stale object files will remain
|
||||
if (!spec.getOutputFile().isFile()) {
|
||||
return;
|
||||
}
|
||||
if (!(spec.getOutputFile().delete())) {
|
||||
throw new GradleException("Create static archive failed: could not delete previous archive");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action<BuildOperationQueue<CommandLineToolInvocation>> newInvocationAction(final StaticLibraryArchiverSpec spec,
|
||||
List<String> args) {
|
||||
final CommandLineToolInvocation invocation = newInvocation(
|
||||
"archiving " + spec.getOutputFile().getName(), spec.getOutputFile().getParentFile(), args, spec.getOperationLogger());
|
||||
|
||||
return buildQueue -> {
|
||||
buildQueue.setLogLocation(spec.getOperationLogger().getLogLocation());
|
||||
buildQueue.add(invocation);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOptionsFileArgs(List<String> args, File tempDir) {
|
||||
// No support for command file
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.gradle.api.NonNullApi;
|
||||
import org.gradle.nativeplatform.internal.StaticLibraryArchiverSpec;
|
||||
import org.gradle.nativeplatform.toolchain.internal.ArgsTransformer;
|
||||
|
||||
@NonNullApi
|
||||
public class StaticLibraryArchiverArgsTransformer implements ArgsTransformer<StaticLibraryArchiverSpec> {
|
||||
|
||||
public List<String> transform(StaticLibraryArchiverSpec spec) {
|
||||
List<String> args = new ArrayList<>(spec.getAllArgs());
|
||||
|
||||
args.add("-rv");
|
||||
|
||||
args.add(spec.getOutputFile().getAbsolutePath());
|
||||
|
||||
for (File file : spec.getObjectFiles()) {
|
||||
args.add(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package org.xbib.gradle.plugin.c.toolchain.transform;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import org.gradle.api.artifacts.transform.InputArtifact;
|
||||
import org.gradle.api.artifacts.transform.TransformAction;
|
||||
import org.gradle.api.artifacts.transform.TransformOutputs;
|
||||
import org.gradle.api.artifacts.transform.TransformParameters;
|
||||
import org.gradle.api.file.FileSystemLocation;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.PathSensitive;
|
||||
import org.gradle.api.tasks.PathSensitivity;
|
||||
import org.gradle.internal.os.OperatingSystem;
|
||||
|
||||
public abstract class ExtractZipTransform implements TransformAction<TransformParameters.None> {
|
||||
|
||||
@InputArtifact
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
public abstract Provider<FileSystemLocation> getInputArtifact();
|
||||
|
||||
@Override
|
||||
public void transform(TransformOutputs outputs) {
|
||||
File input = getInputArtifact().get().getAsFile();
|
||||
File unzipDir = outputs.dir(input.getName().substring(0, input.getName().lastIndexOf(".zip")));
|
||||
try {
|
||||
unzipTo(input, unzipDir);
|
||||
System.out.println("Transformed into: " + unzipDir.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void unzipTo(File input, File unzipDir) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
ZipInputStream zis = new ZipInputStream(Files.newInputStream(input.toPath()));
|
||||
ZipEntry zipEntry = zis.getNextEntry();
|
||||
|
||||
while (zipEntry != null) {
|
||||
if (!zipEntry.isDirectory()) {
|
||||
File newFile = new File(unzipDir, zipEntry.getName());
|
||||
newFile.getParentFile().mkdirs();
|
||||
FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
if (OperatingSystem.current().isUnix()) {
|
||||
Files.setPosixFilePermissions(newFile.toPath(), PosixFilePermissions.fromString("rwxr-xr-x"));
|
||||
}
|
||||
}
|
||||
zipEntry = zis.getNextEntry();
|
||||
}
|
||||
|
||||
zis.closeEntry();
|
||||
zis.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.xbib.gradle.plugin.c.test
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class CPluginIntegrationTest {
|
||||
|
||||
private File projectDir
|
||||
|
||||
private File settingsFile
|
||||
|
||||
private File buildFile
|
||||
|
||||
@BeforeEach
|
||||
void setup(@TempDir File testProjectDir) throws IOException {
|
||||
this.projectDir = testProjectDir
|
||||
this.settingsFile = new File(testProjectDir, "settings.gradle")
|
||||
this.buildFile = new File(testProjectDir, "build.gradle")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPlugin() {
|
||||
String settingsFileContent = '''
|
||||
rootProject.name = 'c-test'
|
||||
'''
|
||||
settingsFile.write(settingsFileContent)
|
||||
String buildFileContent = '''
|
||||
|
||||
plugins {
|
||||
id 'base'
|
||||
id 'org.xbib.gradle.plugin.c'
|
||||
}
|
||||
|
||||
// dummy task, no source present
|
||||
|
||||
tasks.register('compileC', org.xbib.gradle.plugin.c.tasks.ExtendedCCompile) {
|
||||
toolChain.set(c.localTool("14.0.0", "/usr/bin/clang", ".o"))
|
||||
targetPlatform.set(c.platform())
|
||||
source(layout.projectDirectory.files("src/c").asFileTree)
|
||||
includes(layout.projectDirectory.files("src/headers"))
|
||||
compilerArgs.add("-S")
|
||||
objectFileDir.set(layout.buildDirectory.dir("out/o"))
|
||||
}
|
||||
|
||||
'''
|
||||
buildFile.write(buildFileContent)
|
||||
BuildResult result = GradleRunner.create()
|
||||
.withProjectDir(projectDir)
|
||||
.withPluginClasspath()
|
||||
.withArguments(":compileC", "--info", "--stacktrace", "--warning-mode=all")
|
||||
.forwardOutput()
|
||||
.build()
|
||||
assertEquals(TaskOutcome.NO_SOURCE, result.task(":compileC").getOutcome())
|
||||
}
|
||||
}
|
8
gradle-plugin-cmake/NOTICE.txt
Normal file
8
gradle-plugin-cmake/NOTICE.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
This work is based on
|
||||
|
||||
https://github.com/crimsonmagick/gradle-cmake-plugin
|
||||
|
||||
as of Januar 8, 2024
|
||||
|
||||
License: Apache 2.0
|
185
gradle-plugin-cmake/README.md
Normal file
185
gradle-plugin-cmake/README.md
Normal file
|
@ -0,0 +1,185 @@
|
|||
# gradle-plugin-cmake
|
||||
|
||||
This plugin allows to configure and build using CMake.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* `CMake` installed on the system. Available [here](https://www.cmake.org "CMake Homepage").
|
||||
|
||||
## To apply the plugin:
|
||||
|
||||
**plugins DSL**
|
||||
|
||||
```groovy
|
||||
plugins {
|
||||
id 'org.xbib.gradle.plugin.cmake' version '3.1.0'
|
||||
}
|
||||
```
|
||||
|
||||
**Legacy plugin application**
|
||||
|
||||
```groovy
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.xbib.gradle:gradle-plugin-cmake:3.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "org.xbib.gradle.plugin.cmake"
|
||||
```
|
||||
|
||||
and configure by:
|
||||
|
||||
```groovy
|
||||
cmake {
|
||||
// optional configration to path of cmake. Not required if cmake is on the path.
|
||||
executable='/my/path/to/cmake'
|
||||
// optional working folder. default is ./build/cmake
|
||||
workingFolder=file("$buildDir/cmake")
|
||||
// cmakeConfigure parameters
|
||||
// optional source folder. This is where the main CMakeLists.txt file resides. Default is ./src/main/cpp
|
||||
sourceFolder=file("$projectDir/src/main/cpp")
|
||||
// optional install prefix. By default, install prefix is empty.
|
||||
installPrefix="${System.properties['user.home']}"
|
||||
// select a generator (optional, otherwise cmake's default generator is used)
|
||||
generator='Visual Studio 15 2017'
|
||||
// set a platform for generators that support it (usually Visual Studio)
|
||||
platform='x64'
|
||||
// set a toolset generators that support it (usually only Visual Studio)
|
||||
toolset='v141'
|
||||
// optionally set to build static libs
|
||||
buildStaticLibs=true
|
||||
// optionally set to build shared libs
|
||||
buildSharedLibs=true
|
||||
// define arbitrary CMake parameters. The below adds -Dtest=hello to cmake command line.
|
||||
defs.test='hello'
|
||||
// cmakeBuild parameters
|
||||
// optional configuration to build
|
||||
buildConfig='Release'
|
||||
// optional build target
|
||||
buildTarget='install'
|
||||
// optional build clean. if set to true, calls cmake --build with --clean-first
|
||||
buildClean=false
|
||||
}
|
||||
```
|
||||
|
||||
## Auto-created tasks
|
||||
|
||||
* *cmakeConfigure*: Calls CMake to generate your build scripts in the folder selected by workingFolder.
|
||||
|
||||
* *cmakeBuild*: Calls CMake --build in the folder selected by workingFolder to actually build.
|
||||
|
||||
* *cmakeClean*: Cleans the workingFolder.
|
||||
|
||||
* *cmakeGenerators*: Trys to list the generators available on the current platform by parsing `cmake --help`'s output.
|
||||
|
||||
## Examples
|
||||
|
||||
clean, configure and build:
|
||||
|
||||
```bash
|
||||
./gradlew cmakeClean cmakeConfigure cmakeBuild
|
||||
```
|
||||
|
||||
if you have assemble and clean tasks in your gradle project already you can also use:
|
||||
|
||||
```bash
|
||||
assemble.dependsOn cmakeBuild
|
||||
cmakeBuild.dependsOn cmakeConfigure
|
||||
clean.dependsOn cmakeClean
|
||||
```
|
||||
|
||||
and just call
|
||||
|
||||
```bash
|
||||
./gradlew clean assemble
|
||||
```
|
||||
|
||||
If you want to get the output of cmake, add -i to your gradle call, for example:
|
||||
|
||||
```bash
|
||||
./gradlew cmakeConfigure -i
|
||||
```
|
||||
|
||||
## Custom tasks
|
||||
|
||||
You can create custom tasks the following way:
|
||||
|
||||
```groovy
|
||||
task configureFoo(type: org.xbib.gradle.plugin.cmake.CMakeConfigureTask) {
|
||||
sourceFolder=file("$projectDir/src/main/cpp/foo")
|
||||
workingFolder=file("$buildDir/cmake/foo")
|
||||
// ... other parameters you need, see above, except the ones listed under cmakeBuild Parameters
|
||||
}
|
||||
|
||||
task buildFoo(type: org.xbib.gradle.plugin.cmake.CMakeBuildTask) {
|
||||
workingFolder=file("$buildDir/cmake/foo")
|
||||
// ... other parameters you need, see above, except the ones listed under cmakeConfigure parameters
|
||||
}
|
||||
|
||||
buildFoo.dependsOn configureFoo // optional --- make sure its configured when you run the build task
|
||||
```
|
||||
### Multiple targets (cross-compilation)
|
||||
If you need to configure for multiple targets you can use the `targets` property:
|
||||
|
||||
```groovy
|
||||
cmake {
|
||||
sourceFolder = "$projectDir/src"
|
||||
buildSharedLibs = true
|
||||
buildClean = true
|
||||
buildConfig = 'Release'
|
||||
targets {
|
||||
windows {
|
||||
final os = OperatingSystem.WINDOWS
|
||||
workingFolder = new File(project.getBuildDir(), "cmake" + File.separator + os.nativePrefix)
|
||||
platform='x64'
|
||||
}
|
||||
linux {
|
||||
final os = OperatingSystem.LINUX
|
||||
workingFolder = new File(project.getBuildDir(), "cmake" + File.separator + os.nativePrefix)
|
||||
platform = 'x64'
|
||||
}
|
||||
mac {
|
||||
final os = OperatingSystem.MAC_OS
|
||||
workingFolder = new File(project.getBuildDir(), "cmake" + File.separator + os.nativePrefix)
|
||||
platform = 'arm64'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Custom tasks using main configuration
|
||||
|
||||
As an alternative to using `targets` you can "import" the settings you've made in the main configuration "cmake" using the 'configureFromProject()' call:
|
||||
|
||||
```groovy
|
||||
cmake {
|
||||
executable='/my/path/to/cmake'
|
||||
workingFolder=file("$buildDir/cmake")
|
||||
sourceFolder=file("$projectDir/src/main/cpp")
|
||||
installPrefix="${System.properties['user.home']}"
|
||||
generator='Visual Studio 15 2017'
|
||||
platform='x64'
|
||||
}
|
||||
|
||||
task cmakeConfigureX86(type: org.xbib.gradle.plugin.cmake.CMakeConfigureTask) {
|
||||
configureFromProject() // uses everything in the cmake { ... } section.
|
||||
// overwrite target platform
|
||||
platform='x86'
|
||||
// set a different working folder to not collide with default task
|
||||
workingFolder=file("$buildDir/cmake_x86")
|
||||
}
|
||||
|
||||
task cmakeBuildX86(type: org.xbib.gradle.plugin.cmake.CMakeBuildTask) {
|
||||
configureFromProject() // uses everything in the cmake { ... } section.
|
||||
workingFolder=file("$buildDir/cmake_x86")
|
||||
}
|
||||
|
||||
cmakeBuildX86.dependsOn cmakeConfigureX86
|
||||
```
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
|
||||
apply plugin: 'com.gradle.plugin-publish'
|
||||
|
||||
apply from: rootProject.file('gradle/compile/java.gradle')
|
||||
apply from: rootProject.file('gradle/compile/groovy.gradle')
|
||||
apply from: rootProject.file('gradle/test/junit5.gradle')
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package org.xbib.gradle.plugin.cmake.test
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class CmakePluginIntegrationTest {
|
||||
|
||||
private File projectDir
|
||||
|
||||
private File settingsFile
|
||||
|
||||
private File buildFile
|
||||
|
||||
@BeforeEach
|
||||
void setup(@TempDir File testProjectDir) throws IOException {
|
||||
this.projectDir = testProjectDir
|
||||
File f = new File(testProjectDir, 'build/src/main/cpp')
|
||||
f.mkdirs()
|
||||
File cmakeList = new File(f, 'CMakeLists.txt')
|
||||
cmakeList.write('')
|
||||
this.settingsFile = new File(testProjectDir, "settings.gradle")
|
||||
this.buildFile = new File(testProjectDir, "build.gradle")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPlugin() {
|
||||
String settingsFileContent = '''
|
||||
rootProject.name = 'cmake-test'
|
||||
'''
|
||||
settingsFile.write(settingsFileContent)
|
||||
String buildFileContent = '''
|
||||
|
||||
plugins {
|
||||
id 'org.xbib.gradle.plugin.cmake'
|
||||
}
|
||||
|
||||
'''
|
||||
buildFile.write(buildFileContent)
|
||||
BuildResult result = GradleRunner.create()
|
||||
.withProjectDir(projectDir)
|
||||
.withPluginClasspath()
|
||||
.withArguments(":cmakeConfigure", "--info", "--stacktrace", "--warning-mode=all")
|
||||
.forwardOutput()
|
||||
.build()
|
||||
assertEquals(TaskOutcome.SUCCESS, result.task(":cmakeConfigure").getOutcome())
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ dependencyResolutionManagement {
|
|||
libs {
|
||||
version('gradle', '8.5')
|
||||
version('groovy', '3.0.17') // MUST match gradle groovy version
|
||||
// Java 21
|
||||
version('asm', '9.6')
|
||||
// Attention: it is impossible to develop a gradle plugin with groovy 4!
|
||||
// The gradle plugin publish plugin enforces java-gradle-plugin,
|
||||
|
@ -42,6 +43,7 @@ dependencyResolutionManagement {
|
|||
}
|
||||
|
||||
include 'gradle-plugin-asciidoctor'
|
||||
include 'gradle-plugin-c'
|
||||
include 'gradle-plugin-cmake'
|
||||
include 'gradle-plugin-docker'
|
||||
include 'gradle-plugin-git'
|
||||
|
|
Loading…
Reference in a new issue