Skip to content

Commit

Permalink
Improve CMake build option handling and API (#1046)
Browse files Browse the repository at this point in the history
Summary:

- Add some new API to make it easier for ISVs to provide defaults.
- Fully connect UI elements to CMake build process
- Add some missing UI elements (such as customizing generator)
- CMake generator default within CDT changed to Ninja

Details:

Add API to set CMake generator default (eg Ninja) ISV can set
their desired CMake generator by overriding
`CMakeBuildConfiguration.getDefaultProperties`. ISVs can also further
fine tune the build process by overriding
`CMakeBuildConfiguration.getDefaultProperties`

Remove API `IOsOverrides` and related code. `IOsOverrides` was a partial
implementation to achieve builds in Docker containers, however the
work was not complete and it the extra code was complicating some
basic use cases of setting defaults

Add support for all generators to CMake build settings UI page by
using a Combo instead of radio buttons. The non-deprecated generators
that are built-in to CDT populate the Combo, but additional generators
can be manually entered in the Combo.

Rename clean command to clean target to better reflect its use as
the argument passed to cmake's --target command line.

Add all target for the argument passed to cmake's --target
command line when doing a normal build.

Clarify usage of UI overrides and change the UI to be "use defaults"
(i.e. invert the checkbox). This is a **breaking** change as it means
user projects that were using UI overrides will revert to using defaults.
This is done on purpose as so many little things have changed in CMake
settings, that reverting to defaults on upgrade seems like a logical
decision. In addition *use defaults* matches the other GUIs in Eclipse,
for example the MBS build command settings.

Populate all defaults in getDefaultProperties() so that all CMake build
settings are displayed as used (greyed out) and can be used as a starting
point when editing settings.

Simplify some of the code in CMakeBuildTab.

Fix parsing of extra args so that quoted strings work.

Refactored manual tests document and brought it up to date.

Correct command line option for CMake's --warn-unused-vars

Correct command line option for CMake's --warn-uninitialized

Overall this is an API breaking change and the CHANGELOG-API.md has been
updated with all the API changes in and around ICMakeProperties,
including fixing typos in WarnUninitialized methods.

Fixes #1055
Fixes #818
Part of #1000

Co-authored-by: Jonah Graham <jonah@kichwacoders.com>
betamaxbandit and jonahgraham authored Jan 27, 2025
1 parent 11dfaa4 commit fe74d8d
Showing 30 changed files with 921 additions and 1,154 deletions.
15 changes: 15 additions & 0 deletions NewAndNoteworthy/CDT-12.0.md
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions NewAndNoteworthy/CHANGELOG-API.md
Original file line number Diff line number Diff line change
@@ -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
7 changes: 5 additions & 2 deletions cmake/org.eclipse.cdt.cmake.core.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -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)"

Original file line number Diff line number Diff line change
@@ -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<String> 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<String, String> 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<String, String> 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<String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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;
}
}

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion cmake/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -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,
Original file line number Diff line number Diff line change
@@ -12,31 +12,25 @@

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;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.eclipse.cdt.cmake.core.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<IResource, IScannerInfo> 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<String, String> 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<String> 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<String, String> 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<String, String> 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<String, String> args, IConsole console, IP
}
}

CommandDescriptor commandDescr = cmdBuilder.makeCMakeBuildCommandline("all"); //$NON-NLS-1$
CommandDescriptor commandDescr = cmdBuilder.makeCMakeBuildCommandline(cmakeProperties.getAllTarget());
List<String> command = commandDescr.getArguments();
infoStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$

@@ -279,34 +299,16 @@ public IProject[] build(int kind, Map<String, String> args, IConsole console, IP
}
}

/**
* When UI overrides are in force, gets the user specified clean target (if not blank), otherwise the default clean target.
* @return Always a non-null String indicating the clean target.
*/
private String getCleanCommand() {
String retVal = CLEAN_COMMAND_DEFAULT;
Preferences settings = this.getSettings();
boolean useUiOverrides = settings.getBoolean(CMAKE_USE_UI_OVERRIDES, CMAKE_USE_UI_OVERRIDES_DEFAULT);
if (useUiOverrides) {
String cleanCommand = settings.get(CLEAN_COMMAND, CLEAN_COMMAND_DEFAULT);
if (!cleanCommand.isBlank()) {
retVal = cleanCommand;
}
}
return retVal;
}

@Override
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
try {

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<Path> 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> T getAdapter(Class<T> 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 <code>null</code> 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<String, String> 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<String, String> getProperties() {
var map = new HashMap<String, String>();
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<String> extraArgs = Arrays.stream(extraArgsStr.split("\\s+")).map(entry -> entry.trim()) //$NON-NLS-1$
.collect(Collectors.toList());
retVal.setExtraArguments(extraArgs);
// Set UI override for cmake build command, unless it's the default
String buildCommand = settings.get(BUILD_COMMAND, BUILD_COMMAND_DEFAULT);
if (!buildCommand.isBlank() && !BUILD_COMMAND_DEFAULT.equals(buildCommand)) {
retVal.setUseDefaultCommand(false);
retVal.setCommand(buildCommand);
}
}
return retVal;
}
} // SimpleOsOverridesSelector
@Override
public String getProperty(String name) {
return getSettings().get(name, getDefaultProperties().get(name));
}
}
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@
* See the example project <a href="https://github.com/eclipse-cdt/cdt/tree/main/cmake/org.eclipse.cdt.cmake.example">
* org.eclipse.cdt.cmake.example</a> for a full example.
*
* @since 1.6
* @since 2.0
*/
public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProvider {

Original file line number Diff line number Diff line change
@@ -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.
* <p>
* 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();
}
Original file line number Diff line number Diff line change
@@ -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$

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<String> args = new ArrayList<>();
List<String> 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,18 +65,17 @@ 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())) {
args.add("-C"); //$NON-NLS-1$
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<String> args = new ArrayList<>();
List<String> 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<String> argList, final List<String
}
}

/**
* Appends arguments specific to the given OS preferences for build-script generation. The first
* argument in the list will be replaced by the cmake command from the specified preferences, if
* given.
*
* @param args the list to append cmake-arguments to.
* @param prefs the generic OS specific cmake build properties to convert and append.
* @throws CoreException if unable to resolve the value of one or more variables
*/
private static void appendCMakeOsOverrideArgs(List<String> 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

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<String> 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<String> 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;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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();

}
Original file line number Diff line number Diff line change
@@ -23,6 +23,29 @@
* @since 1.4
*/
public interface ICMakeProperties {
/**
* Gets the cmake command. Has no effect if {@link #getUseDefaultCommand()} returns <code>false</code>.
* @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.<br>
*
* @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, <code>false</code>
* 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);

}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
}
@Override
public Map<String, String> 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;
}
}
85 changes: 85 additions & 0 deletions cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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<String, String> 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<String, String> 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<String, String> 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
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fe74d8d

Please sign in to comment.