From 591e99e68bb743f808302d1164575f74ab517aae Mon Sep 17 00:00:00 2001 From: ewaterlander <102143930+ewaterlander@users.noreply.github.com> Date: Thu, 26 Jun 2025 11:44:26 +0100 Subject: [PATCH] Build not configured correctly (#1201) Under some circumstances it can happen that a BuildConfiguration is registered in the CBuildConfigurationManger as both a valid and invalid ICBuildConfiguration counterpart. This results in a "Build not configured correctly" error when trying to build a CoreBuild project. This change removes valid build configurations from the invalid list before looking for the counterpart. Fixes #1193 --- .../CBuildConfigurationManagerTests.java | 39 +++++++++++++++++++ .../org.eclipse.cdt.core/META-INF/MANIFEST.MF | 2 +- .../build/CBuildConfigurationManager.java | 6 +++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/CBuildConfigurationManagerTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/CBuildConfigurationManagerTests.java index cb523ee6d3d..ba26b8bc1f1 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/CBuildConfigurationManagerTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/build/CBuildConfigurationManagerTests.java @@ -11,11 +11,14 @@ package org.eclipse.cdt.core.build; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import org.eclipse.cdt.cmake.core.CMakeBuildConfiguration; import org.eclipse.cdt.cmake.core.CMakeBuildConfigurationProvider; import org.eclipse.cdt.cmake.core.CMakeNature; import org.eclipse.cdt.core.CCProjectNature; @@ -26,6 +29,7 @@ import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase5; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchBarTracker; +import org.eclipse.cdt.internal.core.build.CBuildConfigurationManager; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsScannerInfoProvider; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; @@ -139,6 +143,41 @@ public class CBuildConfigurationManagerTests extends BaseTestCase5 { scannerInfoProvider instanceof ICBuildConfiguration); } + /** + * Test {@link CBuildConfigurationManager#getBuildConfiguration(IBuildConfiguration buildConfig)} + * IBuildConfigurations with a valid ICBuildConfiguration counterpart will be removed from + * the CBuildConfigurationManager.noConfigs Set. + */ + @Test + public void testNoConfigs() throws Exception { + // create a CMake project; performed in setup() + + // Create a new IBuildConfiguration. + CMakeBuildConfigurationProvider provider = new CMakeBuildConfigurationProvider(); + String buildConfigBaseName = "testNoConfigs"; + IBuildConfiguration buildConfiguration = configManager.createBuildConfiguration(provider, project, + buildConfigBaseName, new NullProgressMonitor()); + + // Create a new ICBuildConfiguration. + String buildConfigName = provider.getId() + "/" + buildConfigBaseName; + ILaunchTarget launchTarget = launchTargetManager.getLocalLaunchTarget(); + ICBuildConfiguration cBuildConfig = new CMakeBuildConfiguration(buildConfiguration, buildConfigName, + mockToolchain, null, ILaunchManager.RUN_MODE, launchTarget); + + // Try to get ICBuildConfiguration, before the IBuildConfiguration/ICBuildConfiguration pair was + // added to the build configuration manager. Such a getAdapter() call could happen in a parallel + // process. It will fail and buildConfiguration will be placed in configManager.noConfigs + ICBuildConfiguration cbConfig = buildConfiguration.getAdapter(ICBuildConfiguration.class); + assertThat(cbConfig, is(nullValue())); + + // Register the IBuildConfiguration/ICBuildConfiguration pair. + configManager.addBuildConfiguration(buildConfiguration, cBuildConfig); + + // Get the ICBuildconfiguration counterpart + cbConfig = buildConfiguration.getAdapter(ICBuildConfiguration.class); + assertThat(cbConfig, equalTo(cBuildConfig)); + } + /** * Test {@link ICBuildConfigurationManager#getBuildConfiguration(IProject, IToolChain, String, ILaunchTarget, IProgressMonitor)} * diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 90e2115453b..2b120b41cd1 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true -Bundle-Version: 9.2.0.qualifier +Bundle-Version: 9.2.100.qualifier Bundle-Activator: org.eclipse.cdt.core.CCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java index 4548f78885e..91eaf10a70e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java @@ -247,6 +247,12 @@ public class CBuildConfigurationManager ICBuildConfiguration config = null; boolean resetBinaryParser = false; synchronized (configs) { + // Due to an unlucky order of events, by a call of BuildConfiguration.getAdapter(ICBuildConfiguration.class) + // in a parallel process, buildConfig could have been added to "noConfigs, just before it was added to + // "configs". E.g. by CCorePlugin.getScannerInfoProvider() in the Indexer job. + if (noConfigs.contains(buildConfig) && configs.containsKey(buildConfig)) { + noConfigs.remove(buildConfig); + } if (!noConfigs.contains(buildConfig)) { config = configs.get(buildConfig); if (config == null) {