Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug579242: allow user to override CMake Settings #683

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading