Skip to content

Commit

Permalink
Bug579242: allow user to override CMake Settings (#683)
Browse files Browse the repository at this point in the history
The Launch Bar Launch Configuration, Build Settings tab allows the user
to customise the CMake Settings (CMake generator, extra arguments, build
command and clean command). But changing these settings did not affect
the CMake build. This is now fixed.
A "Use these settings" checkbox allows the user to choose settings from
the UI or use the operating system defaults.
  • Loading branch information
betamaxbandit committed Feb 7, 2024
1 parent 1589b8b commit b7fa359
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 20 deletions.
12 changes: 12 additions & 0 deletions NewAndNoteworthy/CDT-11.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ The original locations of object files within a GNU archive are now calculated u

Managed build _Static Library_ projects using a _Cross GCC_, _Cygwin GCC_, _Linux GCC_ or _MinGW GCC_ toolchain now use the `-P` archiver flag by default to generate the necessary path information.

# CMake
The Launch Bar Launch Configuration Build Settings tab has been updated so it can now correctly control the CMake Generator setting. The "Additional CMake arguments" field can also be used to inject CMake defines into the CMakeCache.txt file to populate it with customizable settings for the project. Use the new "Use these settings" checkbox to control whether to use either the operating system defaults or settings from the UI.

When "Use these settings" checkbox is unchecked, the operating system defaults are used during the CMake build.

<p align="center"><img src="images/CDT-11.5-Build_Settings_Use_these_settings_unchecked.PNG" width="50%"></p>

When the "Use these settings" checkbox is checked, the UI settings are used during the CMake build.

<p align="center"><img src="images/CDT-11.5-Build_Settings_Use_these_settings_checked.PNG" width="50%"></p>


# API Changes, current and planned

## Breaking API changes
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,11 @@ DISPLAY=:99 mvn verify
or specify the `DISPLAY` in the Eclipse JUnit launch configuration:

![junit_env_display.png](images/junit_env_display.png "screenshot of how to set custom DISPLAY")

## Manual Testing
### CMake Build Settings tab
A set of manual tests that check it is possible to control the CMake build using the Launch Bar Launch Configuration > Build Settings tab.

[CMake Build Settings tests](./cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/Bug579242_manual_tests.md)


2 changes: 1 addition & 1 deletion cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.cmake.core;singleton:=true
Bundle-Version: 1.5.400.qualifier
Bundle-Version: 1.5.500.qualifier
Bundle-Activator: org.eclipse.cdt.cmake.core.internal.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
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;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.eclipse.cdt.cmake.core.CMakeErrorParser;
import org.eclipse.cdt.cmake.core.CMakeExecutionMarkerFactory;
Expand Down Expand Up @@ -66,14 +68,19 @@
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.osgi.service.prefs.Preferences;

public class CMakeBuildConfiguration extends CBuildConfiguration {

public static final String CMAKE_USE_UI_OVERRIDES = "cmake.use.ui.overrides"; //$NON-NLS-1$
public static final boolean CMAKE_USE_UI_OVERRIDES_DEFAULT = false;
public static final String CMAKE_GENERATOR = "cmake.generator"; //$NON-NLS-1$
public static final String CMAKE_ARGUMENTS = "cmake.arguments"; //$NON-NLS-1$
public static final String CMAKE_ENV = "cmake.environment"; //$NON-NLS-1$
public static final String BUILD_COMMAND = "cmake.command.build"; //$NON-NLS-1$
public static final String BUILD_COMMAND_DEFAULT = "cmake"; //$NON-NLS-1$
public static final String CLEAN_COMMAND = "cmake.command.clean"; //$NON-NLS-1$
public static final String CLEAN_COMMAND_DEFAULT = "clean"; //$NON-NLS-1$

private ICMakeToolChainFile toolChainFile;

Expand Down Expand Up @@ -261,6 +268,23 @@ public IProject[] build(int kind, Map<String, String> args, IConsole console, IP
}
}

/**
* When UI overrides are in force, gets the user specified clean target (if not blank), otherwise the default clean target.
* @return Always a non-null String indicating the clean target.
*/
private String getCleanCommand() {
String retVal = CLEAN_COMMAND_DEFAULT;
Preferences settings = this.getSettings();
boolean useUiOverrides = settings.getBoolean(CMAKE_USE_UI_OVERRIDES, CMAKE_USE_UI_OVERRIDES_DEFAULT);
if (useUiOverrides) {
String cleanCommand = settings.get(CLEAN_COMMAND, CLEAN_COMMAND_DEFAULT);
if (!cleanCommand.isBlank()) {
retVal = cleanCommand;
}
}
return retVal;
}

@Override
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
Expand All @@ -271,7 +295,7 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti
ICMakeProperties cmakeProperties = getPropertiesController().load();
CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties,
new SimpleOsOverridesSelector());
CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline("clean"); //$NON-NLS-1$
CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(getCleanCommand());
ConsoleOutputStream outStream = console.getOutputStream();

