Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Expand Up @@ -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: 2.0.200.qualifier
Bundle-Version: 2.1.0.qualifier
Bundle-Activator: org.eclipse.cdt.cmake.core.internal.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.34.0,4.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.cdt.cmake.core.properties.CMakePropertiesFactory;
import org.eclipse.cdt.cmake.core.properties.ICMakeGenerator;
import org.eclipse.cdt.cmake.core.properties.ICMakeProperties;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncherManager;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
Expand Down Expand Up @@ -60,8 +61,11 @@
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.launchbar.core.target.ILaunchTarget;
Expand Down Expand Up @@ -195,50 +199,14 @@ public IProject[] build(int kind, Map<String, String> args, IConsole console, IP
}
CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties);
if (runCMake) {
CMakeBuildConfiguration.deleteCMakeErrorMarkers(project);

infoStream.write(String.format(Messages.CMakeBuildConfiguration_Configuring, buildDir));
CommandDescriptor command = cmdBuilder
.makeCMakeCommandline(toolChainFile != null ? toolChainFile.getPath() : null);
// tell cmake where its script is located..
IContainer srcFolder = project;
command.getArguments().add(new File(srcFolder.getLocationURI()).getAbsolutePath());

infoStream.write(String.join(" ", command.getArguments()) + '\n'); //$NON-NLS-1$

org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(
getBuildDirectory().toString());
// hook in cmake error parsing
try (CMakeErrorParser errorParser = new CMakeErrorParser(new CMakeExecutionMarkerFactory(srcFolder))) {
ParsingConsoleOutputStream errStream = new ParsingConsoleOutputStream(console.getErrorStream(),
errorParser);
IConsole errConsole = new CMakeConsoleWrapper(console, errStream);
Process p = startBuildProcess(command.getArguments(), new IEnvironmentVariable[0], workingDir,
errConsole, monitor);
String arg0 = command.getArguments().get(0);
if (p == null) {
// process start failed
String msg = String.format(Messages.CMakeBuildConfiguration_Failure, ""); //$NON-NLS-1$
addMarker(new ProblemMarkerInfo(srcFolder.getProject(), -1, msg,
IMarkerGenerator.SEVERITY_ERROR_BUILD, null, new org.eclipse.core.runtime.Path(arg0)));
return null;
}

// check cmake exit status
final int exitValue = watchProcess(errConsole, monitor);
if (exitValue != 0) {
// cmake had errors...
String msg = String.format(Messages.CMakeBuildConfiguration_ExitFailure, arg0, exitValue);
addMarker(srcFolder.getProject(), -1, msg, IMarkerGenerator.SEVERITY_ERROR_BUILD, null);
return null;
}
IStatus result = configureCMakeBuildFiles(cmdBuilder, console, infoStream, monitor);
Comment thread
betamaxbandit marked this conversation as resolved.
if (!result.isOK()) {
return null;
}
cmakeListsModified = false;
}

// parse compile_commands.json file
getCompileCommandsFile().refreshLocal(IResource.DEPTH_ZERO, monitor);
processCompileCommandsFile(console, monitor);
refreshAndProcessCompileCommandsFile(console, monitor);

infoStream.write(String.format(Messages.CMakeBuildConfiguration_BuildingIn, buildDir.toString()));
// run the build tool...
Expand Down Expand Up @@ -296,6 +264,89 @@ public IProject[] build(int kind, Map<String, String> args, IConsole console, IP
}
}

/**
* Runs the CMake configure step for this build configuration without invoking
* the build target. On success, refreshes and processes compile_commands.json
* so scanner information is updated.
* <p>
* This method writes to the CDT build console, deletes stale CMake execution
* markers, may create new CMake execution markers, and updates scanner
* information for this build configuration.
* <p>
* Callers should run this from a background workspace operation, not directly
* from the UI thread.
*
* @param monitor progress monitor, or {@code null}
* @return {@link Status#OK_STATUS} if CMake completed successfully; otherwise
* an error status if the CMake process could not be started or exited
* non-zero
* @throws CoreException if workspace refresh, marker handling, or scanner-info
* processing fails
* @throws IOException if console/process I/O fails
* @since 2.1
*/
Comment thread
betamaxbandit marked this conversation as resolved.
public IStatus configureCMakeBuildFiles(IProgressMonitor monitor) throws CoreException, IOException {
// Setup console
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(getProject());
ICMakeProperties cmakeProperties = getCMakeProperties();
CommandDescriptorBuilder cmdBuilder = new CommandDescriptorBuilder(cmakeProperties);
SubMonitor subMonitor = SubMonitor.convert(monitor, 2);
IStatus result = configureCMakeBuildFiles(cmdBuilder, console, console.getInfoStream(), subMonitor.split(1));
refreshAndProcessCompileCommandsFile(console, subMonitor.split(1));
return result;
}

