diff --git a/NewAndNoteworthy/CDT-12.0.md b/NewAndNoteworthy/CDT-12.0.md index 45e2426bf66..683095e47ff 100644 --- a/NewAndNoteworthy/CDT-12.0.md +++ b/NewAndNoteworthy/CDT-12.0.md @@ -12,6 +12,21 @@ The minimum version of GLIBC required is now 2.31. This version can be found in Ubuntu 20.04 and later, RHEL 9.0 and later and other distros as well. CDT's native components will likely work with older versions of glibc too, assuming they provide the required APIs for Eclipse CDT. +# 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. + # 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 f4b2f61b517..0a520f8d9f0 100644 --- a/NewAndNoteworthy/CHANGELOG-API.md +++ b/NewAndNoteworthy/CHANGELOG-API.md @@ -8,6 +8,23 @@ This section describes API removals that occurred in past releases, and upcoming Below is the detailed descriptions of API changes and mitigation efforts API consumers need to take. +## API Changes in CDT 12.0. + +### org.eclipse.cdt.cmake.core.properties refactored + +A significant simplification to the CMake build properties was completed, this included removing some API that was not used. +The following classes have been removed or modified in API breaking ways: + +- org.eclipse.cdt.cmake.core.properties.ICMakePropertiesController removed +- org.eclipse.cdt.cmake.core.properties.IGeneralProperties removed +- org.eclipse.cdt.cmake.core.properties.IOsOverrides removed +- org.eclipse.cdt.cmake.core.properties.ICMakeProperties: + - 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. ### org.eclipse.cdt.make.ui.dialogs.DiscoveredPathContainerPage removed diff --git a/cmake/org.eclipse.cdt.cmake.core.tests/META-INF/MANIFEST.MF b/cmake/org.eclipse.cdt.cmake.core.tests/META-INF/MANIFEST.MF index a8ff015db30..c211928cc7f 100644 --- a/cmake/org.eclipse.cdt.cmake.core.tests/META-INF/MANIFEST.MF +++ b/cmake/org.eclipse.cdt.cmake.core.tests/META-INF/MANIFEST.MF @@ -5,9 +5,12 @@ Bundle-SymbolicName: org.eclipse.cdt.cmake.core.tests Bundle-Version: 1.0.0.qualifier Fragment-Host: org.eclipse.cdt.cmake.core;bundle-version="1.5.0" Import-Package: org.assertj.core.api;version="[3.24.2,4.0.0)", - org.junit.jupiter.api;version="[5.9.3,6.0.0)" + org.junit.jupiter.api;version="[5.9.3,6.0.0)", + org.mockito;version="[5.15.0,6.0.0)", + org.mockito.stubbing;version="[5.15.0,6.0.0)" Automatic-Module-Name: org.eclipse.cdt.cmake.core.tests Bundle-Vendor: %Bundle-Vendor Bundle-Copyright: %Bundle-Copyright -Require-Bundle: org.junit +Require-Bundle: org.junit, + org.eclipse.cdt.core.tests;bundle-version="[5.4.0,6.0.0)" 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 new file mode 100644 index 00000000000..7c949fb82e2 --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationTests.java @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 2025 Renesas Electronics Europe. + * + * 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; + +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; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +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; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests a new API added to the CMake Build Configuration which allows default CMake properties to be set. + * See the new interface {@link ICMakeBuildConfiguration}. + */ +public class CMakeBuildConfigurationTests extends BaseTestCase5 { + private IBuildConfiguration buildConfig; + private IToolChain mockToolchain; + + @BeforeEach + public void setup() throws Exception { + // Create a CMake project + IProject project = createCMakeProject(); + // Get the default build config from the project (it always has one) + buildConfig = project.getBuildConfig(IBuildConfiguration.DEFAULT_CONFIG_NAME); + // Setup a toolchain ready to use for creating the valid ICBuildConfiguration + mockToolchain = mock(IToolChain.class); + when(mockToolchain.getProperty(IToolChain.ATTR_OS)).thenReturn("osDummy"); + when(mockToolchain.getProperty(IToolChain.ATTR_ARCH)).thenReturn("archDummy"); + when(mockToolchain.getTypeId()).thenReturn("tc_typeId"); + when(mockToolchain.getId()).thenReturn("tcId"); + when(mockToolchain.getBuildConfigNameFragment()).thenReturn("buildConfigName"); + } + + /** + * Test for {@link ICMakeProperties#setGenerator()}. + * + * This test also verifies that what the ISV overrides in getCMakeProperties is what takes effect. + */ + @Test + public void getCMakePropertiesTestSetGenerator() throws Exception { + CMakeBuildConfiguration cmBuildConfig = new CMakeBuildConfiguration(buildConfig, "cmBuildConfigName", + mockToolchain) { + + @Override + public ICMakeProperties getCMakeProperties() { + ICMakeProperties properties = super.getCMakeProperties(); + properties.setGenerator(CMakeGenerator.WatcomWMake); + return properties; + } + }; + + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + assertThat(cMakeProperties.getGenerator(), is(CMakeGenerator.WatcomWMake)); + } + + /** + * Test for {@link ICMakeProperties#setExtraArguments()} + * + * This test also verifies that what the ISV overrides in getCMakeProperties is what takes effect. + */ + @Test + public void getCMakePropertiesTestSetExtraArguments() 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 ICMakeProperties getCMakeProperties() { + ICMakeProperties properties = super.getCMakeProperties(); + properties.setExtraArguments( + new ArrayList<>((List.of("-DplatformAgnosticArgsTest0=0", "-DplatformAgnosticArgsTest1=1")))); + return properties; + } + }; + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + List extraArguments = cMakeProperties.getExtraArguments(); + assertThat(extraArguments, contains("-DplatformAgnosticArgsTest0=0", "-DplatformAgnosticArgsTest1=1")); + } + + /** + * Test for {@link CMakeBuildConfiguration#getDefaultProperties()} + */ + @Test + public void getDefaultProperties() 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_GENERATOR, CMakeGenerator.WatcomWMake.getCMakeName()); + return defs; + } + }; + // Call the new method on ICMakeBuildConfiguration to get the default CMake properties. + ICMakeProperties cMakeProperties = cmBuildConfig.getCMakeProperties(); + 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()); + // Add C/C++ and CMake natures to make it a CMake project + IProjectDescription description = project.getDescription(); + description.setNatureIds( + new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, CMakeNature.ID }); + project.setDescription(description, null); + return project; + } +} diff --git a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesControllerTest.java b/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesControllerTest.java deleted file mode 100644 index 66f61d86b0d..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesControllerTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; -import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; -import org.eclipse.cdt.cmake.core.properties.IOsOverrides; -import org.junit.Test; - -/** - * @author Martin Weber - */ -public class CMakePropertiesControllerTest { - - /** - * Test method for {@link org.eclipse.cdt.cmake.core.internal.CMakePropertiesController#load()}. - * @throws IOException - */ - @Test - public void testLoad() throws IOException { - CMakePropertiesController testee; - // test with non-existing file - Path file = Path.of(new File("does-not-exist" + UUID.randomUUID().toString()).toURI()); - testee = new CMakePropertiesController(file, () -> { - }); - assertNotNull(testee.load()); - - // test with empty file - File f = File.createTempFile("CMakePropertiesControllerTest", null); - f.deleteOnExit(); - file = Path.of(f.toURI()); - testee = new CMakePropertiesController(file, () -> { - }); - assertNotNull(testee.load()); - } - - /** - * Test method for {@link org.eclipse.cdt.cmake.core.internal.CMakePropertiesController#save(org.eclipse.cdt.cmake.core.properties.ICMakeProperties)}. - * @throws IOException - */ - @Test - public void testSaveLoad() throws IOException { - Path file = Path.of(File.createTempFile("CMakePropertiesControllerTest", null).toURI()); - CMakePropertiesController testee = new CMakePropertiesController(file, () -> { - }); - ICMakeProperties props = testee.load(); - assertNotNull(props); - - props.setCacheFile("cacheFile"); - props.setClearCache(true); - props.setDebugOutput(true); - props.setDebugTryCompile(true); - props.setTrace(true); - props.setWarnNoDev(true); - props.setWarnUnitialized(true); - props.setWarnUnused(true); - { - IOsOverrides overrides = props.getLinuxOverrides(); - overrides.setGenerator(CMakeGenerator.Ninja); - List extraArgs = new ArrayList<>(); - extraArgs.add("arg1l=1"); - extraArgs.add("arg2l=2"); - overrides.setExtraArguments(extraArgs); - } - { - IOsOverrides overrides = props.getWindowsOverrides(); - overrides.setGenerator(CMakeGenerator.BorlandMakefiles); - List extraArgs = new ArrayList<>(); - extraArgs.add("arg1w=1"); - extraArgs.add("arg2w=2"); - overrides.setExtraArguments(extraArgs); - } - - List extraArgs = new ArrayList<>(); - extraArgs.add("arg1"); - extraArgs.add("arg2"); - props.setExtraArguments(extraArgs); - - testee.save(props); - - ICMakeProperties in = testee.load(); - assertThat(in).usingRecursiveComparison().isEqualTo(props); - } -} diff --git a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesEvolutionTest.java b/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesEvolutionTest.java deleted file mode 100644 index 08045f27daa..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core.tests/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesEvolutionTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.cmake.core.internal.properties.CMakePropertiesBean; -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; -import org.junit.Test; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; -import org.yaml.snakeyaml.inspector.TagInspector; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -/** - * @author Martin Weber - */ -public class CMakePropertiesEvolutionTest { - - private static final String VALUE_OF_EVOLVED_PROPERTY = "value of evolvedProperty"; - - /** Tests whether properties persisted by a previous version of our bundle can be loaded by - * a newer version of our bundle. - */ - @Test - public void testSaveLoadEvolution_1() throws IOException { - CMakePropertiesBean propsAtDefault = new CMakePropertiesBean(); - propsAtDefault.reset(true); - - CMakePropertiesBean props = new CMakePropertiesBean(); - props.setCacheFile("cacheFile"); - props.setClearCache(true); - props.setDebugOutput(true); - props.setDebugTryCompile(true); - props.setTrace(true); - props.setWarnNoDev(true); - props.setWarnUnitialized(true); - props.setWarnUnused(true); - props.getLinuxOverrides().setGenerator(CMakeGenerator.Ninja); - - List extraArgs = new ArrayList<>(); - extraArgs.add("arg1"); - extraArgs.add("arg2"); - props.setExtraArguments(extraArgs); - - var loaderoptions = new LoaderOptions(); - TagInspector taginspector = tag -> tag.getClassName().equals(CMakePropertiesBean.class.getName()); - loaderoptions.setTagInspector(taginspector); - Representer customRepresenter = new Representer(new DumperOptions()); - customRepresenter.addClassTag(CMakePropertiesBean.class, Tag.MAP); - - Yaml yaml = new Yaml(new CustomClassLoaderConstructor(this.getClass().getClassLoader(), loaderoptions), - customRepresenter); - String output = yaml.dump(props); - - // try to load as evolved properties.. - CMakePropertiesBean_1 in = yaml.loadAs(output, CMakePropertiesBean_1.class); - assertNotNull(in); - assertEquals(CMakePropertiesEvolutionTest.VALUE_OF_EVOLVED_PROPERTY, in.getEvolvedProperty()); - assertThat(props).usingRecursiveComparison().isEqualTo(in); - } - - private static class CMakePropertiesBean_1 extends CMakePropertiesBean { - private String evolvedProperty; - - @Override - public void reset(boolean resetOsOverrides) { - super.reset(resetOsOverrides); - evolvedProperty = CMakePropertiesEvolutionTest.VALUE_OF_EVOLVED_PROPERTY; - } - - public String getEvolvedProperty() { - return evolvedProperty; - } - - public void setEvolvedProperty(String evolvedProperty) { - this.evolvedProperty = evolvedProperty; - } - } -} diff --git a/cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF b/cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF index e805cfdfcc0..c051e258602 100644 --- a/cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF +++ b/cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF @@ -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.6.0.qualifier +Bundle-Version: 2.0.0.qualifier Bundle-Activator: org.eclipse.cdt.cmake.core.internal.Activator Bundle-Vendor: %providerName Require-Bundle: org.eclipse.core.runtime, 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 5b437b7bd35..1760baff6f1 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 @@ -12,11 +12,8 @@ import java.io.File; import java.io.IOException; -import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -24,19 +21,16 @@ 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; -import org.eclipse.cdt.cmake.core.internal.CMakePropertiesController; import org.eclipse.cdt.cmake.core.internal.CMakeUtils; import org.eclipse.cdt.cmake.core.internal.CommandDescriptorBuilder; import org.eclipse.cdt.cmake.core.internal.CommandDescriptorBuilder.CommandDescriptor; -import org.eclipse.cdt.cmake.core.internal.IOsOverridesSelector; 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.cmake.core.properties.ICMakePropertiesController; -import org.eclipse.cdt.cmake.core.properties.IOsOverrides; import org.eclipse.cdt.core.CommandLauncherManager; import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ErrorParserManager; @@ -56,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; @@ -69,28 +64,14 @@ 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 1.6 + * @since 2.0 */ -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$ +public class CMakeBuildConfiguration extends CBuildConfiguration implements ICMakeBuildConfiguration { private ICMakeToolChainFile toolChainFile; - // lazily instantiated.. - private ICMakePropertiesController pc; - private Map infoPerResource; /** * whether one of the CMakeLists.txt files in the project has been modified and saved by the @@ -102,10 +83,6 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { * To work around that, we run cmake in advance with its dedicated working error parser. */ private boolean cmakeListsModified; - /** - * whether we have to delete file CMakeCache.txt to avoid complaints by cmake - */ - private boolean deleteCMakeCache; public CMakeBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); @@ -124,6 +101,50 @@ public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolCha this.toolChainFile = toolChainFile; } + @Override + public ICMakeProperties getCMakeProperties() { + ICMakeProperties cmakeProperties = CMakePropertiesFactory.createProperties(); + + String useDefaultCMakeSettings = getProperty(CMAKE_USE_DEFAULT_CMAKE_SETTINGS); + final Map properties; + if (Boolean.parseBoolean(useDefaultCMakeSettings)) { + properties = getDefaultProperties(); + } else { + properties = getProperties(); + } + + String cmakeGenerator = properties.get(CMAKE_GENERATOR); + if (cmakeGenerator != null) { + CMakeGenerator generator = CMakeGenerator.getGenerator(cmakeGenerator); + if (generator == null) { + cmakeProperties.setGenerator(new CustomCMakeGenerator(cmakeGenerator)); + } else { + cmakeProperties.setGenerator(generator); + } + } + + String extraArgs = properties.get(CMAKE_ARGUMENTS); + List extraArgsList = Arrays.asList(CommandLineUtil.argumentsToArray(extraArgs)); + cmakeProperties.setExtraArguments(extraArgsList); + + String buildCommand = properties.get(CMAKE_BUILD_COMMAND); + if (buildCommand != null && !buildCommand.isBlank()) { + cmakeProperties.setCommand(buildCommand); + } + + String cleanTarget = properties.get(CMAKE_CLEAN_TARGET); + if (cleanTarget != null && !cleanTarget.isBlank()) { + cmakeProperties.setCleanTarget(cleanTarget); + } + + String allTarget = properties.get(CMAKE_ALL_TARGET); + if (allTarget != null && !allTarget.isBlank()) { + cmakeProperties.setAllTarget(allTarget); + } + + return cmakeProperties; + } + /** * Gets the tool-chain description file to pass to the cmake command-line. * @@ -156,13 +177,8 @@ public IProject[] build(int kind, Map args, IConsole console, IP Path buildDir = getBuildDirectory(); boolean runCMake = cmakeListsModified; - if (deleteCMakeCache) { - Files.deleteIfExists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$ - deleteCMakeCache = false; - runCMake = true; - } + ICMakeProperties cmakeProperties = getCMakeProperties(); - ICMakeProperties cmakeProperties = getPropertiesController().load(); runCMake |= !Files.exists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$ // Causes CMAKE_BUILD_TYPE to be set according to the launch mode @@ -172,12 +188,16 @@ public IProject[] build(int kind, Map args, IConsole console, IP cmakeProperties.setBuildType("Release"); //$NON-NLS-1$ } - final SimpleOsOverridesSelector overridesSelector = new SimpleOsOverridesSelector(); if (!runCMake) { - CMakeGenerator generator = overridesSelector.getOsOverrides(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, overridesSelector); + CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties); if (runCMake) { CMakeBuildConfiguration.deleteCMakeErrorMarkers(project); @@ -243,7 +263,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$ @@ -279,23 +299,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(); @@ -303,10 +306,9 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); - ICMakeProperties cmakeProperties = getPropertiesController().load(); - CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties, - new SimpleOsOverridesSelector()); - CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(getCleanCommand()); + ICMakeProperties cmakeProperties = getCMakeProperties(); + CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties); + CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(cmakeProperties.getCleanTarget()); ConsoleOutputStream outStream = console.getOutputStream(); Path buildDir = getBuildDirectory(); @@ -362,54 +364,6 @@ private void processCompileCommandsFile(IConsole console, IProgressMonitor monit parser.parse(monitor); } - /** - * Recursively removes any files and directories found below the specified Path. - */ - private static void cleanDirectory(Path dir) throws IOException { - SimpleFileVisitor deltor = new SimpleFileVisitor<>() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - super.postVisitDirectory(dir, exc); - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }; - Path[] files = Files.list(dir).toArray(Path[]::new); - for (Path file : files) { - Files.walkFileTree(file, deltor); - } - } - - /** Lazily creates the CMakePropertiesController for the project. - */ - private ICMakePropertiesController getPropertiesController() { - if (pc == null) { - final Path filePath = Path.of(getProject().getFile(".settings/CDT-cmake.yaml").getLocationURI()); //$NON-NLS-1$ - pc = new CMakePropertiesController(filePath, () -> { - deleteCMakeCache = true; - // TODO delete cache file here for the case a user restarts the workbench - // prior to running a new build - }); - } - return pc; - } - - // interface IAdaptable - @Override - @SuppressWarnings("unchecked") - public T getAdapter(Class adapter) { - if (ICMakePropertiesController.class.equals(adapter)) { - return (T) pc; - } - return super.getAdapter(adapter); - } - /** * Overridden since the ScannerInfoCache mechanism does not satisfy our needs. */ @@ -522,6 +476,36 @@ private static void deleteCMakeErrorMarkers(IProject project) throws CoreExcepti project.deleteMarkers(ICMakeExecutionMarkerFactory.CMAKE_PROBLEM_MARKER_ID, false, IResource.DEPTH_INFINITE); } + /** + * For cases when a generator is not one of those built-in to CDT we use this + * custom generator. Unlike the built-in generators this one does not know + * what the generator will use as a makefile name, so the build need to run + * the generation stage with each build instead of optimizing it. See + * {@link CMakeBuildConfiguration#build(int, Map, IConsole, IProgressMonitor)} + */ + private static final class CustomCMakeGenerator implements ICMakeGenerator { + private final String cmakeGenerator; + + private CustomCMakeGenerator(String cmakeGenerator) { + this.cmakeGenerator = cmakeGenerator; + } + + @Override + public String getMakefileName() { + return null; + } + + @Override + public String getIgnoreErrOption() { + return null; + } + + @Override + public String getCMakeName() { + return cmakeGenerator; + } + } + private static class CMakeIndexerInfoConsumer implements ISourceFileInfoConsumer { /** * gathered IScannerInfo objects or null if no new IScannerInfo was received @@ -582,50 +566,28 @@ public void shutdown() { } } // CMakeIndexerInfoConsumer - /** - * 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 Map getDefaultProperties() { + return Map.of(// + CMAKE_GENERATOR, CMAKE_GENERATOR_DEFAULT, // + CMAKE_USE_DEFAULT_CMAKE_SETTINGS, 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 // + ); + } - @Override - public IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) { - IOsOverrides overrides; - // get overrides. Simplistic approach ATM, probably a strategy might fit better. - // see comment in CMakeIndexerInfoConsumer#getFileForCMakePath() - final String os = Platform.getOS(); - if (Platform.OS_WIN32.equals(os)) { - overrides = cmakeProperties.getWindowsOverrides(); - } else { - // fall back to linux, if OS is unknown - overrides = cmakeProperties.getLinuxOverrides(); - } - return getUiOrOsOverrides(overrides); - } + @Override + public Map getProperties() { + var map = new HashMap(); + map.putAll(getDefaultProperties()); + map.putAll(super.getProperties()); + return map; + } - 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 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 + @Override + public String getProperty(String name) { + return getSettings().get(name, getDefaultProperties().get(name)); + } } diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java index 3db6183f7bf..2ddb20cbe92 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/CMakeBuildConfigurationProvider.java @@ -34,7 +34,7 @@ * See the example project * org.eclipse.cdt.cmake.example for a full example. * - * @since 1.6 + * @since 2.0 */ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProvider { diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeBuildConfiguration.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeBuildConfiguration.java new file mode 100644 index 00000000000..d52dffff37a --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeBuildConfiguration.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2025 Renesas Electronics Europe 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; + +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.build.ICBuildConfiguration; + +/** + * Encapsulates the CMake specific {@link ICBuildConfiguration} for building CMake projects. + *

+ * This interface defines the set of properties that can be exposed to a user via the UI. This + * set of properties is converted to a {@link ICMakeBuildConfiguration} when CDT runs CMake's + * build commands. + * + * @since 2.0 + */ +public interface ICMakeBuildConfiguration { + + /** + * When true, {@link #getCMakeProperties()} should use defaults from {@link #getDefaultProperties()}, + * otherwise uses values from {@link #getProperties()} + */ + public static final String CMAKE_USE_DEFAULT_CMAKE_SETTINGS = "cmake.use.default.cmake.settings"; //$NON-NLS-1$ + public static final String CMAKE_USE_DEFAULT_CMAKE_SETTINGS_DEFAULT = "true"; //$NON-NLS-1$ + + /** + * The generator to use, typically one of {@link CMakeGenerator}, or if not present in {@link CMakeGenerator} an + * an custom one will be instantiated. Extenders can customize the generator by overriding {@link #getCMakeProperties()} + * and create an {@link ICMakeGenerator} to assign to {@link ICMakeProperties#setGenerator(ICMakeGenerator)} + */ + public static final String CMAKE_GENERATOR = "cmake.generator"; //$NON-NLS-1$ + public static final String CMAKE_GENERATOR_DEFAULT = "Ninja"; //$NON-NLS-1$ + + /** + * Additional arguments to pass to CMake when running the generator stage. + */ + public static final String CMAKE_ARGUMENTS = "cmake.arguments"; //$NON-NLS-1$ + public static final String CMAKE_ARGUMENTS_DEFAULT = ""; //$NON-NLS-1$ + + /** + * Custom environment to use when launching CMake + */ + public static final String CMAKE_ENV = "cmake.environment"; //$NON-NLS-1$ + + /** + * Name of the CMake executable. + */ + 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$ + + /** + * Name of the default target to pass to CMake's build {@code --target} when building. + */ + 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$ + + /** + * Name of the default target to pass to CMake's build {@code --target} when cleaning. + */ + 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$ + + /** + * Converts the {@link ICBuildConfiguration}'s properties, using the keys defined above + * into an {@link ICMakeProperties} that configures the CMake build processes. + * @return A ICMakeProperties object. Must not be null. + */ + ICMakeProperties getCMakeProperties(); +} diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/Messages.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/Messages.java index 8fb930da018..127052040b7 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/Messages.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/Messages.java @@ -16,7 +16,7 @@ * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. * @noreference This class is not intended to be referenced by clients. - * @since 1.6 + * @since 2.0 */ public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.cdt.cmake.core.messages"; //$NON-NLS-1$ diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesController.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesController.java deleted file mode 100644 index f857357b490..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakePropertiesController.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import java.util.function.BinaryOperator; -import java.util.function.Predicate; - -import org.eclipse.cdt.cmake.core.internal.properties.CMakePropertiesBean; -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; -import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; -import org.eclipse.cdt.cmake.core.properties.ICMakePropertiesController; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; -import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; -import org.yaml.snakeyaml.inspector.TagInspector; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -/** - * A {@code ICMakePropertiesController} that monitors modifications to the project properties that force - * us to delete file CMakeCache.txt to avoid complaints by cmake. - * @author Martin Weber - */ -public class CMakePropertiesController implements ICMakePropertiesController { - - private final Path storageFile; - private final Runnable cmakeCacheDirtyMarker; - - private String cacheFile; - private List extraArguments; - private CMakeGenerator generatorLinux; - private List extraArgumentsLinux; - private CMakeGenerator generatorWindows; - private List extraArgumentsWindows; - private String buildType; - - /** Creates a new CMakePropertiesController object. - * - * @param storageFile - * the file where to persist the properties. The file may not exist, but its parent directory is supposed to exist. - * @param cmakeCacheDirtyMarker - * the object to notify when modifications to the project properties force - * us to delete file CMakeCache.txt to avoid complaints by cmake - */ - public CMakePropertiesController(Path storageFile, Runnable cmakeCacheDirtyMarker) { - this.storageFile = Objects.requireNonNull(storageFile); - this.cmakeCacheDirtyMarker = Objects.requireNonNull(cmakeCacheDirtyMarker); - } - - @Override - public ICMakeProperties load() throws IOException { - CMakePropertiesBean props = null; - if (Files.exists(storageFile)) { - try (InputStream is = Files.newInputStream(storageFile)) { - var classLoader = this.getClass().getClassLoader(); - - var loaderoptions = new LoaderOptions(); - TagInspector taginspector = tag -> tag.getClassName().equals(CMakePropertiesBean.class.getName()); - loaderoptions.setTagInspector(taginspector); - - var clConstructor = new CustomClassLoaderConstructor(classLoader, loaderoptions); - - props = new Yaml(clConstructor).loadAs(is, CMakePropertiesBean.class); - // props is null here if if no document was available in the file - } - } - if (props == null) { - // nothing was persisted, return default properties - props = new CMakePropertiesBean(); - } - - setupModifyDetection(props); - return props; - } - - @Override - public void save(ICMakeProperties properties) throws IOException { - // detect whether changes force us to delete file CMakeCache.txt to avoid complaints by cmake - if (isPropertyModified(properties) || isExtraArgumentsPropertyModified(properties)) { - cmakeCacheDirtyMarker.run(); // mark cmake cache file for removal - } - if (!Files.exists(storageFile)) { - try { - Files.createFile(storageFile); - } catch (FileAlreadyExistsException ignore) { - } - } - try (Writer wr = new OutputStreamWriter(Files.newOutputStream(storageFile))) { - Representer customRepresenter = new Representer(new DumperOptions()); - customRepresenter.addClassTag(CMakePropertiesBean.class, Tag.MAP); - new Yaml(new Constructor(CMakePropertiesBean.class, new LoaderOptions()), customRepresenter) - .dump(properties, wr); - } - - setupModifyDetection(properties); - } - - /** Gets whether changes in one of the basic properties force us to delete file CMakeCache.txt - * to avoid complaints by cmake. - */ - private boolean isPropertyModified(ICMakeProperties properties) { - return !Objects.equals(buildType, properties.getBuildType()) - || !Objects.equals(cacheFile, properties.getCacheFile()) - || !Objects.equals(generatorLinux, properties.getLinuxOverrides().getGenerator()) - || !Objects.equals(generatorWindows, properties.getWindowsOverrides().getGenerator()); - } - - /** Gets whether changes in one of the extra arguments properties force us to delete file CMakeCache.txt - * to avoid complaints by cmake. - */ - private boolean isExtraArgumentsPropertyModified(ICMakeProperties properties) { - return hasExtraArgumentChanged(extraArguments, properties.getExtraArguments()) - || hasExtraArgumentChanged(extraArgumentsLinux, properties.getLinuxOverrides().getExtraArguments()) - || hasExtraArgumentChanged(extraArgumentsWindows, properties.getWindowsOverrides().getExtraArguments()); - } - - /** Sets up detection of modifications that force us to delete file CMakeCache.txt to avoid complaints by cmake - */ - private void setupModifyDetection(ICMakeProperties properties) { - buildType = properties.getBuildType(); - cacheFile = properties.getCacheFile(); - extraArguments = properties.getExtraArguments(); - generatorLinux = properties.getLinuxOverrides().getGenerator(); - extraArgumentsLinux = properties.getLinuxOverrides().getExtraArguments(); - generatorWindows = properties.getWindowsOverrides().getGenerator(); - extraArgumentsWindows = properties.getWindowsOverrides().getExtraArguments(); - } - - private boolean hasExtraArgumentChanged(List expected, List actual) { - String wanted = "CMAKE_TOOLCHAIN_FILE"; //$NON-NLS-1$ - // extract the last arguments that contain String wanted.. - Predicate predContains = a -> a.contains(wanted); - BinaryOperator keepLast = (first, second) -> second; - String a1 = expected.stream().filter(predContains).reduce(keepLast).orElse(null); - String a2 = actual.stream().filter(predContains).reduce(keepLast).orElse(null); - if (!Objects.equals(a1, a2)) { - return true; - } - return false; - } -} \ No newline at end of file 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 41633b8d1ac..c7fd148b2f0 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,10 +16,8 @@ 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.cdt.cmake.core.properties.IOsOverrides; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.VariablesPlugin; @@ -33,14 +31,12 @@ public class CommandDescriptorBuilder { private final ICMakeProperties cmakeProperties; - private final IOsOverridesSelector overridesSelector; /** * @param cmakeProperties the project properties related to the cmake command */ - public CommandDescriptorBuilder(ICMakeProperties cmakeProperties, IOsOverridesSelector overridesSelector) { + public CommandDescriptorBuilder(ICMakeProperties cmakeProperties) { this.cmakeProperties = Objects.requireNonNull(cmakeProperties); - this.overridesSelector = Objects.requireNonNull(overridesSelector); } /** @@ -56,8 +52,10 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc List args = new ArrayList<>(); List env = new ArrayList<>(); - // defaults for all OSes... - args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); + // cmake command + IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); + args.add(varManager.performStringSubstitution(cmakeProperties.getCommand())); + /* add general settings */ if (cmakeProperties.isWarnNoDev()) args.add("-Wno-dev"); //$NON-NLS-1$ @@ -67,10 +65,10 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc args.add("--debug-output"); //$NON-NLS-1$ if (cmakeProperties.isTrace()) args.add("--trace"); //$NON-NLS-1$ - if (cmakeProperties.isWarnUnitialized()) - args.add("--warn-unitialized"); //$NON-NLS-1$ - if (cmakeProperties.isWarnUnused()) - args.add("--warn-unused"); //$NON-NLS-1$ + if (cmakeProperties.isWarnUninitialized()) + args.add("--warn-uninitialized"); //$NON-NLS-1$ + if (cmakeProperties.isWarnUnusedVars()) + args.add("--warn-unused-vars"); //$NON-NLS-1$ { String file = cmakeProperties.getCacheFile(); if (!(file == null || file.isBlank())) { @@ -78,7 +76,6 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc args.add(file); } } - CommandDescriptorBuilder.appendCMakeArguments(args, cmakeProperties.getExtraArguments()); /* at last, add our requirements that override extra args specified by the user... */ { @@ -93,10 +90,12 @@ public CommandDescriptor makeCMakeCommandline(Path toolChainFile) throws CoreExc if (toolChainFile != null) { args.add("-DCMAKE_TOOLCHAIN_FILE=" + toolChainFile.toString()); //$NON-NLS-1$ } - /* Add settings for the operating system we are running under, - * and the user additional CMake arguments set in the Launch Configuration UI. - */ - CommandDescriptorBuilder.appendCMakeOsOverrideArgs(args, overridesSelector.getOsOverrides(cmakeProperties)); + + args.add("-G"); //$NON-NLS-1$ + final ICMakeGenerator generator = cmakeProperties.getGenerator(); + args.add(generator.getCMakeName()); + + CommandDescriptorBuilder.appendCMakeArguments(args, cmakeProperties.getExtraArguments()); return new CommandDescriptor(args, env); } @@ -112,14 +111,9 @@ public CommandDescriptor makeCMakeBuildCommandline(String buildscriptTarget) thr List args = new ArrayList<>(); List env = new ArrayList<>(); - IOsOverrides osOverrides = overridesSelector.getOsOverrides(cmakeProperties); - if (osOverrides.getUseDefaultCommand()) { - args.add(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); - } else { - IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); - String cmd = varManager.performStringSubstitution(osOverrides.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$ @@ -146,28 +140,6 @@ private static void appendCMakeArguments(List argList, final List args, final IOsOverrides prefs) throws CoreException { - // replace cmake command, if given - if (!prefs.getUseDefaultCommand()) { - IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); - String cmd = varManager.performStringSubstitution(prefs.getCommand()); - args.set(0, cmd); - } - args.add("-G"); //$NON-NLS-1$ - final CMakeGenerator generator = prefs.getGenerator(); - args.add(generator.getCMakeName()); - appendCMakeArguments(args, prefs.getExtraArguments()); - } - /** * Command-line arguments and additional environment variables to be used to run a process. * @author Martin Weber diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/IOsOverridesSelector.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/IOsOverridesSelector.java deleted file mode 100644 index 1aa21c0b31e..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/IOsOverridesSelector.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal; - -import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; -import org.eclipse.cdt.cmake.core.properties.IOsOverrides; - -/** - * Responsible for retrieving the {@link IOsOverrides} that match the target operating system of a - * project build. - * - * @author Martin Weber - */ -public interface IOsOverridesSelector { - /** - * Gets the overrides from the specified {@code ICMakeProperties} object that match the target - * operating system.
- * Intended to get the command-line arguments to generate build-scripts or perform the build if - * the platform the eclipse workbench is running on differs from the platform the build - * artifacts are to be build for. (E.g.: The workbench runs on windows but the build is to run - * in a container that runs linux.) - */ - IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties); -} diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/AbstractOsOverrides.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/AbstractOsOverrides.java deleted file mode 100644 index 8d5909c74d5..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/AbstractOsOverrides.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal.properties; - -import java.util.ArrayList; -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.IOsOverrides; - -/** - * Preferences that override/augment the generic properties when running under a - * specific OS. - * - * @author Martin Weber - */ -public abstract class AbstractOsOverrides implements IOsOverrides { - - private String command; - private boolean useDefaultCommand; - private CMakeGenerator generator; - private List extraArguments = new ArrayList<>(0); - - /** - * Creates a new object, initialized with all default values. - */ - public AbstractOsOverrides() { - reset(); - } - - /** - * Sets each value to its default. - */ - public void reset() { - setCommand(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); - useDefaultCommand = true; - setGenerator(CMakeGenerator.UnixMakefiles); - extraArguments.clear(); - } - - @Override - public final boolean getUseDefaultCommand() { - return useDefaultCommand; - } - - @Override - public void setUseDefaultCommand(boolean useDefaultCommand) { - this.useDefaultCommand = useDefaultCommand; - } - - @Override - public final String getCommand() { - return command; - } - - @Override - public void setCommand(String command) { - this.command = Objects.requireNonNull(command, "command"); //$NON-NLS-1$ - } - - @Override - public final CMakeGenerator getGenerator() { - return generator; - } - - @Override - public void setGenerator(CMakeGenerator generator) { - this.generator = Objects.requireNonNull(generator, "generator"); //$NON-NLS-1$ - } - - @Override - public final List getExtraArguments() { - return List.copyOf(extraArguments); - } - - @Override - public void setExtraArguments(List extraArguments) { - this.extraArguments = extraArguments; - } - -} \ No newline at end of file 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 e24b40c8e66..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 @@ -13,7 +13,11 @@ import java.util.ArrayList; 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; /** @@ -23,19 +27,41 @@ */ public class CMakePropertiesBean implements ICMakeProperties { - private boolean warnNoDev, debugTryCompile, debugOutput, trace, warnUnitialized, warnUnused; - private String cacheFile; - private boolean clearCache; + 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 LinuxOverrides linuxOverrides = new LinuxOverrides(); - private WindowsOverrides windowsOverrides = new WindowsOverrides(); 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. */ public CMakePropertiesBean() { - reset(true); + } + + @Override + public final String getCommand() { + return command; + } + + @Override + public void setCommand(String command) { + this.command = Objects.requireNonNull(command, "command"); //$NON-NLS-1$ + } + + @Override + public final ICMakeGenerator getGenerator() { + return generator; + } + + @Override + public void setGenerator(ICMakeGenerator generator) { + this.generator = Objects.requireNonNull(generator, "generator"); //$NON-NLS-1$ } @Override @@ -79,22 +105,22 @@ public void setTrace(boolean trace) { } @Override - public boolean isWarnUnitialized() { - return warnUnitialized; + public boolean isWarnUninitialized() { + return warnUninitialized; } @Override - public void setWarnUnitialized(boolean warnUnitialized) { - this.warnUnitialized = warnUnitialized; + public void setWarnUninitialized(boolean warnUninitialized) { + this.warnUninitialized = warnUninitialized; } @Override - public boolean isWarnUnused() { + public boolean isWarnUnusedVars() { return warnUnused; } @Override - public void setWarnUnused(boolean warnUnused) { + public void setWarnUnusedVars(boolean warnUnused) { this.warnUnused = warnUnused; } @@ -118,24 +144,6 @@ public void setExtraArguments(List extraArguments) { this.extraArguments = extraArguments; } - @Override - public LinuxOverrides getLinuxOverrides() { - return linuxOverrides; - } - - public void setLinuxOverrides(LinuxOverrides linuxOverrides) { - this.linuxOverrides = linuxOverrides; - } - - @Override - public WindowsOverrides getWindowsOverrides() { - return windowsOverrides; - } - - public void setWindowsOverrides(WindowsOverrides windowsOverrides) { - this.windowsOverrides = windowsOverrides; - } - @Override public String getCacheFile() { return cacheFile; @@ -157,19 +165,22 @@ public void setClearCache(boolean clearCache) { } @Override - public void reset(boolean resetOsOverrides) { - warnNoDev = false; - debugTryCompile = false; - debugOutput = false; - trace = false; - warnUnitialized = false; - warnUnused = false; - extraArguments.clear(); - cacheFile = ""; //$NON-NLS-1$ + public String getCleanTarget() { + return cleanTarget; + } - if (resetOsOverrides) { - linuxOverrides.reset(); - windowsOverrides.reset(); - } + @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/internal/properties/WindowsOverrides.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/WindowsOverrides.java deleted file mode 100644 index 4e79f113d70..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/WindowsOverrides.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.internal.properties; - -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; - -/** - * Preferences that override/augment the generic properties when running under - * Windows. - * - * @author Martin Weber - */ -public class WindowsOverrides extends AbstractOsOverrides { - - /** Overridden to set a sensible generator. */ - @Override - public void reset() { - super.reset(); - setGenerator(CMakeGenerator.MinGWMakefiles); - } -} 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/internal/properties/LinuxOverrides.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java similarity index 54% rename from cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/LinuxOverrides.java rename to cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java index d07699089d1..71336495d75 100644 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/LinuxOverrides.java +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Martin Weber. + * Copyright (c) 2025 Renesas Electronics Europe. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,20 +8,15 @@ * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ +package org.eclipse.cdt.cmake.core.properties; -package org.eclipse.cdt.cmake.core.internal.properties; +import org.eclipse.cdt.cmake.core.internal.properties.CMakePropertiesBean; /** - * Preferences that override/augment the generic properties when running under - * Linux. - * - * @author Martin Weber + * @since 2.0 */ -public class LinuxOverrides extends AbstractOsOverrides { - - /** - * Creates a new object, initialized with all default values. - */ - public LinuxOverrides() { +public class CMakePropertiesFactory { + public static ICMakeProperties createProperties() { + return new CMakePropertiesBean(); } } 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 a817efc78b2..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,6 +23,29 @@ * @since 1.4 */ public interface ICMakeProperties { + /** + * Gets the cmake command. Has no effect if {@link #getUseDefaultCommand()} returns false. + * @since 2.0 + */ + String getCommand(); + + /** + * Sets the cmake command. + * @since 2.0 + */ + void setCommand(String command); + + /** + * Gets the cmake buildscript generator. + * @since 2.0 + */ + ICMakeGenerator getGenerator(); + + /** + * Sets the cmake build-script generator. + * @since 2.0 + */ + void setGenerator(ICMakeGenerator generator); /** * {@code -Wno-dev} @@ -66,23 +89,27 @@ public interface ICMakeProperties { /** * {@code --warn-uninitialized} + * @since 2.0 */ - boolean isWarnUnitialized(); + boolean isWarnUninitialized(); /** * {@code --warn-uninitialized} + * @since 2.0 */ - void setWarnUnitialized(boolean warnUnitialized); + void setWarnUninitialized(boolean warnUninitialized); /** * {@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. @@ -141,22 +168,27 @@ public interface ICMakeProperties { void setClearCache(boolean clearCache); /** - * Gets the override/augmenting properties to apply when the build runs on linux. + * The target to pass to {@code --target} CMake command line option, used when user asks to clean a project. + * @since 2.0 */ - IOsOverrides getLinuxOverrides(); + String getCleanTarget(); /** - * Gets the override/augmenting properties to apply when the build runs on windows. + * @param cleanTarget The target to pass to {@code --target} CMake command line option, used when user asks to clean a project. + * @since 2.0 */ - IOsOverrides getWindowsOverrides(); + void setCleanTarget(String cleanTarget); /** - * Sets each property to its default value. This is intended for UIs that wish to implement a restore-defaults feature.
- * - * @param resetOsOverrides - * whether to also reset the OS-specific overrides ({@link #getLinuxOverrides()}, - * {@link #getWindowsOverrides()}). If the overrides are displayed in separate tabs in the UI, false - * should be specified. + * The target to pass to {@code --target} CMake command line option, used when user asks to build a project. + * @since 2.0 */ - void reset(boolean resetOsOverrides); + 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.core/src/org/eclipse/cdt/cmake/core/properties/ICMakePropertiesController.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakePropertiesController.java deleted file mode 100644 index 09a6e717fee..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/ICMakePropertiesController.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.properties; - -import java.io.IOException; - -/** - * Responsible for loading and persisting {@code ICMakeProperties} objects. - * - * @author Martin Weber - * @since 1.4 - */ -public interface ICMakePropertiesController { - - /** Creates a new {@code ICMakeProperties} object, initialized from the persistence store. - * If the persistence store does not exist, an object initialized to the default values is returned. - * - * @throws IOException if the persistence store exists but could not be read - */ - ICMakeProperties load() throws IOException; - - /** Saves the specified {@code ICMakeProperties} object to the persistence store. - * - * @throws IOException if the persistence store could not be written to - */ - void save(ICMakeProperties properties) throws IOException; -} diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IGeneralProperties.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IGeneralProperties.java deleted file mode 100644 index cfb15021c0c..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IGeneralProperties.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.properties; - -/** - * General, non-cmake related project settings. - * - * @author Martin Weber - * - * @noimplement This interface is not intended to be implemented by clients. - * @noextend This interface is not intended to be extended by clients. - * @since 1.4 - */ -public interface IGeneralProperties { - - /** - * Gets the name of the top-level directory relative to the project root. - */ - String getSourceDirectory(); - - /** - * Sets the name of the top-level directory relative to the project root. - */ - void setSourceDirectory(String sourceDirectory); - - /** - * Gets the name of the build directory. - */ - String getBuildDirectory(); - - /** - * Sets the name of the build directory. - */ - void setBuildDirectory(String buildDirectory); -} \ No newline at end of file diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IOsOverrides.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IOsOverrides.java deleted file mode 100644 index 37f4dfe801b..00000000000 --- a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/IOsOverrides.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Martin Weber. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.cdt.cmake.core.properties; - -import java.util.List; - -/** - * Properties that override/augment the generic properties when running under/building for a - * specific OS. - * - * @author Martin Weber - * @since 1.4 - */ -public interface IOsOverrides { - - /** - * Gets whether to use the default cmake command. - */ - boolean getUseDefaultCommand(); - - /** - * Sets whether to use the default cmake command. - */ - void setUseDefaultCommand(boolean useDefaultCommand); - - /** - * Gets the cmake command. Has no effect if {@link #getUseDefaultCommand()} returns false. - */ - String getCommand(); - - /** - * Sets the cmake command. - */ - void setCommand(String command); - - /** - * Gets the cmake buildscript generator. - */ - CMakeGenerator getGenerator(); - - /** - * Sets the cmake build-script generator. - */ - void setGenerator(CMakeGenerator generator); - - /** - * Gets the list of extra arguments to pass on the cmake command-line. - * - * @return an unmodifiable list, never {@code null} - */ - List getExtraArguments(); - - /** - * Sets the list of extra arguments to pass on the cmake command-line. - */ - void setExtraArguments(List extraArguments); -} \ 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 6bf274dc316..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 @@ -10,8 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.cmake.example; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.runtime.CoreException; @@ -34,5 +38,14 @@ public ExtendedCMakeBuildConfiguration(IBuildConfiguration config, String name, super(config, name, toolChain); } - // TODO: Here goes the example extending that is being developed in #1046 https://github.com/eclipse-cdt/cdt/pull/1046 -} \ No newline at end of file + @Override + 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()); + 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..55d54e2c8ad 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; @@ -33,20 +35,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 +66,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 +108,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); - cleanCommandText = new Text(cmakeGroup, SWT.BORDER); - cleanCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - cleanCommandText.addModifyListener(e -> updateLaunchConfigurationDialog()); + 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); + + 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, + CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS_DEFAULT); } @Override @@ -154,51 +164,27 @@ public void initializeFrom(ILaunchConfiguration configuration) { ICBuildConfiguration buildConfig = getBuildConfiguration(); - String generator = buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_GENERATOR); - updateGeneratorButtons(generator); - - String cmakeArgs = buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_ARGUMENTS); - if (cmakeArgs != null) { - cmakeArgsText.setText(cmakeArgs); - } else { - cmakeArgsText.setText(""); //$NON-NLS-1$ - } + boolean isDefaultCMakeProperties = Boolean + .valueOf(buildConfig.getProperty(CMakeBuildConfiguration.CMAKE_USE_DEFAULT_CMAKE_SETTINGS)); + useDefaultCmakeSettings.setSelection(isDefaultCMakeProperties); - String buildCommand = buildConfig.getProperty(CMakeBuildConfiguration.BUILD_COMMAND); - if (buildCommand != null) { - buildCommandText.setText(buildCommand); + if (isDefaultCMakeProperties) { + restoreProperties(buildConfig.getDefaultProperties()); } else { - buildCommandText.setText(""); //$NON-NLS-1$ + restoreProperties(buildConfig.getProperties()); } - 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 +195,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..674bd2205ae 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 toolchain and Core Build System CMakePreferencePage_Add=Add... CMakePreferencePage_ConfirmRemoveDesc=Do you wish to deregister the selected files? CMakePreferencePage_ConfirmRemoveTitle=Deregister CMake ToolChain File