/******************************************************************************* * Copyright (c) 2014, 2015 Rohde & Schwarz GmbH & Co. KG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Martin Runge - initial implementation of cmake support *******************************************************************************/ package org.eclipse.cdt.cmake.langset; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.prefs.BackingStoreException; import org.eclipse.cdt.cmake.Activator; import org.eclipse.cdt.cmake.CMakeOutputPath; import org.eclipse.cdt.cmake.CMakeSettings; import org.eclipse.cdt.cmake.langset.IBuildCommandParserEx.CompileUnitInfo; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsBaseProvider; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuildCommandParser.ResourceScope; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IEclipsePreferences; public class CMakeLangSetProvider extends LanguageSettingsBaseProvider implements ILanguageSettingsProvider { static final String COMPILE_CMDS_FILENAME = "compile_commands.json"; IBuildCommandParserEx m_commandParser = null; public CMakeLangSetProvider() { init(); } public CMakeLangSetProvider(String id, String name) { super(id, name); init(); } public CMakeLangSetProvider(String id, String name, List<String> languages, List<ICLanguageSettingEntry> entries) { super(id, name, languages, entries); init(); } public CMakeLangSetProvider(String id, String name, List<String> languages, List<ICLanguageSettingEntry> entries, Map<String, String> properties) { super(id, name, languages, entries, properties); init(); } private void init() { Activator.getDefault().setLangSetProvider(this); m_commandParser = new CMakeCompileCommandParserGCC(); } public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { // PerProjectSettings projSettings = null; if(cfgDescription == null || rc == null) { return null; } IProject proj = rc.getProject(); CMakeSettings cms = Activator.getDefault().getSettings(); if(proj != null) { CompileCmdsHandler cmdHdl = cms.getCompileCmds(proj, cfgDescription.getName()); if(cmdHdl != null) { try { ProjectScope ps = new ProjectScope(proj); IEclipsePreferences prefs = ps.getNode( Activator.getId() ); String key = "LangSetProv/" + cmdHdl.getFilename(); Long value = prefs.getLong(key, 0); Long current_ts = cmdHdl.getFileModTime(); if( value.longValue() != current_ts.longValue() ) { parseCompileComands(proj, cfgDescription, cmdHdl ); prefs.putLong(key, current_ts); prefs.flush(); } } catch (org.osgi.service.prefs.BackingStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } List<ICLanguageSettingEntry> entries = null; entries = m_commandParser.getSettingEntries(cfgDescription, rc, languageId); return entries; } public void parseCompileComands( IProject project, ICConfigurationDescription cfgDescription, CompileCmdsHandler cmdHdl ) { if(cmdHdl != null) { try { CMakeCompileCmdsCwdTracker cwdTracker = new CMakeCompileCmdsCwdTracker(); if(cmdHdl.hasSourcesOutsideProject()) { Job job = new AddForeignSourcesWorkspaceJob("Creating \"Foreign Sources\" folders", project, cmdHdl.getSourcesOutsideProject()); job.schedule(); } m_commandParser.startup(cfgDescription, cwdTracker); // commandParser.setResourceScope(ResourceScope.PROJECT); for(CompileUnitInfo cu: cmdHdl.getSources()) { m_commandParser.processLine(cu.getCmdLine()); } // shutdown triggers some action that might access the compile command, so detect it before m_commandParser.shutdown(); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { } } } class AddForeignSourcesWorkspaceJob extends WorkspaceJob { private List<CompileUnitInfo> cuInfoList = null; private IProject project = null; /** * @param name */ public AddForeignSourcesWorkspaceJob(String name, IProject project, List<CompileUnitInfo> cuInfos) { super(name); this.cuInfoList = cuInfos; this.project = project; } /* (non-Javadoc) * @see org.eclipse.core.resources.WorkspaceJob#runInWorkspace(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { try { IFolder fsFolder = project.getFolder(new Path("ForeignSources")); if(!fsFolder.exists()) { fsFolder.create(IResource.VIRTUAL, true, null); } for(CompileUnitInfo cuInfo: cuInfoList) { File fsFileName = new File(cuInfo.getParsedResourceName()); IFile fsFile = fsFolder.getFile(fsFileName.getName()); IPath linkTarget = new Path(cuInfo.getParsedResourceName()); fsFile.createLink(linkTarget, IResource.REPLACE, null); } } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } return Status.OK_STATUS; } } }