org.gradle.nativeplatform.tasks.InstallExecutable 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 2016 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.nativeplatform.tasks;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.Incubating;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFile;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.internal.file.FileOperations;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.SkipWhenEmpty;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.nativeintegration.filesystem.FileSystem;
import org.gradle.internal.os.OperatingSystem;
import org.gradle.internal.work.WorkerLeaseService;
import org.gradle.nativeplatform.platform.NativePlatform;
import org.gradle.nativeplatform.toolchain.Gcc;
import org.gradle.platform.base.ToolChain;
import org.gradle.util.GFileUtils;
import javax.inject.Inject;
import java.io.File;
/**
* Installs an executable with it's dependent libraries so it can be easily executed.
*/
@Incubating
public class InstallExecutable extends DefaultTask {
private ToolChain toolChain;
private NativePlatform platform;
private final DirectoryProperty destinationDir;
private final RegularFileProperty executable;
private final ConfigurableFileCollection libs;
private final WorkerLeaseService workerLeaseService;
/**
* Injects a {@link WorkerLeaseService} instance.
*
* @since 4.2
*/
@Inject
public InstallExecutable(WorkerLeaseService workerLeaseService) {
this.workerLeaseService = workerLeaseService;
this.libs = getProject().files();
destinationDir = newOutputDirectory();
executable = newInputFile();
}
/**
* The tool chain used for linking.
*/
@Internal
public ToolChain getToolChain() {
return toolChain;
}
public void setToolChain(ToolChain toolChain) {
this.toolChain = toolChain;
}
/**
* The platform describing the install target.
*/
@Nested
public NativePlatform getPlatform() {
return platform;
}
public void setPlatform(NativePlatform platform) {
this.platform = platform;
}
/**
* The directory to install files into.
*
* @since 4.1
*/
@OutputDirectory
public DirectoryProperty getInstallDirectory() {
return destinationDir;
}
@Internal
public File getDestinationDir() {
return destinationDir.getAsFile().getOrNull();
}
public void setDestinationDir(File destinationDir) {
this.destinationDir.set(destinationDir);
}
/**
* Sets the destination directory to install the executable via a {@link Provider}
*
* @param destinationDir the destination directory provider to use
* @see #setDestinationDir(File)
* @since 4.1
*/
public void setDestinationDir(Provider extends Directory> destinationDir) {
this.destinationDir.set(destinationDir);
}
/**
* The executable file to install.
*
* @since 4.1
*/
@Internal("Covered by inputFileIfExists")
public RegularFileProperty getSourceFile() {
return executable;
}
@Internal("Covered by inputFileIfExists")
public File getExecutable() {
return executable.getAsFile().getOrNull();
}
public void setExecutable(File executable) {
this.executable.set(executable);
}
/**
* Sets the executable to install via a {@link Provider}
*
* @param executable the executable provider to use
* @see #setExecutable(File)
* @since 4.1
*/
public void setExecutable(Provider extends RegularFile> executable) {
this.executable.set(executable);
}
/**
* Workaround for when the task is given an input file that doesn't exist
*
* @since 4.3
*/
@SkipWhenEmpty
@Optional
@InputFile
protected File getInputFileIfExists() {
File inputFile = getExecutable();
if (inputFile != null && inputFile.exists()) {
return inputFile;
} else {
return null;
}
}
/**
* The library files that should be installed.
*/
@InputFiles
public FileCollection getLibs() {
return libs;
}
public void setLibs(FileCollection libs) {
this.libs.setFrom(libs);
}
/**
* Adds a set of library files to be installed. The provided libs object is evaluated as per {@link org.gradle.api.Project#files(Object...)}.
*/
public void lib(Object libs) {
this.libs.from(libs);
}
/**
* Returns the script file that can be used to run the install image.
*/
@Internal
public File getRunScript() {
OperatingSystem operatingSystem = OperatingSystem.forName(platform.getOperatingSystem().getName());
return new File(getDestinationDir(), operatingSystem.getScriptName(getExecutable().getName()));
}
@Inject
protected FileSystem getFileSystem() {
throw new UnsupportedOperationException();
}
@Inject
protected FileOperations getFileOperations() {
throw new UnsupportedOperationException();
}
@TaskAction
public void install() {
// TODO: Migrate this to the worker API once the FileSystem and FileOperations services can be injected
workerLeaseService.withoutProjectLock(new Runnable() {
@Override
public void run() {
if (platform.getOperatingSystem().isWindows()) {
installWindows();
} else {
installUnix();
}
}
});
}
private void installWindows() {
final File destination = getDestinationDir();
final File executable = getExecutable();
installToDir(new File(destination, "lib"));
StringBuilder toolChainPath = new StringBuilder();
if (toolChain instanceof Gcc) {
// Gcc on windows requires the path to be set
toolChainPath.append("SET PATH=");
for (File pathEntry : ((Gcc) toolChain).getPath()) {
toolChainPath.append(pathEntry.getAbsolutePath()).append(";");
}
toolChainPath.append("%PATH%");
}
String runScriptText =
"\n@echo off"
+ "\nSETLOCAL"
+ "\n" + toolChainPath
+ "\nCALL \"%~dp0lib\\" + executable.getName() + "\" %*"
+ "\nEXIT /B %ERRORLEVEL%"
+ "\nENDLOCAL"
+ "\n";
GFileUtils.writeFile(runScriptText, getRunScript());
}
private void installUnix() {
final File destination = getDestinationDir();
final File executable = getExecutable();
installToDir(new File(destination, "lib"));
String runScriptText =
"#!/bin/sh"
+ "\nAPP_BASE_NAME=`dirname \"$0\"`"
+ "\nDYLD_LIBRARY_PATH=\"$APP_BASE_NAME/lib\""
+ "\nexport DYLD_LIBRARY_PATH"
+ "\nLD_LIBRARY_PATH=\"$APP_BASE_NAME/lib\""
+ "\nexport LD_LIBRARY_PATH"
+ "\nexec \"$APP_BASE_NAME/lib/" + executable.getName() + "\" \"$@\""
+ "\n";
GFileUtils.writeFile(runScriptText, getRunScript());
getFileSystem().chmod(getRunScript(), 0755);
}
private void installToDir(final File binaryDir) {
getFileOperations().sync(new Action() {
public void execute(CopySpec copySpec) {
copySpec.into(binaryDir);
copySpec.from(getExecutable());
copySpec.from(getLibs());
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy