From c8d0797265ffea2b7242422600b29f9134541a8a Mon Sep 17 00:00:00 2001 From: John Moule Date: Fri, 17 Jan 2025 17:53:42 +0000 Subject: [PATCH] Add API to set CMake generator default (eg Ninja) ISV can set their desired CMake generator default (eg Ninja). Addresses Issue: CDT CMake Improvements #1000, IDE-82683-REQ-012 CMake generator default --- .../META-INF/MANIFEST.MF | 2 +- .../cmake/core/CMakeBuildConfiguration.java | 61 ++++++++++++++----- .../cmake/core/ICMakeBuildConfiguration.java | 18 ++++++ .../org/eclipse/cdt/cmake/core/Messages.java | 2 +- .../internal/CMakePropertiesController.java | 27 ++++++++ .../properties/CMakePropertiesBean.java | 2 + .../properties/AbstractOsOverrides.java | 14 +++-- .../properties/CMakePropertiesFactory.java | 9 +++ .../ICMakePropertiesController.java | 9 +++ .../cmake/core/properties/IOsOverrides.java | 7 +++ .../properties/LinuxOverrides.java | 7 +-- .../properties/WindowsOverrides.java | 12 ++-- 12 files changed, 137 insertions(+), 33 deletions(-) create mode 100644 cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeBuildConfiguration.java rename cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/{internal => }/properties/AbstractOsOverrides.java (88%) create mode 100644 cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java rename cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/{internal => }/properties/LinuxOverrides.java (84%) rename cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/{internal => }/properties/WindowsOverrides.java (71%) 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..fe7f365c83d 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 @@ -34,6 +34,7 @@ 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.ICMakeProperties; import org.eclipse.cdt.cmake.core.properties.ICMakePropertiesController; import org.eclipse.cdt.cmake.core.properties.IOsOverrides; @@ -72,10 +73,11 @@ import org.osgi.service.prefs.Preferences; /** - * @since 1.6 + * @since 2.0 */ -public class CMakeBuildConfiguration extends CBuildConfiguration { +public class CMakeBuildConfiguration extends CBuildConfiguration implements ICMakeBuildConfiguration { + private static final String CMAKE_PROPERTIES_INITIALSED = "cmake.properties.initialised"; //$NON-NLS-1$ 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$ @@ -91,6 +93,8 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { // lazily instantiated.. private ICMakePropertiesController pc; + ICMakeProperties defaultProperties; + private Map infoPerResource; /** * whether one of the CMakeLists.txt files in the project has been modified and saved by the @@ -112,6 +116,7 @@ public CMakeBuildConfiguration(IBuildConfiguration config, String name) throws C ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class); toolChainFile = manager.getToolChainFileFor(getToolChain()); + setDefaultCMakeProperties(); } public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) { @@ -122,6 +127,30 @@ public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolCha ICMakeToolChainFile toolChainFile, String launchMode) { super(config, name, toolChain, launchMode); this.toolChainFile = toolChainFile; + // // moule + setDefaultCMakeProperties(); + } + + private void setDefaultCMakeProperties() { + // Only set defaults on initial construction + if (getProperty(CMAKE_PROPERTIES_INITIALSED) == null) { + ICMakeProperties properties = CMakePropertiesFactory.getProperties(); + IOsOverrides windowsOverrides = properties.getWindowsOverrides(); + windowsOverrides.setDefaultGenerator(CMakeGenerator.UnixMakefiles); + + IOsOverrides linuxOverrides = properties.getLinuxOverrides(); + linuxOverrides.setDefaultGenerator(CMakeGenerator.UnixMakefiles); + // reset(true) causes the CMake generator to be reset to it's default value. + properties.reset(true); + setDefaultCMakeProperties(properties); + } + } + + @Override + public void setDefaultCMakeProperties(ICMakeProperties defaultProperties) { + this.defaultProperties = defaultProperties; + setProperty(CMAKE_GENERATOR, getOsOverrides(defaultProperties).getGenerator().getCMakeName()); + setProperty(CMAKE_PROPERTIES_INITIALSED, Boolean.TRUE.toString()); } /** @@ -162,7 +191,8 @@ public IProject[] build(int kind, Map args, IConsole console, IP runCMake = true; } - ICMakeProperties cmakeProperties = getPropertiesController().load(); + // ICMakeProperties cmakeProperties = getPropertiesController().load(); + ICMakeProperties cmakeProperties = getPropertiesController().load(defaultProperties); runCMake |= !Files.exists(buildDir.resolve("CMakeCache.txt")); //$NON-NLS-1$ // Causes CMAKE_BUILD_TYPE to be set according to the launch mode @@ -303,7 +333,8 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); - ICMakeProperties cmakeProperties = getPropertiesController().load(); + // ICMakeProperties cmakeProperties = getPropertiesController().load(); + ICMakeProperties cmakeProperties = getPropertiesController().load(defaultProperties); CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties, new SimpleOsOverridesSelector()); CommandDescriptor command = cmdBuilder.makeCMakeBuildCommandline(getCleanCommand()); @@ -405,7 +436,8 @@ private ICMakePropertiesController getPropertiesController() { @SuppressWarnings("unchecked") public T getAdapter(Class adapter) { if (ICMakePropertiesController.class.equals(adapter)) { - return (T) pc; + // return (T) pc; + return (T) getPropertiesController(); } return super.getAdapter(adapter); } @@ -582,6 +614,15 @@ public void shutdown() { } } // CMakeIndexerInfoConsumer + private IOsOverrides getOsOverrides(ICMakeProperties cmakeProperties) { + if (Platform.OS_WIN32.equals(Platform.getOS())) { + return cmakeProperties.getWindowsOverrides(); + + } else { + return cmakeProperties.getLinuxOverrides(); + } + } + /** * 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()) @@ -591,17 +632,9 @@ private class SimpleOsOverridesSelector implements IOsOverridesSelector { @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); + return getUiOrOsOverrides(getOsOverrides(cmakeProperties)); } private IOsOverrides getUiOrOsOverrides(IOsOverrides osOverrides) { 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..5769704217e --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeBuildConfiguration.java @@ -0,0 +1,18 @@ +package org.eclipse.cdt.cmake.core; + +import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; +import org.eclipse.cdt.core.build.ICBuildConfiguration; + +/** + * @since 2.0 + */ +public interface ICMakeBuildConfiguration { + /** + * Provides a CBuildConfiguration with a set of default CMake properties. The ICMakeProperties can then, for + * example, provide a default value for the CMake generator. + * The CMake generator can then be set using {@link ICBuildConfiguration#setProperty(String, String)}, using + * {@link CMakeBuildConfiguration#CMAKE_GENERATOR}. The CMake generator property can then be accessed using + * the {@link ICBuildConfiguration#getProperty(String)}. + */ + void setDefaultCMakeProperties(ICMakeProperties defaultProperties); +} 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 index f857357b490..9af93a57e82 100644 --- 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 @@ -93,6 +93,32 @@ public ICMakeProperties load() throws IOException { return props; } + @Override + public ICMakeProperties load(ICMakeProperties defaults) throws IOException { + ICMakeProperties 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 = defaults; + } + + 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 @@ -158,4 +184,5 @@ private boolean hasExtraArgumentChanged(List expected, List actu } return false; } + } \ 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..4ac566fece9 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 @@ -15,6 +15,8 @@ import java.util.List; import org.eclipse.cdt.cmake.core.properties.ICMakeProperties; +import org.eclipse.cdt.cmake.core.properties.LinuxOverrides; +import org.eclipse.cdt.cmake.core.properties.WindowsOverrides; /** * Holds project Properties for cmake. Follows the Java-Beans pattern to make (de-)serialization easier. 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/properties/AbstractOsOverrides.java similarity index 88% rename from cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/AbstractOsOverrides.java rename to cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/AbstractOsOverrides.java index 8d5909c74d5..b6dce2d4aed 100644 --- 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/properties/AbstractOsOverrides.java @@ -9,21 +9,20 @@ * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ -package org.eclipse.cdt.cmake.core.internal.properties; +package org.eclipse.cdt.cmake.core.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 + * @since 2.0 */ public abstract class AbstractOsOverrides implements IOsOverrides { @@ -31,6 +30,7 @@ public abstract class AbstractOsOverrides implements IOsOverrides { private boolean useDefaultCommand; private CMakeGenerator generator; private List extraArguments = new ArrayList<>(0); + private CMakeGenerator defaultGenerator = CMakeGenerator.Ninja; /** * Creates a new object, initialized with all default values. @@ -45,7 +45,7 @@ public AbstractOsOverrides() { public void reset() { setCommand(CMakeBuildConfiguration.BUILD_COMMAND_DEFAULT); useDefaultCommand = true; - setGenerator(CMakeGenerator.UnixMakefiles); + setGenerator(defaultGenerator); extraArguments.clear(); } @@ -89,4 +89,8 @@ public void setExtraArguments(List extraArguments) { this.extraArguments = extraArguments; } -} \ No newline at end of file + @Override + public void setDefaultGenerator(CMakeGenerator defaultGenerator) { + this.defaultGenerator = defaultGenerator; + } +} diff --git a/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java new file mode 100644 index 00000000000..5d679ded86f --- /dev/null +++ b/cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/CMakePropertiesFactory.java @@ -0,0 +1,9 @@ +package org.eclipse.cdt.cmake.core.properties; + +import org.eclipse.cdt.cmake.core.internal.properties.CMakePropertiesBean; + +public class CMakePropertiesFactory { + public static ICMakeProperties getProperties() { + return new CMakePropertiesBean(); + } +} 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 index 09a6e717fee..cb0fb13a928 100644 --- 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 @@ -26,8 +26,17 @@ public interface ICMakePropertiesController { * * @throws IOException if the persistence store exists but could not be read */ + @Deprecated ICMakeProperties load() throws IOException; + /** 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 + * @since 2.0 + */ + ICMakeProperties load(ICMakeProperties defaults) throws IOException; + /** Saves the specified {@code ICMakeProperties} object to the persistence store. * * @throws IOException if the persistence store could not be written to 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 index 37f4dfe801b..e4aba9d7f82 100644 --- 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 @@ -63,4 +63,11 @@ public interface IOsOverrides { * Sets the list of extra arguments to pass on the cmake command-line. */ void setExtraArguments(List extraArguments); + + /** + * Sets a value that is used when a {@link ICMakeProperties#reset(true)} call is performed, setting the value + * of the CMake generator (see {@link #getGenerator()}) to it's default value. + * @since 2.0 + */ + void setDefaultGenerator(CMakeGenerator defaultGenerator); } \ No newline at end of file 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/LinuxOverrides.java similarity index 84% 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/LinuxOverrides.java index d07699089d1..55c842dfb76 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/LinuxOverrides.java @@ -9,19 +9,18 @@ * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ -package org.eclipse.cdt.cmake.core.internal.properties; +package org.eclipse.cdt.cmake.core.properties; /** * 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() { + super(); } } 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/properties/WindowsOverrides.java similarity index 71% rename from cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/properties/WindowsOverrides.java rename to cmake/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/properties/WindowsOverrides.java index 4e79f113d70..939df6450f4 100644 --- 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/properties/WindowsOverrides.java @@ -9,22 +9,18 @@ * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ -package org.eclipse.cdt.cmake.core.internal.properties; - -import org.eclipse.cdt.cmake.core.properties.CMakeGenerator; +package org.eclipse.cdt.cmake.core.properties; /** * Preferences that override/augment the generic properties when running under * Windows. * * @author Martin Weber + * @since 2.0 */ public class WindowsOverrides extends AbstractOsOverrides { - /** Overridden to set a sensible generator. */ - @Override - public void reset() { - super.reset(); - setGenerator(CMakeGenerator.MinGWMakefiles); + public WindowsOverrides() { + super(); } }