Skip to content

Commit ea68c6d

Browse files
committed
Bug579242: allow user to override CMake Settings
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.
1 parent 61c3568 commit ea68c6d

File tree

8 files changed

+140
-19
lines changed

8 files changed

+140
-19
lines changed

cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.cdt.cmake.core;singleton:=true
5-
Bundle-Version: 1.5.400.qualifier
5+
Bundle-Version: 1.5.500.qualifier
66
Bundle-Activator: org.eclipse.cdt.cmake.core.internal.Activator
77
Bundle-Vendor: %providerName
88
Require-Bundle: org.eclipse.core.runtime,

cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java

+56-3
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import java.nio.file.SimpleFileVisitor;
1919
import java.nio.file.attribute.BasicFileAttributes;
2020
import java.util.ArrayList;
21+
import java.util.Arrays;
2122
import java.util.HashMap;
2223
import java.util.List;
2324
import java.util.Map;
2425
import java.util.Objects;
2526
import java.util.function.Consumer;
27+
import java.util.stream.Collectors;
2628

2729
import org.eclipse.cdt.cmake.core.CMakeErrorParser;
2830
import org.eclipse.cdt.cmake.core.CMakeExecutionMarkerFactory;
@@ -66,14 +68,19 @@
6668
import org.eclipse.core.runtime.NullProgressMonitor;
6769
import org.eclipse.core.runtime.Platform;
6870
import org.eclipse.core.runtime.jobs.Job;
71+
import org.osgi.service.prefs.Preferences;
6972

7073
public class CMakeBuildConfiguration extends CBuildConfiguration {
7174

75+
public static final String CMAKE_USE_UI_OVERRIDES = "cmake.use.ui.overrides"; //$NON-NLS-1$
76+
public static final String CMAKE_USE_UI_OVERRIDES_DEFAULT = Boolean.FALSE.toString();
7277
public static final String CMAKE_GENERATOR = "cmake.generator"; //$NON-NLS-1$
7378
public static final String CMAKE_ARGUMENTS = "cmake.arguments"; //$NON-NLS-1$
7479
public static final String CMAKE_ENV = "cmake.environment"; //$NON-NLS-1$
7580
public static final String BUILD_COMMAND = "cmake.command.build"; //$NON-NLS-1$
81+
public static final String BUILD_COMMAND_DEFAULT = "cmake"; //$NON-NLS-1$
7682
public static final String CLEAN_COMMAND = "cmake.command.clean"; //$NON-NLS-1$
83+
public static final String CLEAN_COMMAND_DEFAULT = "clean"; //$NON-NLS-1$
7784

7885
private ICMakeToolChainFile toolChainFile;
7986

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

271+
/**
272+
* When UI overrides are in force, gets the user specified clean target (if not blank), otherwise the default clean target.
273+
* @return Always a non-null String indicating the clean target.
274+
*/
275+
private String getCleanCommand() {
276+
String retVal = CLEAN_COMMAND_DEFAULT;
277+
Preferences settings = this.getSettings();
278+
boolean useUiOverrides = Boolean.valueOf(settings.get(CMAKE_USE_UI_OVERRIDES, Boolean.FALSE.toString()));
279+
if (useUiOverrides) {
280+
String cleanCommand = settings.get(CLEAN_COMMAND, CLEAN_COMMAND_DEFAULT);
281+
if (!cleanCommand.isBlank()) {
282+
retVal = cleanCommand;
283+
}
284+
}
285+
return retVal;
286+
}
287+
264288
@Override
265289
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
266290
IProject project = getProject();
@@ -271,7 +295,7 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti
271295
ICMakeProperties cmakeProperties = getPropertiesController().load();
272296
CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties,
273297
new SimpleOsOverridesSelector());
274-
CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline("clean"); //$NON-NLS-1$
298+
CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(getCleanCommand());
275299
ConsoleOutputStream outStream = console.getOutputStream();
276300

277301
Path buildDir = getBuildDirectory();
@@ -547,7 +571,12 @@ public void shutdown() {
547571
}
548572
} // CMakeIndexerInfoConsumer
549573

