/* * Copyright 2014 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.rc.tasks; import org.gradle.api.DefaultTask; import org.gradle.api.Incubating; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; import org.gradle.api.internal.changedetection.changes.DiscoveredInputRecorder; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.WorkResult; import org.gradle.api.tasks.incremental.IncrementalTaskInputs; import org.gradle.internal.Cast; import org.gradle.internal.operations.logging.BuildOperationLogger; import org.gradle.internal.operations.logging.BuildOperationLoggerFactory; import org.gradle.language.base.internal.compile.Compiler; import org.gradle.language.base.internal.compile.CompilerUtil; import org.gradle.language.nativeplatform.internal.incremental.IncrementalCompilerBuilder; import org.gradle.language.rc.internal.DefaultWindowsResourceCompileSpec; import org.gradle.nativeplatform.internal.BuildOperationLoggingCompilerDecorator; import org.gradle.nativeplatform.platform.NativePlatform; import org.gradle.nativeplatform.platform.internal.NativePlatformInternal; import org.gradle.nativeplatform.toolchain.NativeToolChain; import org.gradle.nativeplatform.toolchain.internal.NativeCompileSpec; import org.gradle.nativeplatform.toolchain.internal.NativeToolChainInternal; import org.gradle.nativeplatform.toolchain.internal.PlatformToolProvider; import javax.inject.Inject; import java.io.File; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; /** * Compiles Windows Resource scripts into .res files. */ @Incubating public class WindowsResourceCompile extends DefaultTask { private NativeToolChainInternal toolChain; private NativePlatformInternal targetPlatform; private File outputDir; private ConfigurableFileCollection includes; private ConfigurableFileCollection source; private Map<String, String> macros = new LinkedHashMap<String, String>(); private List<String> compilerArgs = new ArrayList<String>(); public WindowsResourceCompile() { includes = getProject().files(); source = getProject().files(); getInputs().property("outputType", new Callable<String>() { @Override public String call() throws Exception { return NativeToolChainInternal.Identifier.identify(toolChain, targetPlatform); } }); } @Inject public IncrementalCompilerBuilder getIncrementalCompilerBuilder() { throw new UnsupportedOperationException(); } @Inject public BuildOperationLoggerFactory getOperationLoggerFactory() { throw new UnsupportedOperationException(); } @TaskAction public void compile(IncrementalTaskInputs inputs) { BuildOperationLogger operationLogger = getOperationLoggerFactory().newOperationLogger(getName(), getTemporaryDir()); NativeCompileSpec spec = new DefaultWindowsResourceCompileSpec(); spec.setTempDir(getTemporaryDir()); spec.setObjectFileDir(getOutputDir()); spec.include(getIncludes()); spec.source(getSource()); spec.setMacros(getMacros()); spec.args(getCompilerArgs()); spec.setIncrementalCompile(inputs.isIncremental()); spec.setDiscoveredInputRecorder((DiscoveredInputRecorder) inputs); spec.setOperationLogger(operationLogger); PlatformToolProvider platformToolProvider = toolChain.select(targetPlatform); WorkResult result = doCompile(spec, platformToolProvider); setDidWork(result.getDidWork()); } private <T extends NativeCompileSpec> WorkResult doCompile(T spec, PlatformToolProvider platformToolProvider) { Class<T> specType = Cast.uncheckedCast(spec.getClass()); Compiler<T> baseCompiler = platformToolProvider.newCompiler(specType); Compiler<T> incrementalCompiler = getIncrementalCompilerBuilder().createIncrementalCompiler(this, baseCompiler, toolChain); Compiler<T> loggingCompiler = BuildOperationLoggingCompilerDecorator.wrap(incrementalCompiler); return CompilerUtil.castCompiler(loggingCompiler).execute(spec); } /** * The tool chain used for compilation. */ @Internal public NativeToolChain getToolChain() { return toolChain; } public void setToolChain(NativeToolChain toolChain) { this.toolChain = (NativeToolChainInternal) toolChain; } /** * The platform being targeted. */ @Nested public NativePlatform getTargetPlatform() { return targetPlatform; } public void setTargetPlatform(NativePlatform targetPlatform) { this.targetPlatform = (NativePlatformInternal) targetPlatform; } /** * The directory where object files will be generated. */ @OutputDirectory public File getOutputDir() { return outputDir; } public void setOutputDir(File outputDir) { this.outputDir = outputDir; } /** * Returns the header directories to be used for compilation. */ @InputFiles public FileCollection getIncludes() { return includes; } /** * Add directories where the compiler should search for header files. */ public void includes(Object includeRoots) { includes.from(includeRoots); } /** * Returns the source files to be compiled. */ @InputFiles public FileCollection getSource() { return source; } /** * Adds a set of source files to be compiled. The provided sourceFiles object is evaluated as per {@link org.gradle.api.Project#files(Object...)}. */ public void source(Object sourceFiles) { source.from(sourceFiles); } /** * Macros that should be defined for the compiler. */ @Input public Map<String, String> getMacros() { return macros; } public void setMacros(Map<String, String> macros) { this.macros = macros; } /** * Additional arguments to provide to the compiler. */ @Input public List<String> getCompilerArgs() { return compilerArgs; } public void setCompilerArgs(List<String> compilerArgs) { this.compilerArgs = compilerArgs; } }