private IStatus configureCMakeBuildFiles(CommandDescriptorBuilder cmdBuilder, IConsole console,
ConsoleOutputStream infoStream, IProgressMonitor monitor) throws CoreException, IOException {
SubMonitor subMonitor = SubMonitor.convert(monitor, 4);
CMakeBuildConfiguration.deleteCMakeErrorMarkers(getProject());
infoStream.write(String.format(Messages.CMakeBuildConfiguration_Configuring, getBuildDirectory()));
CommandDescriptor command = cmdBuilder
.makeCMakeCommandline(toolChainFile != null ? toolChainFile.getPath() : null);
// tell cmake where its script is located..
IContainer srcFolder = getProject();
command.getArguments().add(new File(srcFolder.getLocationURI()).getAbsolutePath());

infoStream.write(String.join(" ", command.getArguments()) + '\n'); //$NON-NLS-1$

org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(getBuildDirectory().toString());
// hook in cmake error parsing
try (CMakeErrorParser errorParser = new CMakeErrorParser(new CMakeExecutionMarkerFactory(srcFolder))) {
ParsingConsoleOutputStream errStream = new ParsingConsoleOutputStream(console.getErrorStream(),
errorParser);
IConsole errConsole = new CMakeConsoleWrapper(console, errStream);
Process p = startBuildProcess(command.getArguments(), new IEnvironmentVariable[0], workingDir, errConsole,
subMonitor.split(1));
String arg0 = command.getArguments().get(0);
if (p == null) {
// process start failed
String msg = String.format(Messages.CMakeBuildConfiguration_Failure, "Process failed to start"); //$NON-NLS-1$
addMarker(new ProblemMarkerInfo(srcFolder.getProject(), -1, msg, IMarkerGenerator.SEVERITY_ERROR_BUILD,
null, new org.eclipse.core.runtime.Path(arg0)));
return Status.error(msg);
}
// check cmake exit status
final int exitValue = watchProcess(errConsole, subMonitor.split(1));
if (exitValue != 0) {
// cmake had errors...
String msg = String.format(Messages.CMakeBuildConfiguration_ExitFailure, arg0, exitValue);
addMarker(srcFolder.getProject(), -1, msg, IMarkerGenerator.SEVERITY_ERROR_BUILD, null);
return Status.error(msg);
}
}
cmakeListsModified = false;
return Status.OK_STATUS;
}

/**
* Parse compile_commands.json file
*/
private void refreshAndProcessCompileCommandsFile(IConsole console, IProgressMonitor monitor) throws CoreException {
getCompileCommandsFile().refreshLocal(IResource.DEPTH_ZERO, monitor);
processCompileCommandsFile(console, monitor);
}