550-
private static class SimpleOsOverridesSelector implements IOsOverridesSelector {
574+
/**
575+
* Supports OS overrides and also User Interface (UI) overrides, provided in the CMakeBuildTab. The UI
576+
* overrides are stored in the intermediary CBuildConfiguration Preferences (CBuildConfiguration.getSettings())
577+
* and used only when CMAKE_USE_UI_OVERRIDES is true.
578+
*/
579+
private class SimpleOsOverridesSelector implements IOsOverridesSelector {
551580

552581
@Override
553582
public IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) {
@@ -561,7 +590,31 @@ public IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) {
561590
// fall back to linux, if OS is unknown
562591
overrides = cmakeProperties.getLinuxOverrides();
563592
}
564-
return overrides;
593+
return getUiOrOsOverrides(overrides);
594+
}
595+
596+
private IOsOverrides getUiOrOsOverrides(IOsOverrides osOverrides) {
597+
IOsOverrides retVal = Objects.requireNonNull(osOverrides, "osOverrides must not be null"); //$NON-NLS-1$
598+
Preferences settings = getSettings();
599+
boolean useUiOverrides = Boolean.valueOf(settings.get(CMAKE_USE_UI_OVERRIDES, Boolean.FALSE.toString()));
600+
if (useUiOverrides) {
601+
// Set UI override for generator
602+
String gen = settings.get(CMAKE_GENERATOR, ""); //$NON-NLS-1$
603+
retVal.setGenerator(CMakeGenerator.getGenerator(gen));
604+
// Set UI override for Extra Arguments
605+
String extraArgsStr = settings.get(CMAKE_ARGUMENTS, ""); //$NON-NLS-1$
606+
// Convert String of args, separated by 1 or more spaces, into list of Strings
607+
List<String> extraArgs = Arrays.stream(extraArgsStr.split("\\s+")).map(entry -> entry.trim()) //$NON-NLS-1$
608+
.collect(Collectors.toList());
609+
retVal.setExtraArguments(extraArgs);
610+
// Set UI override for cmake build command, unless it's the default
611+
String buildCommand = settings.get(BUILD_COMMAND, BUILD_COMMAND_DEFAULT);
612+
if (!buildCommand.isBlank() && !BUILD_COMMAND_DEFAULT.equals(buildCommand)) {
613+
retVal.setUseDefaultCommand(false);
614+
retVal.setCommand(buildCommand);
615+
}
616+
}
617+
return retVal;
565618
}
566619
} // SimpleOsOverridesSelector
567620
}

cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CommandDescriptorBuilder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreException
5656
List<String> env = new ArrayList<>();
5757

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