Path buildDir = getBuildDirectory();
Expand Down Expand Up @@ -547,7 +571,12 @@ public void shutdown() {
}
} // CMakeIndexerInfoConsumer

private static class SimpleOsOverridesSelector implements IOsOverridesSelector {
/**
* Supports OS overrides and also User Interface (UI) overrides, provided in the CMakeBuildTab. The UI
* overrides are stored in the intermediary CBuildConfiguration Preferences (CBuildConfiguration.getSettings())
* and used only when CMAKE_USE_UI_OVERRIDES is true.
*/
private class SimpleOsOverridesSelector implements IOsOverridesSelector {

@Override
public IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) {
Expand All @@ -561,7 +590,31 @@ public IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) {
// fall back to linux, if OS is unknown
overrides = cmakeProperties.getLinuxOverrides();
}
return overrides;
return getUiOrOsOverrides(overrides);
}

private IOsOverrides getUiOrOsOverrides(IOsOverrides osOverrides) {
IOsOverrides retVal = Objects.requireNonNull(osOverrides, "osOverrides must not be null"); //$NON-NLS-1$
Preferences settings = getSettings();
boolean useUiOverrides = settings.getBoolean(CMAKE_USE_UI_OVERRIDES, CMAKE_USE_UI_OVERRIDES_DEFAULT);
if (useUiOverrides) {
// Set UI override for generator
String gen = settings.get(CMAKE_GENERATOR, ""); //$NON-NLS-1$
retVal.setGenerator(CMakeGenerator.getGenerator(gen));
// Set UI override for Extra Arguments
String extraArgsStr = settings.get(CMAKE_ARGUMENTS, ""); //$NON-NLS-1$
// Convert String of args, separated by 1 or more spaces, into list of Strings
List<String> extraArgs = Arrays.stream(extraArgsStr.split("\\s+")).map(entry -> entry.trim()) //$NON-NLS-1$
.collect(Collectors.toList());
retVal.setExtraArguments(extraArgs);
// Set UI override for cmake build command, unless it's the default
String buildCommand = settings.get(BUILD_COMMAND, BUILD_COMMAND_DEFAULT);
if (!buildCommand.isBlank() && !BUILD_COMMAND_DEFAULT.equals(buildCommand)) {
retVal.setUseDefaultCommand(false);
retVal.setCommand(buildCommand);
}
}
return retVal;
}
} // SimpleOsOverridesSelector
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreException
List<String> env = new ArrayList<>();

// defaults for all OSes...
args.add("cmake"); //$NON-NLS-1$
args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT);
/* add general settings */
if (cmakeProperties.isWarnNoDev())
args.add("-Wno-dev"); //$NON-NLS-1$
Expand Down Expand Up @@ -111,7 +111,7 @@ CommandDescriptor makeCMakeBuildCommandline(String buildscriptTarget) throws Cor

IOsOverrides osOverrides = overridesSelector.getOsOverrides(cmakeProperties);
if (osOverrides.getUseDefaultCommand()) {
args.add("cmake"); //$NON-NLS-1$
args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT);
} else {
IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager();
String cmd = varManager.performStringSubstitution(osOverrides.getCommand());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import java.util.Objects;

import org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration;
import org.eclipse.cdt.cmake.core.properties.CMakeGenerator;
import org.eclipse.cdt.cmake.core.properties.IOsOverrides;

Expand Down Expand Up @@ -42,7 +43,7 @@ public AbstractOsOverrides() {
* Sets each value to its default.
*/
public void reset() {
setCommand("cmake"); //$NON-NLS-1$
setCommand(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT);
useDefaultCommand = true;
setGenerator(CMakeGenerator.UnixMakefiles);
extraArguments.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,16 @@ public String getMakefileName() {
public String getIgnoreErrOption() {
return ignoreErrOption;
}

/**
* @since 1.5
*/
public static CMakeGenerator getGenerator(String generatorName) {
for (CMakeGenerator gen : values()) {
if (gen.getCMakeName().equals(generatorName)) {
return gen;
}
}
return null;
}
}
Loading

0 comments on commit b7fa359

Please sign in to comment.