From 50cd03ad8416604b500f0fb7d4dbd00c80ba5e06 Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Fri, 24 Jan 2025 09:25:23 -0500 Subject: [PATCH] Refactor CMake build settings Add support for all generators to CMake build settings Correct command line option for CMake's --warn-unused-vars Rename clean command to clean target to better reflect its use as the argument passed to cmake's --target command line. Add all target for the argument passed to cmake's --target command line when doing a normal build. Clarify usage of UI overrides and change the UI to be "use defaults" (i.e. invert the checkbox). This is a **breaking** change as it means user projects that were using UI overrides will revert to using defaults. This is done on purpose as so many little things have changed in CMake settings, that reverting to defaults on upgrade seems like a logical decision. In addition *use defaults* matches the other GUIs in Eclipse, for example the MBS build command settings. Populate all default in getDefaultProperties() so that all CMake build settings are displayed as used (greyed out) and can be used as a starting point when editing settings. Simplify some of the code in CMakeBuildTab, especially: - removing the duplicated code between initializeFrom and restoreProperties - use Map's getOrDefault instead of a get, followed by a null check. Remove getUseDefaultCommand/setUseDefaultCommand as they don't appear in the GUI and it makes it impossible for the GUI command to be used. It is also redundant as use ui overrides is a global use default for all settings, so having a second use default seems unneeded at this point. Cleanup and simplify getCMakeProperties. Fix parsing of extra args so that quoted strings work. Remove doubled-up extra args added to command line. Refactored manual tests document and brought it up to date. Fixes #1055 Part of #1000 --- NewAndNoteworthy/CDT-12.0.md | 10 +- NewAndNoteworthy/CHANGELOG-API.md | 1 + .../core/CMakeBuildConfigurationTests.java | 161 ++++++++++++- .../cmake/core/CMakeBuildConfiguration.java | 133 +++++++---- .../internal/CommandDescriptorBuilder.java | 30 +-- .../properties/CMakePropertiesBean.java | 46 ++-- .../cmake/core/properties/CMakeGenerator.java | 5 +- .../core/properties/ICMakeGenerator.java | 47 ++++ .../core/properties/ICMakeProperties.java | 48 ++-- .../ExtendedCMakeBuildConfiguration.java | 2 +- .../manualTests/README.md | 85 +++++++ ...42_manual_tests.md => testrun-20240129.md} | 83 +------ .../cdt/cmake/ui/internal/CMakeBuildTab.java | 220 ++++++++---------- .../cdt/cmake/ui/internal/Messages.java | 9 +- .../cdt/cmake/ui/internal/messages.properties | 9 +- 15 files changed, 570 insertions(+), 319 deletions(-) create mode 100644 cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeGenerator.java create mode 100644 cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md rename cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/{Bug579242_manual_tests.md => testrun-20240129.md} (75%) diff --git a/NewAndNoteworthy/CDT-12.0.md b/NewAndNoteworthy/CDT-12.0.md index dfd79c48775..683095e47ff 100644 --- a/NewAndNoteworthy/CDT-12.0.md +++ b/NewAndNoteworthy/CDT-12.0.md @@ -14,13 +14,19 @@ CDT's native components will likely work with older versions of glibc too, assum # Core Build +## More CMake build settings are now available in the user interface + +The CMake build setting GUI has been updated to include more CMake settings, and some of the settings that did not used to do the correct thing have been updated for more consistent behavior. +The way these settings are saved has been slightly modified, meaning workspaces with CMake projects from before CDT 12 will have their build settings restored to defaults. +Build settings can be customized by unchecking "Use default CMake settings". + +TODO: Before release add the final screenshot for the build settings here. I am not including it now because the UI keeps changing. + ## Default build system generator for CMake changed to Ninja on all platforms The default for CMake's build system generator is now Ninja on all platforms. Users who want to use other build system generators can select their desired generator in the build settings. -TODO: Before release add the final screenshot for the build settings here. I am not including it now because the UI keeps changing. - # Managed Build ## New *C Project* and new *C++ Project* available via *New C/C++ Project* wizard diff --git a/NewAndNoteworthy/CHANGELOG-API.md b/NewAndNoteworthy/CHANGELOG-API.md index 574f4cf7244..0a520f8d9f0 100644 --- a/NewAndNoteworthy/CHANGELOG-API.md +++ b/NewAndNoteworthy/CHANGELOG-API.md @@ -22,6 +22,7 @@ The following classes have been removed or modified in API breaking ways: - new methods added to compensate for removal of IOsOverrides - reset method removed - spelling corrected for methods with Uninitialized in the name + - setWarnUnused renamed to setWarnUnusedVars and isWarnUnused renamed to isWarnUnusedVars ## API Changes in CDT 11.5. diff --git a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationTests.java b/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationTests.java index 8a80607b619..7c949fb82e2 100644 --- a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationTests.java +++ b/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationTests.java @@ -13,6 +13,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -22,12 +23,14 @@ import java.util.Map; import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; +import org.eclipse.cdt.cmake.core.properties.ICMakeGenerator; import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase5; +import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; @@ -118,7 +121,6 @@ public void getDefaultProperties() throws Exception { public Map getDefaultProperties() { var defs = new HashMap<>(super.getDefaultProperties()); defs.put(CMAKE_GENERATOR, CMakeGenerator.WatcomWMake.getCMakeName()); - defs.put(CMAKE_USE_UI_OVERRIDES, "true"); return defs; } }; @@ -127,6 +129,163 @@ public Map getDefaultProperties() { assertThat(cMakeProperties.getGenerator(), is(CMakeGenerator.WatcomWMake)); } + @Test + public void getDefaultPropertiesTestExtraArgs() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + @Override + public Map getDefaultProperties() { + var defs = new HashMap<>(super.getDefaultProperties()); + defs.put(CMAKE_ARGUMENTS, "-Dtest0=0 -Dtest1=1"); + return defs; + } + }; + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + List extraArguments = cMakeProperties.getExtraArguments(); + assertThat(extraArguments, contains("-Dtest0=0", "-Dtest1=1")); + } + + /** + * Test that a custom cmake generator can be entered and auto-created + */ + @Test + public void customCMakeGeneratorEntryAuto() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + @Override + public Map getDefaultProperties() { + var defs = new HashMap<>(super.getDefaultProperties()); + // A custom generator for a custom cmake version + defs.put(CMAKE_GENERATOR, "My Personal Generator"); + return defs; + } + }; + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getGenerator().getCMakeName(), is("My Personal Generator")); + assertThat(cMakeProperties.getGenerator().getIgnoreErrOption(), is(nullValue())); + assertThat(cMakeProperties.getGenerator().getMakefileName(), is(nullValue())); + } + + /** + * Test that a custom cmake generator can be entered and manually-created + */ + @Test + public void customCMakeGeneratorEntryManual() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + @Override + public Map getDefaultProperties() { + var defs = new HashMap<>(super.getDefaultProperties()); + // A custom generator for a custom cmake version + defs.put(CMAKE_GENERATOR, "My Personal Generator"); + return defs; + } + + @Override + public ICMakeProperties getCMakeProperties() { + ICMakeProperties properties = super.getCMakeProperties(); + if ("My Personal Generator".equals(properties.getGenerator().getCMakeName())) { + var generator = new ICMakeGenerator() { + @Override + public String getMakefileName() { + return "MyMak.mak"; + } + + @Override + public String getIgnoreErrOption() { + return "-mycustom"; + } + + @Override + public String getCMakeName() { + return "My Personal Generator"; + } + }; + properties.setGenerator(generator); + } + return properties; + } + }; + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getGenerator().getCMakeName(), is("My Personal Generator")); + assertThat(cMakeProperties.getGenerator().getIgnoreErrOption(), is("-mycustom")); + assertThat(cMakeProperties.getGenerator().getMakefileName(), is("MyMak.mak")); + } + + /** + * Test all and clean targets and cmake command have working defaults + */ + @Test + public void targetsAndCommandDefaults() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain); + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getCommand(), is("cmake")); + assertThat(cMakeProperties.getAllTarget(), is("all")); + assertThat(cMakeProperties.getCleanTarget(), is("clean")); + } + + /** + * Test all and clean targets and cmake command can be overridden + */ + @Test + public void targetsAndCommand() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + @Override + public Map getDefaultProperties() { + var defs = new HashMap<>(super.getDefaultProperties()); + defs.put(CMAKE_BUILD_COMMAND, "mycmake"); + defs.put(CMAKE_ALL_TARGET, "myall"); + defs.put(CMAKE_CLEAN_TARGET, "myclean"); + return defs; + } + }; + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getCommand(), is("mycmake")); + assertThat(cMakeProperties.getAllTarget(), is("myall")); + assertThat(cMakeProperties.getCleanTarget(), is("myclean")); + } + + /** + * Test that extra arguments parse correctly, e.g. handles ". + * + * Note that this test is minimal here as the real functionality is in {@link CommandLineUtil} + * and all the special cases are tested in CommandLineUtilTest. + */ + @Test + public void extraArgumentsParseCorrectly() throws Exception { + // Create a C Build Configuration using the default build config and an arbitrary name + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + @Override + public Map getDefaultProperties() { + var defs = new HashMap<>(super.getDefaultProperties()); + defs.put(CMAKE_ARGUMENTS, "-Da=\"something with space and quotes\" \"-Danother=quoted\""); + return defs; + } + }; + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getExtraArguments(), + is(List.of("-Da=something with space and quotes", "-Danother=quoted"))); + } + private IProject createCMakeProject() throws Exception { // Create a plain Eclipse project IProject project = ResourceHelper.createProject(this.getName()); diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfiguration.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfiguration.java index 224b490f936..e0d08057b57 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfiguration.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfiguration.java @@ -21,7 +21,6 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import java.util.stream.Collectors; import org.eclipse.cdt.cmake.core.internal.Activator; import org.eclipse.cdt.cmake.core.internal.CMakeConsoleWrapper; @@ -30,6 +29,7 @@ import org.eclipse.cdt.cmake.core.internal.CommandDescriptorBuilder.CommandDescriptor; import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; import org.eclipse.cdt.cmake.core.properties.CMakePropertiesFactory; +import org.eclipse.cdt.cmake.core.properties.ICMakeGenerator; import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; import org.eclipse.cdt.core.CommandLauncherManager; import org.eclipse.cdt.core.ConsoleOutputStream; @@ -50,6 +50,7 @@ import org.eclipse.cdt.jsoncdb.core.CompileCommandsJsonParser; import org.eclipse.cdt.jsoncdb.core.ISourceFileInfoConsumer; import org.eclipse.cdt.jsoncdb.core.ParseRequest; +import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -63,23 +64,25 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.ILaunchManager; -import org.osgi.service.prefs.Preferences; /** * @since 2.0 */ public class CMakeBuildConfiguration extends CBuildConfiguration implements ICMakeBuildConfiguration { - 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_USE_DEFAULT_CMAKE_SETTINGS = "cmake.use.default.cmake.settings"; //$NON-NLS-1$ + public static final boolean CMAKE_USE_DEFAULT_CMAKE_SETTINGS_DEFAULT = true; public static final String CMAKE_GENERATOR = "cmake.generator"; //$NON-NLS-1$ public static final String CMAKE_GENERATOR_DEFAULT = "Ninja"; //$NON-NLS-1$ public static final String CMAKE_ARGUMENTS = "cmake.arguments"; //$NON-NLS-1$ + public static final String CMAKE_ARGUMENTS_DEFAULT = ""; //$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$ + public static final String CMAKE_BUILD_COMMAND = "cmake.command.build"; //$NON-NLS-1$ + public static final String CMAKE_BUILD_COMMAND_DEFAULT = "cmake"; //$NON-NLS-1$ + public static final String CMAKE_ALL_TARGET = "cmake.target.all"; //$NON-NLS-1$ + public static final String CMAKE_ALL_TARGET_DEFAULT = "all"; //$NON-NLS-1$ + public static final String CMAKE_CLEAN_TARGET = "cmake.target.clean"; //$NON-NLS-1$ + public static final String CMAKE_CLEAN_TARGET_DEFAULT = "clean"; //$NON-NLS-1$ private ICMakeToolChainFile toolChainFile; @@ -115,27 +118,66 @@ public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolCha @Override public ICMakeProperties getCMakeProperties() { // Create CMake default properties - ICMakeProperties properties = CMakePropertiesFactory.createProperties(); - - String useUiOverrides = getProperty(CMAKE_USE_UI_OVERRIDES); - if (Boolean.parseBoolean(useUiOverrides)) { - // UI overrides are enabled so UI overridden values take precedence if not null, otherwise use CMake default - // CMAKE_GENERATOR - String cmakeGeneratorUiValue = getProperty(CMakeBuildConfiguration.CMAKE_GENERATOR); - if (cmakeGeneratorUiValue != null) { - CMakeGenerator generator = CMakeGenerator.getGenerator(cmakeGeneratorUiValue); - if (generator != null) { - properties.setGenerator(generator); - } + ICMakeProperties cmakeProperties = CMakePropertiesFactory.createProperties(); + + String useDefaultCMakeSettings = getProperty(CMAKE_USE_DEFAULT_CMAKE_SETTINGS); + final Map properties; + if (Boolean.parseBoolean(useDefaultCMakeSettings)) { + properties = getDefaultProperties(); + } else { + properties = getProperties(); + } + // UI overrides are enabled so UI overridden values take precedence if not null, otherwise use CMake default + // CMAKE_GENERATOR + String cmakeGeneratorUiValue = properties.get(CMakeBuildConfiguration.CMAKE_GENERATOR); + if (cmakeGeneratorUiValue != null) { + CMakeGenerator generator = CMakeGenerator.getGenerator(cmakeGeneratorUiValue); + if (generator == null) { + cmakeProperties.setGenerator(new ICMakeGenerator() { + + @Override + public String getMakefileName() { + return null; + } + + @Override + public String getIgnoreErrOption() { + return null; + } + + @Override + public String getCMakeName() { + return cmakeGeneratorUiValue; + } + }); + } else { + cmakeProperties.setGenerator(generator); } - // CMAKE_ARGUMENTS - String extraArgsUiValue = getProperty(CMAKE_ARGUMENTS); - // TODO this split is insufficient as it does not handle escaping, quoted strings and whitespace correctly - List extraArgsList = Arrays.stream(extraArgsUiValue.split("\\s+")).map(entry -> entry.trim()) //$NON-NLS-1$ - .collect(Collectors.toList()); - properties.setExtraArguments(extraArgsList); } - return properties; + // CMAKE_ARGUMENTS + String extraArgsUiValue = properties.get(CMAKE_ARGUMENTS); + List extraArgsList = Arrays.asList(CommandLineUtil.argumentsToArray(extraArgsUiValue)); + cmakeProperties.setExtraArguments(extraArgsList); + + // BUILD_COMMAND + String buildCommandUiValue = properties.get(CMAKE_BUILD_COMMAND); + if (buildCommandUiValue != null && !buildCommandUiValue.isBlank()) { + cmakeProperties.setCommand(buildCommandUiValue); + } + + // CLEAN_TARGET + String cleanTarget = properties.get(CMAKE_CLEAN_TARGET); + if (cleanTarget != null && !cleanTarget.isBlank()) { + cmakeProperties.setCleanTarget(cleanTarget); + } + + // ALL_TARGET + String allTarget = properties.get(CMAKE_ALL_TARGET); + if (allTarget != null && !allTarget.isBlank()) { + cmakeProperties.setAllTarget(allTarget); + } + + return cmakeProperties; } /** @@ -182,8 +224,13 @@ public IProject[] build(int kind, Map args, IConsole console, IP } if (!runCMake) { - CMakeGenerator generator = cmakeProperties.getGenerator(); - runCMake |= !Files.exists(buildDir.resolve(generator.getMakefileName())); + ICMakeGenerator generator = cmakeProperties.getGenerator(); + String makefileName = generator.getMakefileName(); + if (makefileName == null) { + runCMake = true; + } else { + runCMake |= !Files.exists(buildDir.resolve(makefileName)); + } } CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties); if (runCMake) { @@ -251,7 +298,7 @@ public IProject[] build(int kind, Map args, IConsole console, IP } } - CommandDescriptor commandDescr = cmdBuilder.makeCMakeBuildCommandline("all"); //$NON-NLS-1$ + CommandDescriptor commandDescr = cmdBuilder.makeCMakeBuildCommandline(cmakeProperties.getAllTarget()); List command = commandDescr.getArguments(); infoStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ @@ -287,23 +334,6 @@ public IProject[] build(int kind, Map 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(); @@ -313,7 +343,7 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti ICMakeProperties cmakeProperties = getCMakeProperties(); CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties); - CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(getCleanCommand()); + CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(cmakeProperties.getCleanTarget()); ConsoleOutputStream outStream = console.getOutputStream(); Path buildDir = getBuildDirectory(); @@ -545,8 +575,11 @@ public void shutdown() { public Map getDefaultProperties() { return Map.of(// CMAKE_GENERATOR, CMAKE_GENERATOR_DEFAULT, // - CMAKE_USE_UI_OVERRIDES, Boolean.toString(CMAKE_USE_UI_OVERRIDES_DEFAULT), // - CMAKE_ARGUMENTS, "" // //$NON-NLS-1$ + CMAKE_USE_DEFAULT_CMAKE_SETTINGS, Boolean.toString(CMAKE_USE_DEFAULT_CMAKE_SETTINGS_DEFAULT), // + CMAKE_ARGUMENTS, CMAKE_ARGUMENTS_DEFAULT, // + CMAKE_BUILD_COMMAND, CMAKE_BUILD_COMMAND_DEFAULT, // + CMAKE_ALL_TARGET, CMAKE_ALL_TARGET_DEFAULT, // + CMAKE_CLEAN_TARGET, CMAKE_CLEAN_TARGET_DEFAULT // ); } diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CommandDescriptorBuilder.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CommandDescriptorBuilder.java index 159d26d24c4..4f501f16723 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CommandDescriptorBuilder.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CommandDescriptorBuilder.java @@ -16,8 +16,7 @@ import java.util.List; import java.util.Objects; -import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; +import org.eclipse.cdt.cmake.core.properties.ICMakeGenerator; import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.variables.IStringVariableManager; @@ -53,13 +52,9 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc List args = new ArrayList<>(); List env = new ArrayList<>(); - // replace cmake command, if given - if (cmakeProperties.getUseDefaultCommand()) { - args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); - } else { - IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); - args.add(varManager.performStringSubstitution(cmakeProperties.getCommand())); - } + // cmake command + IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); + args.add(varManager.performStringSubstitution(cmakeProperties.getCommand())); /* add general settings */ if (cmakeProperties.isWarnNoDev()) @@ -72,8 +67,8 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc args.add("--trace"); //$NON-NLS-1$ if (cmakeProperties.isWarnUninitialized()) args.add("--warn-uninitialized"); //$NON-NLS-1$ - if (cmakeProperties.isWarnUnused()) - args.add("--warn-unused"); //$NON-NLS-1$ + if (cmakeProperties.isWarnUnusedVars()) + args.add("--warn-unused-vars"); //$NON-NLS-1$ { String file = cmakeProperties.getCacheFile(); if (!(file == null || file.isBlank())) { @@ -98,9 +93,8 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc } args.add("-G"); //$NON-NLS-1$ - final CMakeGenerator generator = cmakeProperties.getGenerator(); + final ICMakeGenerator generator = cmakeProperties.getGenerator(); args.add(generator.getCMakeName()); - appendCMakeArguments(args, cmakeProperties.getExtraArguments()); return new CommandDescriptor(args, env); } @@ -116,13 +110,9 @@ public CommandDescriptor makeCMakeBuildCommandline(String buildscriptTarget) thr List args = new ArrayList<>(); List env = new ArrayList<>(); - if (cmakeProperties.getUseDefaultCommand()) { - args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); - } else { - IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); - String cmd = varManager.performStringSubstitution(cmakeProperties.getCommand()); - args.add(cmd); - } + IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); + String cmd = varManager.performStringSubstitution(cmakeProperties.getCommand()); + args.add(cmd); args.add("--build"); //$NON-NLS-1$ args.add("."); //$NON-NLS-1$ args.add("--target"); //$NON-NLS-1$ diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/CMakePropertiesBean.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/CMakePropertiesBean.java index 850d3f21852..aa8d448a50b 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/CMakePropertiesBean.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/CMakePropertiesBean.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; +import org.eclipse.cdt.cmake.core.properties.ICMakeGenerator; import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; /** @@ -26,15 +27,16 @@ */ public class CMakePropertiesBean implements ICMakeProperties { - private String command = CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT; - private boolean useDefaultCommand = true; - private CMakeGenerator generator = CMakeGenerator.getGenerator(CMakeBuildConfiguration.CMAKE_GENERATOR_DEFAULT); + private String command = CMakeBuildConfiguration.CMAKE_BUILD_COMMAND_DEFAULT; + private ICMakeGenerator generator = CMakeGenerator.getGenerator(CMakeBuildConfiguration.CMAKE_GENERATOR_DEFAULT); private boolean warnNoDev = false, debugTryCompile = false, debugOutput = false, trace = false, warnUninitialized = false, warnUnused = false; private String cacheFile = ""; //$NON-NLS-1$ private boolean clearCache = false; private List extraArguments = new ArrayList<>(0); private String buildType; + private String allTarget = CMakeBuildConfiguration.CMAKE_ALL_TARGET_DEFAULT; + private String cleanTarget = CMakeBuildConfiguration.CMAKE_CLEAN_TARGET_DEFAULT; /** * Creates a new object, initialized with all default values. @@ -42,16 +44,6 @@ public class CMakePropertiesBean implements ICMakeProperties { public CMakePropertiesBean() { } - @Override - public final boolean getUseDefaultCommand() { - return useDefaultCommand; - } - - @Override - public void setUseDefaultCommand(boolean useDefaultCommand) { - this.useDefaultCommand = useDefaultCommand; - } - @Override public final String getCommand() { return command; @@ -63,12 +55,12 @@ public void setCommand(String command) { } @Override - public final CMakeGenerator getGenerator() { + public final ICMakeGenerator getGenerator() { return generator; } @Override - public void setGenerator(CMakeGenerator generator) { + public void setGenerator(ICMakeGenerator generator) { this.generator = Objects.requireNonNull(generator, "generator"); //$NON-NLS-1$ } @@ -123,12 +115,12 @@ public void setWarnUninitialized(boolean warnUninitialized) { } @Override - public boolean isWarnUnused() { + public boolean isWarnUnusedVars() { return warnUnused; } @Override - public void setWarnUnused(boolean warnUnused) { + public void setWarnUnusedVars(boolean warnUnused) { this.warnUnused = warnUnused; } @@ -171,4 +163,24 @@ public boolean isClearCache() { public void setClearCache(boolean clearCache) { this.clearCache = clearCache; } + + @Override + public String getCleanTarget() { + return cleanTarget; + } + + @Override + public void setCleanTarget(String cleanTarget) { + this.cleanTarget = cleanTarget; + } + + @Override + public String getAllTarget() { + return allTarget; + } + + @Override + public void setAllTarget(String allTarget) { + this.allTarget = allTarget; + } } diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakeGenerator.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakeGenerator.java index 4ff5a2296c4..c5496835451 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakeGenerator.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakeGenerator.java @@ -18,7 +18,7 @@ * @author Martin Weber * @since 1.4 */ -public enum CMakeGenerator { +public enum CMakeGenerator implements ICMakeGenerator { /* * Implementation Note: Please do not include generators for IDE project files, * such as "Eclipse CDT4 - Unix Makefiles". @@ -59,6 +59,7 @@ private CMakeGenerator(String name) { * @return a non-empty string, which must be a valid argument for cmake's -G * option. */ + @Override public String getCMakeName() { return name; } @@ -69,6 +70,7 @@ public String getCMakeName() { * * @return name of the makefile. */ + @Override public String getMakefileName() { return "Makefile"; //$NON-NLS-1$ } @@ -78,6 +80,7 @@ public String getMakefileName() { * * @return the command option string or {@code null} if no argument is needed. */ + @Override public String getIgnoreErrOption() { return ignoreErrOption; } diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeGenerator.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeGenerator.java new file mode 100644 index 00000000000..0def9e35447 --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeGenerator.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2020, 2025 Martin Weber and others. + * + * 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.properties; + +import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; + +/** + * This class can be implemented by extenders who want to contribute a fully custom + * CMakeGenerator configuration when generating {@link ICMakeProperties} in + * {@link CMakeBuildConfiguration#getCMakeProperties()}; + * + * @since 2.0 + */ +public interface ICMakeGenerator { + + /** + * Gets the cmake argument that specifies the build-script generator. + * + * @return a non-empty string, which must be a valid argument for cmake's -G + * option. + */ + String getCMakeName(); + + /** + * Gets the name of the top-level makefile (build-script) which is interpreted + * by the build-script processor. + * + * @return name of the makefile, or {@code null} for CDT to always run CMake. + */ + String getMakefileName(); + + /** + * Gets the build-script processorĀ“s command argument(s) to ignore build errors. + * + * @return the command option string or {@code null} if no argument is needed. + */ + String getIgnoreErrOption(); + +} diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeProperties.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeProperties.java index bd33f7b5ea9..db5bfff370d 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeProperties.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakeProperties.java @@ -23,19 +23,6 @@ * @since 1.4 */ public interface ICMakeProperties { - - /** - * Gets whether to use the default cmake command. - * @since 2.0 - */ - boolean getUseDefaultCommand(); - - /** - * Sets whether to use the default cmake command. - * @since 2.0 - */ - void setUseDefaultCommand(boolean useDefaultCommand); - /** * Gets the cmake command. Has no effect if {@link #getUseDefaultCommand()} returns false. * @since 2.0 @@ -52,13 +39,13 @@ public interface ICMakeProperties { * Gets the cmake buildscript generator. * @since 2.0 */ - CMakeGenerator getGenerator(); + ICMakeGenerator getGenerator(); /** * Sets the cmake build-script generator. * @since 2.0 */ - void setGenerator(CMakeGenerator generator); + void setGenerator(ICMakeGenerator generator); /** * {@code -Wno-dev} @@ -114,13 +101,15 @@ public interface ICMakeProperties { /** * {@code --warn-unused-vars} + * @since 2.0 */ - boolean isWarnUnused(); + boolean isWarnUnusedVars(); /** * {@code --warn-unused-vars} + * @since 2.0 */ - void setWarnUnused(boolean warnUnused); + void setWarnUnusedVars(boolean warnUnused); /** Gets the build type ({@code Debug}, {@code Release}, ...). The returned value is passed to cmake * as the {@code CMAKE_BUILD_TYPE} symbol on the command-line. @@ -177,4 +166,29 @@ public interface ICMakeProperties { /** Sets whether to clear the cmake-cache before build. */ void setClearCache(boolean clearCache); + + /** + * The target to pass to {@code --target} CMake command line option, used when user asks to clean a project. + * @since 2.0 + */ + String getCleanTarget(); + + /** + * @param cleanTarget The target to pass to {@code --target} CMake command line option, used when user asks to clean a project. + * @since 2.0 + */ + void setCleanTarget(String cleanTarget); + + /** + * The target to pass to {@code --target} CMake command line option, used when user asks to build a project. + * @since 2.0 + */ + String getAllTarget(); + + /** + * @param allTarget The target to pass to {@code --target} CMake command line option, used when user asks to build a project. + * @since 2.0 + */ + void setAllTarget(String allTarget); + } \ No newline at end of file diff --git a/cmake/org.eclipse.cdt.cmake.example/src/org/eclipse/cdt/cmake/example/ExtendedCMakeBuildConfiguration.java b/cmake/org.eclipse.cdt.cmake.example/src/org/eclipse/cdt/cmake/example/ExtendedCMakeBuildConfiguration.java index 5fa4c36dfc4..fccef89ddf7 100644 --- a/cmake/org.eclipse.cdt.cmake.example/src/org/eclipse/cdt/cmake/example/ExtendedCMakeBuildConfiguration.java +++ b/cmake/org.eclipse.cdt.cmake.example/src/org/eclipse/cdt/cmake/example/ExtendedCMakeBuildConfiguration.java @@ -42,10 +42,10 @@ public ExtendedCMakeBuildConfiguration(IBuildConfiguration config, String name, public Map getDefaultProperties() { /* * Here we demonstrate how an ISV can provide a different default generator. + * More examples can be found in CMakeBuildConfigurationTests */ var defs = new HashMap<>(super.getDefaultProperties()); defs.put(CMAKE_GENERATOR, CMakeGenerator.UnixMakefiles.getCMakeName()); - defs.put(CMAKE_USE_UI_OVERRIDES, "true"); //$NON-NLS-1$ return defs; } } diff --git a/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md b/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md new file mode 100644 index 00000000000..4409208f1be --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md @@ -0,0 +1,85 @@ +## Overview + +This document captures the manual tests that should be completed on the +CMake setting. + +## Test cases +The following test cases use a Launch Target set to Local. + +### 1) Operating system defaults used +#### 1.1) Launch Bar Launch Mode=Run, CMake Settings > "Use default CMake settings"=checked + Expected: Build uses default generator (Ninja) +#### 1.2) Launch Bar Launch Mode=Debug, CMake Settings > "Use default CMake settings"=checked + Expected: Build uses default generator (Ninja) + +### 2) Build Settings specific generator used: +Note, the Build Settings tab settings are stored separately for Run mode and Debug mode. +#### 2.1) Launch Bar Launch Mode=Run, CMake Settings > "Use default CMake settings"=unchecked, Generator=Unix Makefiles + Expected: Build uses generator Unix Makefiles +#### 2.2) Launch Bar Launch Mode=Debug, CMake Settings > "Use default CMake settings"=unchecked, Generator=Unix Makefiles + Expected: Build uses generator Unix Makefiles +#### 2.3) Build Settings are remembered +#### 2.4) Build Settings for Run mode can be different to settings stored for Debug + +### 3) Build Settings specific Additional CMake arguments: +#### 3.1) CMake Settings > "Use default CMake settings"=unchecked, Additional CMake arguments are used during build +#### 3.2) CMake Settings > "Use default CMake settings"=checked, Additional CMake arguments are NOT used during build and text box is blank + +### 4) Build Settings specific Build command: +#### 4.1) Enter a custom build command, such as the full path to cmake, and run build + Expected: the custom cmake command is used + +### 5) Build Settings specific all target: +#### 5.1) Enter a custom all target, such as `helloworld`, and run build + Expected: the custom target is used in the cmake command line + +### 6) Build Settings specific all target: +#### 6.1) Enter a custom clean target, such as `help`, and clean project + Expected: the custom target is used in the cmake command line + +### 8) Restart Eclipse +#### 8.1) Perform build, clean and open build settings + Expected: Settings are persisted + +## Setup & prerequisites +### Setup Host + Note, these instructions do not require the following tools to be added to the system path environment variable in the OS before starting Eclipse. This allows a clean environment to be maintained. + +- Install Eclipse/CDT on host. +- Install gcc toolchain and make tools on host. + - On Windows I used msys64 (https://www.msys2.org/), which contains mingw64. +- Install CMake and Ninja on host. + +### In Eclipse, setup tool paths. + +#### Toolchain + When using a recognised gcc toolchain (mingw64 is one of these), CDT automatically registers the toolchain for use within the workbench. + * To check if the toolchain is registered, open Preferences > C/C++ > Core Build Toolchains. In the Available Toolchains list, check if it contains the toolchain you installed on the host. + +For example, when using mingw64 the following toolchain is available: + + Type Name OS Arch + GCC win32 x86_64 C:\msys64\mingw64\bin\gcc.exe win32 x86_64 +Otherwise, register your toolchain by clicking Add... in the User Defined Toolchains list. + +#### CMake & Ninja +* Open Preferences > C/C++ > Build > Environment and click Add... + + In Name enter "PATH" and in Value enter the path to CMake and Ninja, for example + + `C:\Program Files\CMake\bin;C:\Ninja\bin` + + + You probably want to make sure "Append variables to native environment" (default) is selected. + +#### Create a CMake project +* In Eclipse, choose File > C/C++ Project. +* In the New C/C++ Project wizard, choose CMake in the left hand side sash and then CMake Project and click Next. +* Enter a project name, for example helloworld and click Finish. +* In the Project Explorer, expand the generated project. It contains 3 files : + + helloworld.cpp + + CMakeLists.txt + + config.h.in diff --git a/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/Bug579242_manual_tests.md b/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/testrun-20240129.md similarity index 75% rename from cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/Bug579242_manual_tests.md rename to cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/testrun-20240129.md index 26d5ad05b51..57dfd97e300 100644 --- a/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/Bug579242_manual_tests.md +++ b/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/testrun-20240129.md @@ -1,83 +1,8 @@ -Bug 579242 - Ninja generator not connected - -## Overview -Tests that it is possible to control the CMake build using the Launch Bar Launch Configuration > Build Settings tab. -The Build Settings page allows the user to control: - - * "Use these settings" checkbox allows user to use these settings instead of operating system defaults. - * Generator "Unix Makefiles" or "Ninja" radio group allows choice of CMake generator. - * "Additional CMake arguments" allows variable=value arguments to be passed to CMake CACHE entry to customise settings for the project. - -## Test cases -The following test cases use a Launch Target set to Local. - -### 1) Operating system defaults used -#### 1.1) Launch Bar Launch Mode=Run, CMake Settings > "Use these settings"=unchecked - Expected: Build uses default generator (win32: -G MinGW Makefiles) -#### 1.2) Launch Bar Launch Mode=Debug, CMake Settings > "Use these settings"=unchecked - Expected: Build uses default generator (win32: -G MinGW Makefiles) - -### 2) Build Settings specific generator used: -Note, the Build Settings tab settings are stored separately for Run mode and Debug mode. -#### 2.1) Launch Bar Launch Mode=Run, CMake Settings > Use these settings=checked, Generator=Ninja - Expected: Build uses generator Ninja -#### 2.2) Launch Bar Launch Mode=Debug, CMake Settings > Use these settings=checked, Generator=Unix Makefiles - Expected: Build uses generator Unix Makefiles -#### 2.3) Build Settings are remembered -#### 2.4) Build Settings for Run mode can be different to settings stored for Debug - -### 3) Build Settings specific Additional CMake arguments: -#### 3.1) CMake Settings > Use these settings=checked, Additional CMake arguments are used during build -#### 3.2) CMake Settings > Use these settings=unchecked, Additional CMake arguments are NOT used during build - -### 4) Build Settings specific Build and Clean command: -Note, not tested. These may be removed in future. - -## Setup & prerequisites -### Setup Host - Note, these instructions do not require the following tools to be added to the system path environment variable in the OS before starting Eclipse. This allows a clean environment to be maintained. - -- Install Eclipse/CDT on host. -- Install gcc toolchain and make tools on host. - - On Windows I used msys64 (https://www.msys2.org/), which contains mingw64. -- Install CMake and Ninja on host. - -### In Eclipse, setup tool paths. - #### Toolchain - When using a recognised gcc toolchain (mingw64 is one of these), CDT automatically registers the toolchain for use within the workbench. - * To check if the toolchain is registered, open Preferences > C/C++ > Core Build Toolchains. In the Available Toolchains list, check if it contains the toolchain you installed on the host. - -For example, when using mingw64 the following toolchain is available: - - Type Name OS Arch - GCC win32 x86_64 C:\msys64\mingw64\bin\gcc.exe win32 x86_64 -Otherwise, register your toolchain by clicking Add... in the User Defined Toolchains list. - -#### CMake & Ninja -* Open Preferences > C/C++ > Build > Environment and click Add... - - In Name enter "PATH" and in Value enter the path to CMake and Ninja, for example - - `C:\Program Files\CMake\bin;C:\Ninja\bin` - - - You probably want to make sure "Append variables to native environment" (default) is selected. - -#### Create a CMake project -* In Eclipse, choose File > C/C++ Project. -* In the New C/C++ Project wizard, choose CMake in the left hand side sash and then CMake Project and click Next. -* Enter a project name, for example helloworld and click Finish. -* In the Project Explorer, expand the generated project. It contains 3 files : - - helloworld.cpp - - CMakeLists.txt - - config.h.in - - ## Test Execution -### 20240129 Windows 10. All tests pass. + +[The tests](https://github.com/eclipse-cdt/cdt/blob/5e62200e60deccb0b43f341153a4db5f5b02ccc2/cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/Bug579242_manual_tests.md) were run on 20240129 Windows 10. +All tests pass. +This document captures some of the results for future developers to have a valuable comparison point. ### Setup Create CMake Project called helloworld. diff --git a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakeBuildTab.java b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakeBuildTab.java index 8ab0d8db6b7..ec94be07066 100644 --- a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakeBuildTab.java +++ b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakeBuildTab.java @@ -10,11 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.cmake.ui.internal; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; import org.eclipse.cdt.cmake.core.CMakeBuildConfigurationProvider; +import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.launch.ui.corebuild.CommonBuildTab; import org.eclipse.debug.core.ILaunchConfiguration; @@ -25,6 +26,7 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; @@ -37,16 +39,17 @@ public class CMakeBuildTab extends CommonBuildTab { * Checkbox allowing user to choose these settings over the default operating system defaults. * This is connected to the CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES preference. */ - private Button useUiCmakeSettings; - private Button unixGenButton; - private Button ninjaGenButton; + private Button useDefaultCmakeSettings; + private Combo generatorCombo; private Text cmakeArgsText; private Text buildCommandText; - private Text cleanCommandText; + private Text allTargetText; + private Text cleanTargetText; private Label generatorLabel; private Label cmakeArgsLabel; private Label buildCommandLabel; - private Label cleanCommandLabel; + private Label allTargetLabel; + private Label cleanTargetLabel; @Override protected String getBuildConfigProviderId() { @@ -67,35 +70,28 @@ public void createControl(Composite parent) { cmakeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); cmakeGroup.setLayout(new GridLayout()); - useUiCmakeSettings = new Button(cmakeGroup, SWT.CHECK); - useUiCmakeSettings.setText(Messages.CMakeBuildTab_useUICmakeSettings); - useUiCmakeSettings.setToolTipText(Messages.CMakeBuildTab_useUICmakeSettingsTip); - useUiCmakeSettings.addSelectionListener(new SelectionAdapter() { + useDefaultCmakeSettings = new Button(cmakeGroup, SWT.CHECK); + useDefaultCmakeSettings.setText(Messages.CMakeBuildTab_useDefaultCmakeSettings); + useDefaultCmakeSettings.setToolTipText(Messages.CMakeBuildTab_useDefaultCmakeSettingsTip); + useDefaultCmakeSettings.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + showDefaultsInUi(); updateEnablement(); updateLaunchConfigurationDialog(); } + }); generatorLabel = new Label(cmakeGroup, SWT.NONE); generatorLabel.setText(Messages.CMakeBuildTab_Generator); - Composite genComp = new Composite(cmakeGroup, SWT.BORDER); - genComp.setLayout(new GridLayout(2, true)); - - unixGenButton = new Button(genComp, SWT.RADIO); - unixGenButton.setText(Messages.CMakeBuildTab_UnixMakefiles); - unixGenButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - updateLaunchConfigurationDialog(); - } - }); - - ninjaGenButton = new Button(genComp, SWT.RADIO); - ninjaGenButton.setText(Messages.CMakeBuildTab_Ninja); - ninjaGenButton.addSelectionListener(new SelectionAdapter() { + CMakeGenerator[] generators = CMakeGenerator.values(); + String[] generatorNames = Arrays.stream(generators).map(CMakeGenerator::getCMakeName).toArray(String[]::new); + generatorCombo = new Combo(cmakeGroup, SWT.DROP_DOWN); + generatorCombo.setItems(generatorNames); + generatorCombo.select(0); + generatorCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateLaunchConfigurationDialog(); @@ -116,36 +112,54 @@ public void widgetSelected(SelectionEvent e) { buildCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); buildCommandText.addModifyListener(e -> updateLaunchConfigurationDialog()); - cleanCommandLabel = new Label(cmakeGroup, SWT.NONE); - cleanCommandLabel.setText(Messages.CMakeBuildTab_CleanCommand); + allTargetLabel = new Label(cmakeGroup, SWT.NONE); + allTargetLabel.setText(Messages.CMakeBuildTab_AllTarget); + + allTargetText = new Text(cmakeGroup, SWT.BORDER); + allTargetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + allTargetText.addModifyListener(e -> updateLaunchConfigurationDialog()); + + cleanTargetLabel = new Label(cmakeGroup, SWT.NONE); + cleanTargetLabel.setText(Messages.CMakeBuildTab_CleanTarget); - cleanCommandText = new Text(cmakeGroup, SWT.BORDER); - cleanCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - cleanCommandText.addModifyListener(e -> updateLaunchConfigurationDialog()); + cleanTargetText = new Text(cmakeGroup, SWT.BORDER); + cleanTargetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + cleanTargetText.addModifyListener(e -> updateLaunchConfigurationDialog()); + } + + /** + * When use CMake defaults is selected, restore the defaults + */ + private void showDefaultsInUi() { + if (useDefaultCmakeSettings.getSelection()) { + restoreProperties(getBuildConfiguration().getDefaultProperties()); + } } /** * Updates the enabled state of the CMake settings controls based on useUiCmakeSettings checkbox */ private void updateEnablement() { - boolean isSelected = useUiCmakeSettings.getSelection(); - generatorLabel.setEnabled(isSelected); - unixGenButton.setEnabled(isSelected); - ninjaGenButton.setEnabled(isSelected); - cmakeArgsLabel.setEnabled(isSelected); - cmakeArgsText.setEnabled(isSelected); - buildCommandLabel.setEnabled(isSelected); - buildCommandText.setEnabled(isSelected); - cleanCommandLabel.setEnabled(isSelected); - cleanCommandText.setEnabled(isSelected); + boolean isDefaultCMakeProperties = useDefaultCmakeSettings.getSelection(); + boolean enabled = !isDefaultCMakeProperties; + generatorLabel.setEnabled(enabled); + generatorCombo.setEnabled(enabled); + cmakeArgsLabel.setEnabled(enabled); + cmakeArgsText.setEnabled(enabled); + buildCommandLabel.setEnabled(enabled); + buildCommandText.setEnabled(enabled); + allTargetLabel.setEnabled(enabled); + allTargetText.setEnabled(enabled); + cleanTargetLabel.setEnabled(enabled); + cleanTargetText.setEnabled(enabled); } @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { // Set defaults for Build Settings ICBuildConfiguration buildConfig = getBuildConfiguration(); - buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES, - Boolean.toString(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES_DEFAULT)); + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS, + Boolean.toString(CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS_DEFAULT)); } @Override @@ -154,51 +168,27 @@ public void initializeFrom(ILaunchConfiguration configuration) { ICBuildConfiguration buildConfig = getBuildConfiguration(); - String generator = buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_GENERATOR); - updateGeneratorButtons(generator); + boolean isDefaultCMakeProperties = Boolean + .valueOf(buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS)); + useDefaultCmakeSettings.setSelection(isDefaultCMakeProperties); - String cmakeArgs = buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_ARGUMENTS); - if (cmakeArgs != null) { - cmakeArgsText.setText(cmakeArgs); + if (isDefaultCMakeProperties) { + restoreProperties(buildConfig.getDefaultProperties()); } else { - cmakeArgsText.setText(""); //$NON-NLS-1$ + restoreProperties(buildConfig.getProperties()); } - String buildCommand = buildConfig.getProperty(CMakeBuildConfiguration.BUILD_COMMAND); - if (buildCommand != null) { - buildCommandText.setText(buildCommand); - } else { - buildCommandText.setText(""); //$NON-NLS-1$ - } - - String cleanCommand = buildConfig.getProperty(CMakeBuildConfiguration.CLEAN_COMMAND); - if (cleanCommand != null) { - cleanCommandText.setText(cleanCommand); - } else { - cleanCommandText.setText(""); //$NON-NLS-1$ - } - - boolean isSelected = Boolean.valueOf(buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES)); - useUiCmakeSettings.setSelection(isSelected); updateEnablement(); } - private void updateGeneratorButtons(String generator) { - if (generator == null || generator.equals("Ninja")) { //$NON-NLS-1$ - ninjaGenButton.setSelection(true); - } else { - unixGenButton.setSelection(true); - } - } - @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { super.performApply(configuration); ICBuildConfiguration buildConfig = getBuildConfiguration(); - String gen = ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"; //$NON-NLS-1$ //$NON-NLS-2$ - buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_GENERATOR, gen); + String generator = generatorCombo.getText().trim(); + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_GENERATOR, generator); String cmakeArgs = cmakeArgsText.getText().trim(); if (!cmakeArgs.isEmpty()) { @@ -209,75 +199,63 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) { String buildCommand = buildCommandText.getText().trim(); if (!buildCommand.isEmpty()) { - buildConfig.setProperty(CMakeBuildConfiguration.BUILD_COMMAND, buildCommand); + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_BUILD_COMMAND, buildCommand); } else { - buildConfig.removeProperty(CMakeBuildConfiguration.BUILD_COMMAND); + buildConfig.removeProperty(CMakeBuildConfiguration.CMAKE_BUILD_COMMAND); } - String cleanCommand = cleanCommandText.getText().trim(); - if (!cleanCommand.isEmpty()) { - buildConfig.setProperty(CMakeBuildConfiguration.CLEAN_COMMAND, cleanCommand); + String allTarget = allTargetText.getText().trim(); + if (!allTarget.isEmpty()) { + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_ALL_TARGET, allTarget); } else { - buildConfig.removeProperty(CMakeBuildConfiguration.CLEAN_COMMAND); + buildConfig.removeProperty(CMakeBuildConfiguration.CMAKE_ALL_TARGET); } - boolean isSelected = useUiCmakeSettings.getSelection(); - buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES, Boolean.toString(isSelected)); + String cleanTarget = cleanTargetText.getText().trim(); + if (!cleanTarget.isEmpty()) { + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_CLEAN_TARGET, cleanTarget); + } else { + buildConfig.removeProperty(CMakeBuildConfiguration.CMAKE_CLEAN_TARGET); + } - Map saved = new HashMap<>(); - saved.put(CMakeBuildConfiguration.CMAKE_USE_UI_OVERRIDES, Boolean.toString(isSelected)); - getBuildConfiguration().setProperties(saved); + boolean isDefaultCMakeProperties = useDefaultCmakeSettings.getSelection(); + buildConfig.setProperty(CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS, + Boolean.toString(isDefaultCMakeProperties)); } @Override protected void saveProperties(Map properties) { super.saveProperties(properties); - properties.put(CMakeBuildConfiguration.CMAKE_GENERATOR, - ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"); //$NON-NLS-1$ //$NON-NLS-2$ - + properties.put(CMakeBuildConfiguration.CMAKE_GENERATOR, generatorCombo.getText().trim()); properties.put(CMakeBuildConfiguration.CMAKE_ARGUMENTS, cmakeArgsText.getText().trim()); - properties.put(CMakeBuildConfiguration.BUILD_COMMAND, buildCommandText.getText().trim()); - properties.put(CMakeBuildConfiguration.CLEAN_COMMAND, cleanCommandText.getText().trim()); + properties.put(CMakeBuildConfiguration.CMAKE_BUILD_COMMAND, buildCommandText.getText().trim()); + properties.put(CMakeBuildConfiguration.CMAKE_ALL_TARGET, allTargetText.getText().trim()); + properties.put(CMakeBuildConfiguration.CMAKE_CLEAN_TARGET, cleanTargetText.getText().trim()); } @Override protected void restoreProperties(Map properties) { super.restoreProperties(properties); - String gen = properties.get(CMakeBuildConfiguration.CMAKE_GENERATOR); - if (gen != null) { - switch (gen) { - case "Ninja": //$NON-NLS-1$ - ninjaGenButton.setSelection(true); - unixGenButton.setSelection(false); - break; - case "Unix Makefiles": //$NON-NLS-1$ - ninjaGenButton.setSelection(false); - unixGenButton.setSelection(true); - break; - } - } + String gen = properties.getOrDefault(CMakeBuildConfiguration.CMAKE_GENERATOR, + CMakeBuildConfiguration.CMAKE_GENERATOR_DEFAULT); + generatorCombo.setText(gen); - String cmakeArgs = properties.get(CMakeBuildConfiguration.CMAKE_ARGUMENTS); - if (cmakeArgs != null) { - cmakeArgsText.setText(cmakeArgs); - } else { - cmakeArgsText.setText(""); //$NON-NLS-1$ - } + String cmakeArgs = properties.getOrDefault(CMakeBuildConfiguration.CMAKE_ARGUMENTS, + CMakeBuildConfiguration.CMAKE_ARGUMENTS_DEFAULT); + cmakeArgsText.setText(cmakeArgs); - String buildCmd = properties.get(CMakeBuildConfiguration.BUILD_COMMAND); - if (buildCmd != null) { - buildCommandText.setText(buildCmd); - } else { - buildCommandText.setText(""); //$NON-NLS-1$ - } + String buildCmd = properties.getOrDefault(CMakeBuildConfiguration.CMAKE_BUILD_COMMAND, + CMakeBuildConfiguration.CMAKE_BUILD_COMMAND_DEFAULT); + buildCommandText.setText(buildCmd); - String cleanCmd = properties.get(CMakeBuildConfiguration.CLEAN_COMMAND); - if (cleanCmd != null) { - cleanCommandText.setText(cleanCmd); - } else { - cleanCommandText.setText(""); //$NON-NLS-1$ - } + String allTarget = properties.getOrDefault(CMakeBuildConfiguration.CMAKE_ALL_TARGET, + CMakeBuildConfiguration.CMAKE_ALL_TARGET_DEFAULT); + allTargetText.setText(allTarget); + + String cleanTarget = properties.getOrDefault(CMakeBuildConfiguration.CMAKE_CLEAN_TARGET, + CMakeBuildConfiguration.CMAKE_CLEAN_TARGET_DEFAULT); + cleanTargetText.setText(cleanTarget); } @Override diff --git a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java index deeb27c78e3..579ed81e76b 100644 --- a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java +++ b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java @@ -15,17 +15,16 @@ public class Messages extends NLS { public static String CMakeBuildTab_BuildCommand; - public static String CMakeBuildTab_CleanCommand; + public static String CMakeBuildTab_AllTarget; + public static String CMakeBuildTab_CleanTarget; public static String CMakeBuildTab_Cmake; public static String CMakeBuildTab_CMakeArgs; public static String CMakeBuildTab_Generator; - public static String CMakeBuildTab_Ninja; public static String CMakeBuildTab_NoneAvailable; public static String CMakeBuildTab_Settings; public static String CMakeBuildTab_Toolchain; - public static String CMakeBuildTab_UnixMakefiles; - public static String CMakeBuildTab_useUICmakeSettings; - public static String CMakeBuildTab_useUICmakeSettingsTip; + public static String CMakeBuildTab_useDefaultCmakeSettings; + public static String CMakeBuildTab_useDefaultCmakeSettingsTip; public static String CMakePreferencePage_Add; public static String CMakePreferencePage_ConfirmRemoveDesc; public static String CMakePreferencePage_ConfirmRemoveTitle; diff --git a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties index b13c7c24520..a79a8054681 100644 --- a/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties +++ b/cmake/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties @@ -1,15 +1,14 @@ CMakeBuildTab_BuildCommand=Build command -CMakeBuildTab_CleanCommand=Clean command +CMakeBuildTab_AllTarget=Build all target +CMakeBuildTab_CleanTarget=Clean target CMakeBuildTab_Cmake=CMake CMakeBuildTab_CMakeArgs=Additional CMake arguments: CMakeBuildTab_Generator=Generator -CMakeBuildTab_Ninja=Ninja CMakeBuildTab_NoneAvailable=No Toolchains Available for this Target CMakeBuildTab_Settings=CMake Settings CMakeBuildTab_Toolchain=Toolchain -CMakeBuildTab_UnixMakefiles=Unix Makefiles -CMakeBuildTab_useUICmakeSettings=Use these settings -CMakeBuildTab_useUICmakeSettingsTip=Use these settings instead of the operating system defaults +CMakeBuildTab_useDefaultCmakeSettings=Use default CMake settings +CMakeBuildTab_useDefaultCmakeSettingsTip=Use the default CMake settings that are provided by the tool chain and C build configuration CMakePreferencePage_Add=Add... CMakePreferencePage_ConfirmRemoveDesc=Do you wish to deregister the selected files? CMakePreferencePage_ConfirmRemoveTitle=Deregister CMake ToolChain File