@Override
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
Expand Down
7 changes: 5 additions & 2 deletions cmake/org.eclipse.cdt.cmake.example/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.cmake.example;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 1.0.100.qualifier
Export-Package: org.eclipse.cdt.cmake.example;x-internal:=true
Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: JavaSE-17
Expand All @@ -17,7 +17,10 @@ Require-Bundle: org.eclipse.cdt.cmake.core,
org.eclipse.tools.templates.freemarker,
org.eclipse.ui,
org.eclipse.ui.ide,
org.eclipse.launchbar.core;bundle-version="[3.0.0,4.0.0)"
org.eclipse.launchbar.core;bundle-version="[3.0.0,4.0.0)",
org.eclipse.cdt.debug.core;bundle-version="[9.0.0,10.0.0)",
org.eclipse.debug.core;bundle-version="[3.24.0,4.0.0)",
org.eclipse.cdt.launch;bundle-version="[11.0.0,12.0.0)"
Import-Package: freemarker.template;version="[2.3.22,3.0.0)"
Automatic-Module-Name: org.eclipse.cdt.cmake.example
Bundle-Localization: plugin
44 changes: 44 additions & 0 deletions cmake/org.eclipse.cdt.cmake.example/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,48 @@
</tagReference>
</template>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
<command
commandId="org.eclipse.cdt.cmake.example.configureCMakeProject"
label="Configure CMake Project"
style="push"
tooltip="Start CMake configuration">
<visibleWhen
checkEnabled="true">
<with
variable="activeMenuSelection">
<and>
<count
value="1">
</count>
<iterate
ifEmpty="false">
<adapt
type="org.eclipse.core.resources.IProject">
<test
forcePluginActivation="true"
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.cdt.cmake.core.cmakeNature">
</test>
</adapt>
</iterate>
</and>
</with>
</visibleWhen>
</command>
</menuContribution>
</extension>
<extension
id="org.eclipse.cdt.cmake.example.configureCMake"
name="Configure CMake Project"
point="org.eclipse.ui.commands">
<command
defaultHandler="org.eclipse.cdt.cmake.example.handler.ConfigureCMakeProjectHandler"
id="org.eclipse.cdt.cmake.example.configureCMakeProject"
name="Configure CMake Project">
</command>
</extension>
</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class Messages extends NLS {
public static String NewExtendedCMakeProjectWizard_PageTitle;
public static String NewExtendedCMakeProjectWizard_WindowTitle;

public static String ConfigureCMakeProjectHandler_ConfigError;

static {
// initialize resource bundle
NLS.initializeMessages("org.eclipse.cdt.cmake.example.messages", Messages.class); //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright (c) 2026 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.example.handler;

import java.io.IOException;
import java.text.MessageFormat;

import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration;
import org.eclipse.cdt.cmake.example.Messages;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.launch.LaunchUtils;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.launchbar.core.ILaunchBarManager;

public class ConfigureCMakeProjectHandler extends AbstractHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ICBuildConfigurationManager configManager = CDebugCorePlugin.getService(ICBuildConfigurationManager.class);
ILaunchBarManager launchBarManager = CDebugCorePlugin.getService(ILaunchBarManager.class);
try {
ILaunchConfiguration activeLaunchConfiguration;
activeLaunchConfiguration = launchBarManager.getActiveLaunchConfiguration();
IProject project = LaunchUtils.getProject(activeLaunchConfiguration);
ICBuildConfiguration buildConfig = configManager.getBuildConfiguration(project.getActiveBuildConfig());
if (buildConfig instanceof CMakeBuildConfiguration cbc) {
WorkspaceJob job = new WorkspaceJob("Configuring CMake Project...") { //$NON-NLS-1$
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try {
return cbc.configureCMakeBuildFiles(monitor);
} catch (CoreException | IOException e) {
return Status.error(MessageFormat.format(Messages.ConfigureCMakeProjectHandler_ConfigError,
project.getName()), e);
}
}
};
job.setRule(project);
job.schedule();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job modifies project state: markers, resource refresh, and scanner information. Should it set a scheduling rule before scheduling, probably the project, to avoid running concurrently with other workspace operations on the same project?
Suggestion ...

job.setRule(project);
job.schedule();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm with you on this one.

I'm not quite sure if there's another WS job running during CMake configuration process, so I'll play it safe here and set rule to it as suggested.

}
} catch (CoreException e) {
ILog.of(getClass()).error("Error getting CBuildConfiguration", e); //$NON-NLS-1$
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NewExtendedCMakeProjectWizard_WindowTitle=New CMake Project
NewExtendedCMakeProjectWizard_PageTitle=New CMake Project
NewExtendedCMakeProjectWizard_Description=Specify properties of new CMake project.
ConfigureCMakeProjectHandler_ConfigError=Failed to perform CMake configuration for project {0}
10 changes: 10 additions & 0 deletions cmake/org.eclipse.cdt.cmake.ui.tests/manualTests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ Note, the Build Settings tab settings are stored separately for Run mode and Deb
#### 8.1) Perform build, clean and open build settings
Expected: Settings are persisted

### 9) CMake configuration

Verifies that the API for configuring CMake can be invoked independently.
Note: this API can only be tested in a CDT development environment that includes the **org.eclipse.cdt.cmake.example** plug-in.

1. Remove any existing **/build/** folder.
2. Right-click the project and select Configure CMake Project.

Expected: The CMake configuration process starts using the active launch settings.

## 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.
Expand Down
Loading