112112
IOsOverrides osOverrides = overridesSelector.getOsOverrides(cmakeProperties);
113113
if (osOverrides.getUseDefaultCommand()) {
114-
args.add("cmake"); //$NON-NLS-1$
114+
args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT);
115115
} else {
116116
IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager();
117117
String cmd = varManager.performStringSubstitution(osOverrides.getCommand());

cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/AbstractOsOverrides.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.List;
1616
import java.util.Objects;
1717

18+
import org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration;
1819
import org.eclipse.cdt.cmake.core.properties.CMakeGenerator;
1920
import org.eclipse.cdt.cmake.core.properties.IOsOverrides;
2021

@@ -42,7 +43,7 @@ public AbstractOsOverrides() {
4243
* Sets each value to its default.
4344
*/
4445
public void reset() {
45-
setCommand("cmake"); //$NON-NLS-1$
46+
setCommand(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT);
4647
useDefaultCommand = true;
4748
setGenerator(CMakeGenerator.UnixMakefiles);
4849
extraArguments.clear();

cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakeGenerator.java

+12
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,16 @@ public String getMakefileName() {
8181
public String getIgnoreErrOption() {
8282
return ignoreErrOption;
8383
}
84+
85+
/**
86+
* @since 1.5
87+
*/
88+
public static CMakeGenerator getGenerator(String generatorName) {
89+
for (CMakeGenerator gen : values()) {
90+
if (gen.getCMakeName().equals(generatorName)) {
91+
return gen;
92+
}
93+
}
94+
return null;
95+
}
8496
}

cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakeBuildTab.java

+63-12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.eclipse.cdt.cmake.ui.internal;
1212

13+
import java.util.HashMap;
1314
import java.util.Map;
1415

1516
import org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration;
@@ -32,11 +33,20 @@
3233

3334
public class CMakeBuildTab extends CommonBuildTab {
3435

36+
/**
37+
* Checkbox allowing user to choose these settings over the default operating system defaults.
38+
* This is connected to the CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES preference.
39+
*/
40+
private Button useUiCmakeSettings;
3541
private Button unixGenButton;
3642
private Button ninjaGenButton;
3743
private Text cmakeArgsText;
3844
private Text buildCommandText;
3945
private Text cleanCommandText;
46+
private Label generatorLabel;
47+
private Label cmakeArgsLabel;
48+
private Label buildCommandLabel;
49+
private Label cleanCommandLabel;
4050

4151
@Override
4252
protected String getBuildConfigProviderId() {
@@ -57,8 +67,19 @@ public void createControl(Composite parent) {
5767
cmakeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
5868
cmakeGroup.setLayout(new GridLayout());
5969

60-
Label label = new Label(cmakeGroup, SWT.NONE);
61-
label.setText(Messages.CMakeBuildTab_Generator);
70+
useUiCmakeSettings = new Button(cmakeGroup, SWT.CHECK);
71+
useUiCmakeSettings.setText(Messages.CMakeBuildTab_useUICmakeSettings);
72+
useUiCmakeSettings.setToolTipText(Messages.CMakeBuildTab_useUICmakeSettingsTip);
73+
useUiCmakeSettings.addSelectionListener(new SelectionAdapter() {
74+
@Override
75+
public void widgetSelected(SelectionEvent e) {
76+
updateEnablement();
77+
updateLaunchConfigurationDialog();
78+
}
79+
});
80+
81+
generatorLabel = new Label(cmakeGroup, SWT.NONE);
82+
generatorLabel.setText(Messages.CMakeBuildTab_Generator);
6283

6384
Composite genComp = new Composite(cmakeGroup, SWT.BORDER);
6485
genComp.setLayout(new GridLayout(2, true));
@@ -81,31 +102,50 @@ public void widgetSelected(SelectionEvent e) {
81102
}
82103
});
83104

84-
label = new Label(cmakeGroup, SWT.NONE);
85-
label.setText(Messages.CMakeBuildTab_CMakeArgs);
105+
cmakeArgsLabel = new Label(cmakeGroup, SWT.NONE);
106+
cmakeArgsLabel.setText(Messages.CMakeBuildTab_CMakeArgs);
86107

87108
cmakeArgsText = new Text(cmakeGroup, SWT.BORDER);
88109
cmakeArgsText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
89110
cmakeArgsText.addModifyListener(e -> updateLaunchConfigurationDialog());
90111

91-
label = new Label(cmakeGroup, SWT.NONE);
92-
label.setText(Messages.CMakeBuildTab_BuildCommand);
112+
buildCommandLabel = new Label(cmakeGroup, SWT.NONE);
113+
buildCommandLabel.setText(Messages.CMakeBuildTab_BuildCommand);
93114

94115
buildCommandText = new Text(cmakeGroup, SWT.BORDER);
95116
buildCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
96117
buildCommandText.addModifyListener(e -> updateLaunchConfigurationDialog());
97118

98-
label = new Label(cmakeGroup, SWT.NONE);
99-
label.setText(Messages.CMakeBuildTab_CleanCommand);
119+
cleanCommandLabel = new Label(cmakeGroup, SWT.NONE);
120+
cleanCommandLabel.setText(Messages.CMakeBuildTab_CleanCommand);
100121

101122
cleanCommandText = new Text(cmakeGroup, SWT.BORDER);
102123
cleanCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
103124
cleanCommandText.addModifyListener(e -> updateLaunchConfigurationDialog());
104125
}
105126

127+
/**
128+
* Updates the enabled state of the CMake settings controls based on useUiCmakeSettings checkbox
129+
*/
130+
private void updateEnablement() {
131+
boolean isSelected = useUiCmakeSettings.getSelection();
132+
generatorLabel.setEnabled(isSelected);
133+
unixGenButton.setEnabled(isSelected);
134+
ninjaGenButton.setEnabled(isSelected);
135+
cmakeArgsLabel.setEnabled(isSelected);
136+
cmakeArgsText.setEnabled(isSelected);
137+
buildCommandLabel.setEnabled(isSelected);
138+
buildCommandText.setEnabled(isSelected);
139+
cleanCommandLabel.setEnabled(isSelected);
140+
cleanCommandText.setEnabled(isSelected);
141+
}
142+
106143
@Override
107144
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
108-
// TODO
145+
// Set defaults for Build Settings
146+
ICBuildConfiguration buildConfig = getBuildConfiguration();
147+
buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES,
148+
CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES_DEFAULT);
109149
}
110150

111151
@Override
@@ -133,10 +173,14 @@ public void initializeFrom(ILaunchConfiguration configuration) {
133173

134174
String cleanCommand = buildConfig.getProperty(CMakeBuildConfiguration.CLEAN_COMMAND);
135175
if (cleanCommand != null) {
136-
cleanCommandText.setText(buildCommand);
176+
cleanCommandText.setText(cleanCommand);
137177
} else {
138178
cleanCommandText.setText(""); //$NON-NLS-1$
139179
}
180+
181+
boolean isSelected = Boolean.valueOf(buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES));
182+
useUiCmakeSettings.setSelection(isSelected);
183+
updateEnablement();
140184
}
141185

