Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdt-dev] weird scanner discovery behaviour

Hi Chris,

2009/11/26 Chris Recoskie <recoskie@xxxxxxxxxx>

>  - The language setting entries are used by managed build for
> storing it's paths and preproc symbols.  If you use this method on
> managed projects you'll be changing the set of includes / macros
> that are passed to the compiler, won't you?

Hmmm.... well they are stored in the build model IOption elements as well. I think only the IOption data is actually passed to the compiler. I will make sure I test that scenario. For now I have committed it for XLC.

In the new build system the ICLanguageSettingsEntries are the cdt.core manifestation of IOption values.  The magic for this happens in ManagedBuild's BuildLanguageData which hangs off CLanguageData. There's the method #getSupportedEntryKinds() which tells cdt.core what kinds of setting entries the build system's toolchain supports.

This drives the kind of settings entries that core will allow to persist, which tabs are visible in C/C++ General / Paths & Symbols, etc.  Amusingly, if managedbuild's toolchain doesn't have a tool with a MACROS option, say, then any MACRO setting entries set using this API will simply be lost...

You should see if you add a path to the C/C++ General > Paths & Symbols page, it also appears in C/C++ Build > Settings && is stored in as an option value in the .cproject file? Obviously for Makefile projects you don't get the tool settings tab in Build > Settings, but the option value should still be stored under the respective tool in the .cproject file.

If there isn't a managedbuild Configuration Data Provider registered, cdt.core provides its own persistence mechanism for the language settings entries.

To me, the benefits far outweighed the outstanding issues, as it's not acceptable for us to have the user

I agree, and I use this mechanism as well. It's just that the it has  pitfalls, one being managed projects.

In ManagedBuild what I did was to use scanner discovery to provide compiler built-ins, and I added some hooks to force clear these entries on compiler change, etc.  As the user provides the other build settings themselves, this seems to work well.
 
> - There's no way to distinguish between paths you added and paths
> contributed from elsewhere, be it user UI or ManagedBuild. I notice
> in your code you only every add entries.  This means that, if you
> change compiler, or change an include directory on a file, you'll
> end up retaining the older entries

Yep... it sucks but I couldn't find a way around it.

This is easier using the Dwarf parser as you get the full debug info for the binary rather than incremental output from the build

Ideally yes. However, my brain exploded when I tried to figure out how to create new configs. And it didn't

:) Code for how I did this below.  In updateResourceConfigurations resource descriptions are created if they don't exist from the parent resource desc. There's complete code for doing this on the dwarf settings bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=236872
> There are tricks to get around this, but it's not pretty.

That's a general issue though with the project description. I haven't done anything to make that worse :-P

It gets worse if you do what I did and try to annotate the model per-File rather than per-Project. In the end aggregating macros per-Folder worked and produces a very good approximation of what was built.
Cheers,
James



 protected void updateResourceConfigurations(IProject project, ICConfigurationDescription cfgDesc/*String cfgID*/, Map<IPath, LinkedHashSet> pathToDebugObjSet)
 throws CoreException {
  int resourceConfigCount = 0;
  for (Map.Entry<IPath, LinkedHashSet> e : pathToDebugObjSet.entrySet()) {
   // All extenders to specify a set of paths they want to be annotated with these attributes
   for (IPath path : getRelevantPaths(project, e.getKey())) {
    ++resourceConfigCount;
    ICResourceDescription resDesc = cfgDesc.getResourceDescription(path, true);
    if (resDesc == null) {
     // Ensure the resource exists...
     if (project.findMember(path) == null || !project.findMember(path).exists()) {
      reportInfo("Resource " + path + " not found!");
      continue;
     }
     // Find parent ICResourceDescription
     IPath parentPath = path.removeLastSegments(1);
     ICResourceDescription parentDesc = cfgDesc.getResourceDescription(parentPath, false);
     // Create the resource configuration for the file / directory based on the parent
     switch (project.findMember(path).getType()) {
     case IResource.FILE:
      resDesc = cfgDesc.createFileDescription(path, parentDesc);
      break;
     case IResource.FOLDER:
     case IResource.PROJECT:
      resDesc = cfgDesc.createFolderDescription(path, (ICFolderDescription)parentDesc);
      break;
     default:
      reportError("Resource type " + project.findMember(path).getType() + " unhandled!");
     }
    }
    // Convert Macros/Includes attributes to Settings entries
    LinkedHashSet<ICLanguageSettingEntry> newSettings = dwarfObjToSettingEntrys(e.getKey(), e.getValue());
    List<ICLanguageSetting> langs = new ArrayList<ICLanguageSetting>(3);
    if (resDesc instanceof ICFileDescription)
     langs.add(((ICFileDescription)resDesc).getLanguageSetting());
    else {
     for (ICLanguageSetting lang : ((ICFolderDescription)resDesc).getLanguageSettings()) {
      if (lang.supportsEntryKind(kind))
       langs.add(lang);
     }
    }
    for (ICLanguageSetting lang : langs) {
     if ((kind & ICSettingEntry.INCLUDE_PATH) != 0) {
      newSettings.addAll(lang.getSettingEntriesList(ICSettingEntry.INCLUDE_PATH));
      removeScannerDiscoveryProvidedInfo(newSettings);
      lang.setSettingEntries(ICSettingEntry.INCLUDE_PATH, newSettings.toArray(new ICLanguageSettingEntry[newSettings.size()]));
     }
     if ((kind & ICSettingEntry.MACRO) != 0) {
      newSettings.addAll(lang.getSettingEntriesList(ICSettingEntry.MACRO));
      removeScannerDiscoveryProvidedInfo(newSettings);
      lang.setSettingEntries(ICSettingEntry.MACRO, newSettings.toArray(new ICLanguageSettingEntry[newSettings.size()]));
     }
    }
   }
  }
  if (Debug.DWARF_PROVIDER) {
   System.out.println("Number of resource configs set on: " + cfgDesc.getId() + " was " + resourceConfigCount);
  }
 }


 

Back to the top