mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 08:46:02 +02:00
Bug 567488: Use command-line options to pass to cmake ICMakeProperties object
Change-Id: I4d6383ce240e6f2b8d7079f281ef7c2e56ea93a6 Signed-off-by: Martin Weber <fifteenknots505@gmail.com>
This commit is contained in:
parent
3a10f42019
commit
ebf2d24c95
5 changed files with 311 additions and 109 deletions
|
@ -20,3 +20,4 @@ Export-Package: org.eclipse.cdt.cmake.core,
|
|||
org.eclipse.cdt.cmake.core.properties
|
||||
Automatic-Module-Name: org.eclipse.cdt.cmake.core
|
||||
Bundle-Localization: plugin
|
||||
Import-Package: org.eclipse.core.variables
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.nio.file.Path;
|
|||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -27,6 +26,10 @@ import java.util.function.Consumer;
|
|||
|
||||
import org.eclipse.cdt.cmake.core.ICMakeToolChainFile;
|
||||
import org.eclipse.cdt.cmake.core.ICMakeToolChainManager;
|
||||
import org.eclipse.cdt.cmake.core.properties.CMakeGenerator;
|
||||
import org.eclipse.cdt.cmake.core.properties.ICMakeProperties;
|
||||
import org.eclipse.cdt.cmake.core.properties.ICMakePropertiesController;
|
||||
import org.eclipse.cdt.cmake.core.properties.IOsOverrides;
|
||||
import org.eclipse.cdt.cmake.is.core.CompileCommandsJsonParser;
|
||||
import org.eclipse.cdt.cmake.is.core.IIndexerInfoConsumer;
|
||||
import org.eclipse.cdt.cmake.is.core.ParseRequest;
|
||||
|
@ -56,6 +59,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
|
||||
public class CMakeBuildConfiguration extends CBuildConfiguration {
|
||||
|
||||
|
@ -66,6 +71,11 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
public static final String CLEAN_COMMAND = "cmake.command.clean"; //$NON-NLS-1$
|
||||
|
||||
private ICMakeToolChainFile toolChainFile;
|
||||
|
||||
private final CMakePropertiesController pc = new CMakePropertiesController(() -> {
|
||||
deleteCMakeCache = true;
|
||||
});
|
||||
|
||||
private Map<IResource, IScannerInfo> infoPerResource;
|
||||
/** whether one of the CMakeLists.txt files in the project has been
|
||||
* modified and saved by the user since the last build.<br>
|
||||
|
@ -76,6 +86,9 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
* To work around that, we run cmake in advance with its dedicated working error parser.
|
||||
*/
|
||||
private boolean cmakeListsModified;
|
||||
/** whether we have to delete file CMakeCache.txt to avoid complaints by cmake
|
||||
*/
|
||||
private boolean deleteCMakeCache;
|
||||
|
||||
public CMakeBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
|
||||
super(config, name);
|
||||
|
@ -94,10 +107,16 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
this.toolChainFile = toolChainFile;
|
||||
}
|
||||
|
||||
/** Gets the tool-chain description file to pass to the cmake command-line.
|
||||
*
|
||||
* @return the tool-chain file or <code>null</code> if cmake should take the native (i.e. the tools first found on
|
||||
* the executable search path aka $path)
|
||||
*/
|
||||
public ICMakeToolChainFile getToolChainFile() {
|
||||
return toolChainFile;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // kept for reference of the property names
|
||||
private boolean isLocal() throws CoreException {
|
||||
IToolChain toolchain = getToolChain();
|
||||
return (Platform.getOS().equals(toolchain.getProperty(IToolChain.ATTR_OS))
|
||||
|
@ -110,81 +129,36 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
throws CoreException {
|
||||
IProject project = getProject();
|
||||
|
||||
try {
|
||||
String generator = getProperty(CMAKE_GENERATOR);
|
||||
if (generator == null) {
|
||||
generator = "Ninja"; //$NON-NLS-1$
|
||||
}
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
|
||||
infoPerResource = new HashMap<>();
|
||||
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
|
||||
infoPerResource = new HashMap<>();
|
||||
try {
|
||||
|
||||
ConsoleOutputStream infoStream = console.getInfoStream();
|
||||
|
||||
Path buildDir = getBuildDirectory();
|
||||
|
||||
infoStream.write(String.format(Messages.CMakeBuildConfiguration_BuildingIn, buildDir.toString()));
|
||||
|
||||
// Make sure we have a toolchain file if cross
|
||||
if (toolChainFile == null && !isLocal()) {
|
||||
ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class);
|
||||
toolChainFile = manager.getToolChainFileFor(getToolChain());
|
||||
|
||||
if (toolChainFile == null) {
|
||||
// error
|
||||
console.getErrorStream().write(Messages.CMakeBuildConfiguration_NoToolchainFile);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean runCMake = cmakeListsModified;
|
||||
if (!runCMake) {
|
||||
switch (generator) {
|
||||
case "Ninja": //$NON-NLS-1$
|
||||
runCMake = !Files.exists(buildDir.resolve("build.ninja")); //$NON-NLS-1$
|
||||
break;
|
||||
case "Unix Makefiles": //$NON-NLS-1$
|
||||
runCMake = !Files.exists(buildDir.resolve("Makefile")); //$NON-NLS-1$
|
||||
break;
|
||||
default:
|
||||
runCMake = !Files.exists(buildDir.resolve("CMakeFiles")); //$NON-NLS-1$
|
||||
}
|
||||
if (deleteCMakeCache) {
|
||||
Files.deleteIfExists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$
|
||||
deleteCMakeCache = false;
|
||||
runCMake = true;
|
||||
}
|
||||
|
||||
ICMakeProperties cmakeProperties = pc.load();
|
||||
runCMake |= !Files.exists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$
|
||||
|
||||
IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties);
|
||||
CMakeGenerator generator = overrides.getGenerator();
|
||||
if (!runCMake) {
|
||||
runCMake |= !Files.exists(buildDir.resolve(generator.getMakefileName()));
|
||||
}
|
||||
if (runCMake) {
|
||||
CMakeBuildConfiguration.deleteCMakeErrorMarkers(project);
|
||||
|
||||
infoStream.write(String.format(Messages.CMakeBuildConfiguration_Configuring, buildDir));
|
||||
// clean output to make sure there is no content
|
||||
// incompatible with current settings (cmake config would fail)
|
||||
cleanBuildDirectory(buildDir);
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
|
||||
command.add("cmake"); //$NON-NLS-1$
|
||||
command.add("-G"); //$NON-NLS-1$
|
||||
command.add(generator);
|
||||
|
||||
if (toolChainFile != null) {
|
||||
command.add("-DCMAKE_TOOLCHAIN_FILE=" + toolChainFile.getPath().toString()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
switch (getLaunchMode()) {
|
||||
// TODO what to do with other modes
|
||||
case "debug": //$NON-NLS-1$
|
||||
command.add("-DCMAKE_BUILD_TYPE=Debug"); //$NON-NLS-1$
|
||||
break;
|
||||
case "run": //$NON-NLS-1$
|
||||
command.add("-DCMAKE_BUILD_TYPE=Release"); //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
command.add("-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"); //$NON-NLS-1$
|
||||
|
||||
String userArgs = getProperty(CMAKE_ARGUMENTS);
|
||||
if (userArgs != null) {
|
||||
command.addAll(Arrays.asList(userArgs.trim().split("\\s+"))); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
List<String> command = makeCMakeCommandline(cmakeProperties, overrides);
|
||||
// tell cmake where its script is located..
|
||||
IContainer srcFolder = project;
|
||||
command.add(new File(srcFolder.getLocationURI()).getAbsolutePath());
|
||||
|
||||
|
@ -197,6 +171,9 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
ParsingConsoleOutputStream errStream = new ParsingConsoleOutputStream(console.getErrorStream(),
|
||||
errorParser);
|
||||
IConsole errConsole = new CMakeConsoleWrapper(console, errStream);
|
||||
// TODO startBuildProcess() calls java.lang.ProcessBuilder.
|
||||
// Use org.eclipse.cdt.core.ICommandLauncher
|
||||
// in order to run builds in a container.
|
||||
Process p = startBuildProcess(command, new IEnvironmentVariable[0], workingDir, errConsole,
|
||||
monitor);
|
||||
if (p == null) {
|
||||
|
@ -209,11 +186,16 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
cmakeListsModified = false;
|
||||
}
|
||||
|
||||
// parse compile_commands.json file
|
||||
processCompileCommandsFile(console, monitor);
|
||||
|
||||
infoStream.write(String.format(Messages.CMakeBuildConfiguration_BuildingIn, buildDir.toString()));
|
||||
// run the build tool...
|
||||
try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this,
|
||||
getToolChain().getErrorParserIds())) {
|
||||
epm.setOutputStream(console.getOutputStream());
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
List<String> command = makeCMakeBuildCommandline(cmakeProperties, overrides, "all"); //$NON-NLS-1$
|
||||
|
||||
String envStr = getProperty(CMAKE_ENV);
|
||||
List<IEnvironmentVariable> envVars = new ArrayList<>();
|
||||
|
@ -229,23 +211,12 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
String buildCommand = getProperty(BUILD_COMMAND);
|
||||
if (buildCommand == null) {
|
||||
command.add("cmake"); //$NON-NLS-1$
|
||||
command.add("--build"); //$NON-NLS-1$
|
||||
command.add("."); //$NON-NLS-1$
|
||||
if ("Ninja".equals(generator)) { //$NON-NLS-1$
|
||||
command.add("--"); //$NON-NLS-1$
|
||||
command.add("-v"); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
command.addAll(Arrays.asList(buildCommand.split(" "))); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
infoStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$
|
||||
|
||||
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(
|
||||
getBuildDirectory().toString());
|
||||
// TODO startBuildProcess() calls java.lang.ProcessBuilder. Use org.eclipse.cdt.core.ICommandLauncher
|
||||
// in order to run builds in a container.
|
||||
Process p = startBuildProcess(command, envVars.toArray(new IEnvironmentVariable[0]), workingDir,
|
||||
console, monitor);
|
||||
if (p == null) {
|
||||
|
@ -257,11 +228,6 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
|
||||
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||
|
||||
// parse compile_commands.json file
|
||||
// built-ins detection output goes to the build console, if the user requested
|
||||
// output
|
||||
processCompileCommandsFile(console, monitor);
|
||||
|
||||
infoStream.write(String.format(Messages.CMakeBuildConfiguration_BuildingComplete, epm.getErrorCount(),
|
||||
epm.getWarningCount(), buildDir.toString()));
|
||||
}
|
||||
|
@ -273,14 +239,34 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cmakeProperties
|
||||
* @return
|
||||
*/
|
||||
private IOsOverrides extractCMakeOsOverrides(ICMakeProperties cmakeProperties) {
|
||||
IOsOverrides overrides;
|
||||
// get overrides. Simplistic approach ATM, probably a strategy might fit better.
|
||||
// see comment in CMakeIndexerInfoConsumer#getFileForCMakePath()
|
||||
final String os = Platform.getOS();
|
||||
if (Platform.OS_WIN32.equals(os)) {
|
||||
overrides = cmakeProperties.getWindowsOverrides();
|
||||
} else {
|
||||
// fall back to linux, if OS is unknown
|
||||
overrides = cmakeProperties.getLinuxOverrides();
|
||||
}
|
||||
return overrides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
|
||||
IProject project = getProject();
|
||||
try {
|
||||
String generator = getProperty(CMAKE_GENERATOR);
|
||||
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
|
||||
|
||||
ICMakeProperties cmakeProperties = pc.load();
|
||||
IOsOverrides overrides = extractCMakeOsOverrides(cmakeProperties);
|
||||
List<String> command = makeCMakeBuildCommandline(cmakeProperties, overrides, "clean"); //$NON-NLS-1$
|
||||
ConsoleOutputStream outStream = console.getOutputStream();
|
||||
|
||||
Path buildDir = getBuildDirectory();
|
||||
|
@ -290,27 +276,13 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
return;
|
||||
}
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
String cleanCommand = getProperty(CLEAN_COMMAND);
|
||||
if (cleanCommand == null) {
|
||||
if (generator == null || generator.equals("Ninja")) { //$NON-NLS-1$
|
||||
command.add("ninja"); //$NON-NLS-1$
|
||||
command.add("clean"); //$NON-NLS-1$
|
||||
} else {
|
||||
command.add("make"); //$NON-NLS-1$
|
||||
command.add("clean"); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
command.addAll(Arrays.asList(cleanCommand.split(" "))); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
IEnvironmentVariable[] env = new IEnvironmentVariable[0];
|
||||
|
||||
outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$
|
||||
|
||||
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(
|
||||
getBuildDirectory().toString());
|
||||
Process p = startBuildProcess(command, env, workingDir, console, monitor);
|
||||
// TODO startBuildProcess() calls java.lang.ProcessBuilder. Use org.eclipse.cdt.core.ICommandLauncher
|
||||
// in order to run builds in a container.
|
||||
Process p = startBuildProcess(command, new IEnvironmentVariable[0], workingDir, console, monitor);
|
||||
if (p == null) {
|
||||
console.getErrorStream().write(String.format(Messages.CMakeBuildConfiguration_Failure, "")); //$NON-NLS-1$
|
||||
return;
|
||||
|
@ -327,6 +299,130 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command-line for cmake. The first argument will be the
|
||||
* cmake-command.
|
||||
*
|
||||
* @throws CoreException
|
||||
*/
|
||||
private List<String> makeCMakeCommandline(ICMakeProperties cmakeProps, IOsOverrides osOverrideProps)
|
||||
throws CoreException {
|
||||
List<String> args = new ArrayList<>();
|
||||
|
||||
// default for all OSes (maybe replaced later)
|
||||
args.add("cmake"); //$NON-NLS-1$
|
||||
/* add general settings */
|
||||
if (cmakeProps.isWarnNoDev())
|
||||
args.add("-Wno-dev"); //$NON-NLS-1$
|
||||
if (cmakeProps.isDebugTryCompile())
|
||||
args.add("--debug-trycompile"); //$NON-NLS-1$
|
||||
if (cmakeProps.isDebugOutput())
|
||||
args.add("--debug-output"); //$NON-NLS-1$
|
||||
if (cmakeProps.isTrace())
|
||||
args.add("--trace"); //$NON-NLS-1$
|
||||
if (cmakeProps.isWarnUnitialized())
|
||||
args.add("--warn-unitialized"); //$NON-NLS-1$
|
||||
if (cmakeProps.isWarnUnused())
|
||||
args.add("--warn-unused"); //$NON-NLS-1$
|
||||
{
|
||||
String file = cmakeProps.getCacheFile();
|
||||
if (!(file == null || file.isBlank())) {
|
||||
args.add("-C"); //$NON-NLS-1$
|
||||
args.add(file);
|
||||
}
|
||||
}
|
||||
if (toolChainFile != null) {
|
||||
args.add("-DCMAKE_TOOLCHAIN_FILE=" + toolChainFile.getPath().toString()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
appendCMakeArguments(args, cmakeProps.getExtraArguments());
|
||||
|
||||
/* add settings for the operating system we are running under */
|
||||
appendCMakeOsOverrideArgs(args, osOverrideProps);
|
||||
|
||||
/* add our requirements */
|
||||
{
|
||||
// set argument for build type..
|
||||
String bt = cmakeProps.getBuildType();
|
||||
if (!(bt == null || bt.isBlank())) {
|
||||
args.add("-DCMAKE_BUILD_TYPE=" + bt); //$NON-NLS-1$
|
||||
}
|
||||
// tell cmake to write compile commands to a JSON file
|
||||
args.add("-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"); //$NON-NLS-1$
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command-line for cmake to build the project. The first argument will be the
|
||||
* cmake-command.
|
||||
*
|
||||
* @throws CoreException
|
||||
*/
|
||||
private List<String> makeCMakeBuildCommandline(ICMakeProperties cmakeProps, IOsOverrides osOverrides,
|
||||
String buildscriptTarget) throws CoreException {
|
||||
List<String> args = new ArrayList<>();
|
||||
|
||||
if (osOverrides.getUseDefaultCommand()) {
|
||||
args.add("cmake"); //$NON-NLS-1$
|
||||
} else {
|
||||
IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager();
|
||||
String cmd = varManager.performStringSubstitution(osOverrides.getCommand());
|
||||
args.add(cmd);
|
||||
}
|
||||
args.add("--build"); //$NON-NLS-1$
|
||||
args.add("."); //$NON-NLS-1$
|
||||
args.add("--target"); //$NON-NLS-1$
|
||||
args.add(buildscriptTarget);
|
||||
// TODO parallel build: use CMAKE_BUILD_PARALLEL_LEVEL envvar (since cmake 3.12)
|
||||
// TODO verbose build: use VERBOSE envvar (since cmake 3.14)
|
||||
// TODO stop on first error: query CMakeGenerator object for argument
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the additional arguments to pass on the cmake command-line. Performs variable substitutions.
|
||||
*
|
||||
* @param argList
|
||||
* the list to append cmake-arguments to
|
||||
* @param moreArgs
|
||||
* the arguments to substitute and append
|
||||
* @throws CoreException
|
||||
* if unable to resolve the value of one or more variables
|
||||
*/
|
||||
private void appendCMakeArguments(List<String> argList, final List<String> moreArgs) throws CoreException {
|
||||
IStringVariableManager mgr = VariablesPlugin.getDefault().getStringVariableManager();
|
||||
for (String arg : moreArgs) {
|
||||
String expanded = mgr.performStringSubstitution(arg);
|
||||
argList.add(expanded);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends arguments specific to the given OS preferences for build-script generation.
|
||||
* The first argument in the list will be replaced by the cmake command from the specified preferences,
|
||||
* if given.
|
||||
*
|
||||
* @param args
|
||||
* the list to append cmake-arguments to.
|
||||
* @param prefs
|
||||
* the generic OS specific cmake build properties to convert and append.
|
||||
* @throws CoreException
|
||||
* if unable to resolve the value of one or more variables
|
||||
*/
|
||||
private void appendCMakeOsOverrideArgs(List<String> args, final IOsOverrides prefs) throws CoreException {
|
||||
// replace cmake command, if given
|
||||
if (!prefs.getUseDefaultCommand()) {
|
||||
IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager();
|
||||
String cmd = varManager.performStringSubstitution(prefs.getCommand());
|
||||
args.set(0, cmd);
|
||||
}
|
||||
args.add("-G"); //$NON-NLS-1$
|
||||
final CMakeGenerator generator = prefs.getGenerator();
|
||||
args.add(generator.getCMakeName());
|
||||
appendCMakeArguments(args, prefs.getExtraArguments());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param console the console to print the compiler output during built-ins
|
||||
* detection to or <code>null</code> if no separate console is to
|
||||
|
@ -365,12 +461,17 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private void cleanBuildDirectory(Path buildDir) throws IOException {
|
||||
if (!Files.exists(buildDir))
|
||||
return;
|
||||
if (Files.isDirectory(buildDir))
|
||||
cleanDirectory(buildDir);
|
||||
// TODO: not a directory should we do something?
|
||||
// interface IAdaptable
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
T adapter0 = super.getAdapter(adapter);
|
||||
if (adapter0 == null) {
|
||||
if (ICMakePropertiesController.class.equals(adapter)) {
|
||||
adapter0 = (T) pc;
|
||||
}
|
||||
}
|
||||
return adapter0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -426,7 +527,8 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
IResource resource = resourceDelta.getResource();
|
||||
if (resource.getType() == IResource.FILE) {
|
||||
String name = resource.getName();
|
||||
if (name.equals("CMakeLists.txt") || name.endsWith(".cmake")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (!resource.isDerived(IResource.CHECK_ANCESTORS)
|
||||
&& (name.equals("CMakeLists.txt") || name.endsWith(".cmake"))) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
cmakeListsModified = true;
|
||||
return false; // stop processing
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Martin Weber.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.cmake.core.internal;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.cdt.cmake.core.internal.properties.CMakePropertiesBean;
|
||||
import org.eclipse.cdt.cmake.core.properties.CMakeGenerator;
|
||||
import org.eclipse.cdt.cmake.core.properties.ICMakeProperties;
|
||||
import org.eclipse.cdt.cmake.core.properties.ICMakePropertiesController;
|
||||
|
||||
/**
|
||||
* A {@code ICMakePropertiesController} that monitors modifications to the project properties that force
|
||||
* us to delete file CMakeCache.txt to avoid complaints by cmake.
|
||||
* @author Martin Weber
|
||||
*/
|
||||
class CMakePropertiesController implements ICMakePropertiesController {
|
||||
|
||||
private final Runnable cmakeCacheDirtyMarker;
|
||||
|
||||
private String cacheFile;
|
||||
private List<String> extraArguments;
|
||||
private CMakeGenerator generatorLinux;
|
||||
private List<String> extraArgumentsLinux;
|
||||
private CMakeGenerator generatorWindows;
|
||||
private List<String> extraArgumentsWindows;
|
||||
private String buildType;
|
||||
|
||||
/** Creates a new CMakePropertiesController object.
|
||||
*
|
||||
* @param cmakeCacheDirtyMarker
|
||||
* the object to notify when modifications to the project properties force
|
||||
* us to delete file CMakeCache.txt to avoid complaints by cmake
|
||||
*/
|
||||
CMakePropertiesController(Runnable cmakeCacheDirtyMarker) {
|
||||
this.cmakeCacheDirtyMarker = Objects.requireNonNull(cmakeCacheDirtyMarker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICMakeProperties load() {
|
||||
// TODO implement load()
|
||||
CMakePropertiesBean props = new CMakePropertiesBean();
|
||||
|
||||
setupModifyDetection(props);
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ICMakeProperties properties) {
|
||||
// detect whether changes force us to delete file CMakeCache.txt to avoid complaints by cmake
|
||||
if (!Objects.equals(buildType, properties.getBuildType())
|
||||
|| !Objects.equals(cacheFile, properties.getCacheFile())
|
||||
|| !Objects.equals(generatorLinux, properties.getLinuxOverrides().getGenerator())
|
||||
|| !Objects.equals(generatorWindows, properties.getWindowsOverrides().getGenerator())) {
|
||||
cmakeCacheDirtyMarker.run(); // must remove cmake cachefile
|
||||
} else if (extraArgumentsChange(extraArguments, properties.getExtraArguments())
|
||||
|| extraArgumentsChange(extraArgumentsLinux, properties.getLinuxOverrides().getExtraArguments())
|
||||
|| extraArgumentsChange(extraArgumentsWindows, properties.getWindowsOverrides().getExtraArguments())) {
|
||||
cmakeCacheDirtyMarker.run(); // must remove cmake cachefile
|
||||
}
|
||||
// TODO implement save()
|
||||
setupModifyDetection(properties);
|
||||
}
|
||||
|
||||
/** Sets up detection of modifications that force us to delete file CMakeCache.txt to avoid complaints by cmake
|
||||
*/
|
||||
private void setupModifyDetection(ICMakeProperties properties) {
|
||||
buildType = properties.getBuildType();
|
||||
cacheFile = properties.getCacheFile();
|
||||
extraArguments = properties.getExtraArguments();
|
||||
generatorLinux = properties.getLinuxOverrides().getGenerator();
|
||||
extraArgumentsLinux = properties.getLinuxOverrides().getExtraArguments();
|
||||
generatorWindows = properties.getWindowsOverrides().getGenerator();
|
||||
extraArgumentsWindows = properties.getWindowsOverrides().getExtraArguments();
|
||||
}
|
||||
|
||||
private boolean extraArgumentsChange(List<String> args1, List<String> args2) {
|
||||
String wanted = "CMAKE_TOOLCHAIN_FILE"; //$NON-NLS-1$
|
||||
// extract the last arguments that contain String wanted..
|
||||
Predicate<? super String> predContains = a -> a.contains(wanted);
|
||||
BinaryOperator<String> keepLast = (first, second) -> second;
|
||||
String a1 = args1.stream().filter(predContains).reduce(keepLast).orElse(null);
|
||||
String a2 = args2.stream().filter(predContains).reduce(keepLast).orElse(null);
|
||||
if (!Objects.equals(a1, a2)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ public class Messages extends NLS {
|
|||
public static String CMakeBuildConfiguration_Cleaning;
|
||||
public static String CMakeBuildConfiguration_Configuring;
|
||||
public static String CMakeBuildConfiguration_NotFound;
|
||||
public static String CMakeBuildConfiguration_NoToolchainFile;
|
||||
public static String CMakeBuildConfiguration_ProcCompCmds;
|
||||
public static String CMakeBuildConfiguration_ProcCompJson;
|
||||
public static String CMakeBuildConfiguration_Failure;
|
||||
|
|
|
@ -15,7 +15,6 @@ CMakeBuildConfiguration_BuildComplete=Build complete\n
|
|||
CMakeBuildConfiguration_Configuring=Configuring in: %s\n
|
||||
CMakeBuildConfiguration_Cleaning=Cleaning %s
|
||||
CMakeBuildConfiguration_NotFound=CMakeFiles not found. Assuming clean.
|
||||
CMakeBuildConfiguration_NoToolchainFile=No CMake toolchain file found for this target.
|
||||
CMakeBuildConfiguration_ProcCompCmds=Processing compile commands %s
|
||||
CMakeBuildConfiguration_ProcCompJson=Processing compile_commands.json
|
||||
CMakeBuildConfiguration_Failure=Failure running cmake: %s\n
|
||||
|
|
Loading…
Add table
Reference in a new issue