142186
private void updateGeneratorButtons(String generator) {
@@ -153,8 +197,8 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
153197

154198
ICBuildConfiguration buildConfig = getBuildConfiguration();
155199

156-
buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_GENERATOR,
157-
ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"); //$NON-NLS-1$ //$NON-NLS-2$
200+
String gen = ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"; //$NON-NLS-1$ //$NON-NLS-2$
201+
buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_GENERATOR, gen);
158202

159203
String cmakeArgs = cmakeArgsText.getText().trim();
160204
if (!cmakeArgs.isEmpty()) {
@@ -176,6 +220,13 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
176220
} else {
177221
buildConfig.removeProperty(CMakeBuildConfiguration.CLEAN_COMMAND);
178222
}
223+
224+
boolean isSelected = useUiCmakeSettings.getSelection();
225+
buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES, Boolean.toString(isSelected));
226+
227+
Map<String, String> saved = new HashMap<>();
228+
saved.put(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES, Boolean.toString(isSelected));
229+
getBuildConfiguration().setProperties(saved);
179230
}
180231

181232
@Override

cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public class Messages extends NLS {
2424
public static String CMakeBuildTab_Settings;
2525
public static String CMakeBuildTab_Toolchain;
2626
public static String CMakeBuildTab_UnixMakefiles;
27+
public static String CMakeBuildTab_useUICmakeSettings;
28+
public static String CMakeBuildTab_useUICmakeSettingsTip;
2729
public static String CMakePreferencePage_Add;
2830
public static String CMakePreferencePage_ConfirmRemoveDesc;
2931
public static String CMakePreferencePage_ConfirmRemoveTitle;

cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ CMakeBuildTab_NoneAvailable=No Toolchains Available for this Target
88
CMakeBuildTab_Settings=CMake Settings
99
CMakeBuildTab_Toolchain=Toolchain
1010
CMakeBuildTab_UnixMakefiles=Unix Makefiles
11+
CMakeBuildTab_useUICmakeSettings=Use these settings
12+
CMakeBuildTab_useUICmakeSettingsTip=Use these settings instead of the operating system defaults
1113
CMakePreferencePage_Add=Add...
1214
CMakePreferencePage_ConfirmRemoveDesc=Do you wish to deregister the selected files?
1315
CMakePreferencePage_ConfirmRemoveTitle=Deregister CMake ToolChain File

0 commit comments

Comments
 (0)