Search code examples
eclipse-plugineclipse-cdt

Programmatically configuring CDT project


I created a Eclipse plugin with a new project type, creating that project type also adds the C/C++ natures from CDT. Now I want to provide a default configuration for that project type, specifically I want it to be configured to use the CMake4Eclipse build type.

I need to set:

  1. current Toolchain
  2. current Builder
  3. CMake Host OS overrides
  4. Source location
  5. Environment

For neither of those have I been able to figure out how to set them programmatically. A solution where I have a static default configuration is acceptable.


Solution

  • Step 1. and 2. (setting toolchain & builder) I managed successfully with the following code:

    // convert to C/C++ project
        CCorePlugin ccore = CCorePlugin.getDefault();
        ccore.convertProjectToNewC(project, ManagedBuildManager.CFG_DATA_PROVIDER_ID, monitor);
        CCorePlugin.getDefault().convertProjectFromCtoCC(project, monitor);
    
    // get toolchain and cmake builder
        IBuilder cmakeBuilder = ManagedBuildManager.getExtensionBuilder("de.marw.cdt.cmake.core.genscriptbuilder");
        IToolChain toolChain = ManagedBuildManager.getExtensionToolChain("cdt.managedbuild.toolchain.gnu.base");
    
    // arcane incantations based on org.eclipse.cdt.managedbuilder.ui.wizards.NewMakeProjFromExisting.performFinish()
        ICProjectDescriptionManager pdMgr = CoreModel.getDefault().getProjectDescriptionManager();
        ICProjectDescription projDesc = pdMgr.createProjectDescription(project, false);
        ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project);
        ManagedProject mProj = new ManagedProject(projDesc);
        info.setManagedProject(mProj);
    
        CfgHolder cfgHolder = new CfgHolder(toolChain, null);
        IConfiguration config = new Configuration(mProj, (ToolChain) toolChain,
        ManagedBuildManager.calculateChildId(toolChain.getId(), null), cfgHolder.getName());
    // set cmake builder
        config.changeBuilder(cmakeBuilder, ManagedBuildManager.calculateChildId(config.getId(), null),
        cmakeBuilder.getName());
    // make sure makefile generation is enabled
        config.setManagedBuildOn(true);
        CConfigurationData data = config.getConfigurationData();
        projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
    
        pdMgr.setProjectDescription(project, projDesc);
    

    Step 3. (cmake configuration) wasn't possible out of the box, the cmake4eclipse plugin does not export the API necessary to change its settings. So I created a fragment that imports and exports the necessary packages. Then it was straightforward to configure with above code in place:

    ICConfigurationDescription desc = projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
    CMakePreferences cmakePref = ConfigurationManager.getInstance().getOrCreate(desc);
    cmakePref.getWindowsPreferences().setGenerator(CmakeGenerator.NMakeMakefiles);
    cmakePref.getDefines().add(new CmakeDefine("CMAKE_BUILD_TYPE",CmakeVariableType.STRING,"Release"));
    

    Step 4. (setting a source folder) looks like this:

      private void setAsSourceFolder(IResource folder, IProject project) throws CoreException {
        ICSourceEntry newEntry = new CSourceEntry(folder.getProjectRelativePath(), null, 0);
        ICProjectDescription des = CCorePlugin.getDefault().getProjectDescription(project, true);
    
        ICConfigurationDescription[] cfgs = des.getConfigurations();
        for (ICConfigurationDescription cfg : cfgs) {
          cfg.setSourceEntries(new ICSourceEntry[] { newEntry });
        }
    
        CCorePlugin.getDefault().setProjectDescription(project, des);
      }