Skip to content

Commit

Permalink
Created JSON Compilation Database Generator preference page and set file
Browse files Browse the repository at this point in the history
generation on false by default.
Added JUnit test to test the generation of the file
  • Loading branch information
alicetrifu committed Feb 28, 2024
1 parent e6fb475 commit c825859
Show file tree
Hide file tree
Showing 13 changed files with 542 additions and 14 deletions.
Binary file not shown.
@@ -0,0 +1,187 @@
/*******************************************************************************
* Copyright (c) 2019, 2020 Marc-Andre Laperle.
*
* 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.managedbuilder.core.tests;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.FileReader;
import java.io.IOException;

import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
import org.eclipse.cdt.managedbuilder.core.jsoncdb.CompilationDatabaseInformation;
import org.eclipse.cdt.managedbuilder.testplugin.AbstractBuilderTest;
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.junit.Test;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;

public class CompilationDatabaseGenerationTest extends AbstractBuilderTest {

/**
* Tests generation of compile_commands.json in "build" folder
* @throws CoreException
*/
@Test
public void testCompilationDatabaseGeneration() throws CoreException {
setWorkspace("regressions");
final IProject app = loadProject("helloworldC");
isGenerateFileOptionEnabled(true);
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
IFile compilationDatabase = app.getFile("build/compile_commands.json");
assertTrue(compilationDatabase.exists());
}

/**
* Tests format for compile_commands.json. JSON array is expected, containing an element for the c file
* @throws JsonIOException
* @throws CoreException
*/
@Test
public void testJsonFormat() throws JsonIOException, CoreException {
setWorkspace("regressions");
final IProject app = loadProject("helloworldC");
isGenerateFileOptionEnabled(true);
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
IFile commandsFile = app.getFile("build/compile_commands.json");
if (commandsFile.exists()) {

try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
Gson gson = new Gson();
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
System.out.println(jsonArray);
for (JsonElement element : jsonArray) {
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
CompilationDatabaseInformation.class);

assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
assertTrue(compileCommand.file().endsWith("src/helloworldC.c"));
}

} catch (IOException e) {
assertTrue(false);
}

}
}

/**
* Test that compile_commands.json is correctly generated when more than one .c file is present as a source file
* @throws CoreException
*/
@Test
public void testMultipleFiles() throws CoreException {
setWorkspace("regressions");
final IProject app = loadProject("helloworldC");
IFile aFile = ManagedBuildTestHelper.createFile(app, "src/newFile.c");
isGenerateFileOptionEnabled(true);
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
IFile commandsFile = app.getFile("build/compile_commands.json");
int numberOfElementsFound = 0;
boolean helloworldCIsPresent = false;
boolean newFileIsPresent = false;
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
Gson gson = new Gson();
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
System.out.println(jsonArray);
for (JsonElement element : jsonArray) {
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
CompilationDatabaseInformation.class);
numberOfElementsFound++;
if (compileCommand.file().endsWith("helloworldC.c")) {
helloworldCIsPresent = true;
}
if (compileCommand.file().endsWith("newFile.c")) {
newFileIsPresent = true;
}
}
assertEquals(2, numberOfElementsFound);
assertTrue(helloworldCIsPresent);
assertTrue(newFileIsPresent);
} catch (IOException e) {
assertTrue(false);
}

}

/**
* Tests that cpp files are handled by compile_commands.json file generator
* @throws CoreException
*/
@Test
public void isCPPFileAllowed() throws CoreException {
setWorkspace("regressions");
final IProject app = loadProject("helloworldCPP");
isGenerateFileOptionEnabled(true);
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
System.out.println(app.getLocation());
IFile commandsFile = app.getFile("build/compile_commands.json");
if (commandsFile.exists()) {

try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
Gson gson = new Gson();
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
System.out.println(jsonArray);
for (JsonElement element : jsonArray) {
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
CompilationDatabaseInformation.class);

assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
assertTrue(compileCommand.file().endsWith("src/helloworldCPP.cpp"));
}

} catch (IOException e) {
assertTrue(false);
}
}
}

/**
* Tests that compilation database is not generated when feature is disabled
* @throws CoreException
*/
@Test
public void testCompilationDatabaseGenerationNotEnabled() throws CoreException {
setWorkspace("regressions");
final IProject app = loadProject("helloworldC");
isGenerateFileOptionEnabled(false);
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
IFile compilationDatabase = app.getFile("build/compile_commands.json");
assertFalse(compilationDatabase.exists());
}

public static boolean isGenerateFileOptionEnabled(boolean value) {
try {
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
"org.eclipse.cdt.managedbuilder.ui"); //$NON-NLS-1$
preferenceStore.setDefault("generateFile", value);
return preferenceStore.getBoolean("generateFile");
} catch (Exception e) {
ManagedBuilderCorePlugin.log(e);
}
return false;
}
}
Expand Up @@ -69,7 +69,7 @@

</documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.managedbuilder.core.jsoncdb.generator.api.ICompilationDatabaseContributor"/>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.managedbuilder.core.jsoncdb.ICompilationDatabaseContributor"/>
</appInfo>
</annotation>
</attribute>
Expand Down
Expand Up @@ -32,9 +32,17 @@
private static final String ATTRIB_TOOLCHAIN_ID = "toolchainID"; //$NON-NLS-1$
private static final String ID_COMPILATIONDATABASE = "compilationDatabase"; //$NON-NLS-1$
private static final String EXTENSION_ID = "compilationDatabaseContributor"; //$NON-NLS-1$
/**
* Map of tool chain IDs (see {@link IToolChain#getId()} to
* loaded instances of {@link ICompilationDatabaseContributor}
*/
@NonNull
private final Map<String, ICompilationDatabaseContributor> loadedInstances;
private final Map<String, IConfigurationElement> factoryExtensions;
private final Map<String, ICompilationDatabaseContributor> loadedInstances = new HashMap<>();
/**
* Map of tool chain IDs (see {@link IToolChain#getId()} to
* extension point information for the compilationDatabaseContributor extension.
*/
private final Map<String, IConfigurationElement> factoryExtensions = new HashMap<>();

private class EmptyCompilationDatabaseContributor implements ICompilationDatabaseContributor {

Expand All @@ -47,8 +55,6 @@ private class EmptyCompilationDatabaseContributor implements ICompilationDatabas
private static CompilationDatabaseContributionManager instance;

private CompilationDatabaseContributionManager() {
this.factoryExtensions = new HashMap<>();
this.loadedInstances = new HashMap<>();
initalise();
}

Expand All @@ -60,8 +66,6 @@ public static synchronized CompilationDatabaseContributionManager getInstance()
}

private void initalise() {
Map<String, IConfigurationElement> loadedExtension = new HashMap<>();

IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(
"org.eclipse.cdt.managedbuilder.core", CompilationDatabaseContributionManager.EXTENSION_ID); //$NON-NLS-1$
if (extension != null) {
Expand All @@ -75,14 +79,12 @@ private void initalise() {
String className = configElement
.getAttribute(CompilationDatabaseContributionManager.ATTRIB_RUNNER);
if (toolchainId != null && className != null) {
loadedExtension.put(toolchainId, configElement);
factoryExtensions.put(toolchainId, configElement);
}
}
}
}
}

this.factoryExtensions.putAll(loadedExtension);
}

/**
Expand Down
Expand Up @@ -86,6 +86,9 @@
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.preferences.ScopedPreferenceStore;

public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuilder2 {

Expand All @@ -94,6 +97,7 @@ public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuild
private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$
private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$
private static final String COMPILATION_DATABASE_ENABLEMENT = "generateFile"; //$NON-NLS-1$
public static boolean VERBOSE = false;

private static final int PROGRESS_MONITOR_SCALE = 100;
Expand Down Expand Up @@ -506,8 +510,10 @@ private IProject[] build(int kind, IProject project, IBuilder[] builders, boolea
}

for (int i = 0; i < num; i++) {
CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg);
generator.generate();
if (isGenerateFileOptionEnabled()) {
CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg);
generator.generate();
}
//bug 219337
if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
if (buildConfigResourceChanges()) { //only build projects with project resource changes
Expand Down Expand Up @@ -1378,4 +1384,15 @@ public ISchedulingRule getRule(int trigger, Map args) {
// Success!
return null;
}

public static boolean isGenerateFileOptionEnabled() {
try {
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
"org.eclipse.cdt.managedbuilder.ui"); //$NON-NLS-1$
return preferenceStore.getBoolean(COMPILATION_DATABASE_ENABLEMENT);
} catch (Exception e) {
ManagedBuilderCorePlugin.log(e);
}
return false;
}
}
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.ui; singleton:=true
Bundle-Version: 9.4.0.qualifier
Bundle-Version: 9.4.100.qualifier
Bundle-Activator: org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Expand Down
2 changes: 2 additions & 0 deletions build/org.eclipse.cdt.managedbuilder.ui/plugin.properties
Expand Up @@ -119,3 +119,5 @@ Configurations.menu=Build Configurations

buildDefinitionsUI.ep.name = Build Definitions UI
extension-point.name = Custom MBS New Wizard Pages

JSONCompilatioDatabaseGeneratorPage.name = JSON Compilation Database Generator
13 changes: 12 additions & 1 deletion build/org.eclipse.cdt.managedbuilder.ui/plugin.xml
Expand Up @@ -340,6 +340,12 @@
id="org.eclipse.cdt.managedbuilder.ui.preferences.PrefPage_MultiConfig"
name="%multicfg">
</page>
<page
category="org.eclipse.cdt.ui.preferences.BuildSettings"
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.JsonCdbGeneratorPreferencePage"
id="org.eclipse.cdt.managedbuilder.ui.compilationdatabase.JsonCdbPreferencePage"
name="%JSONCompilatioDatabaseGeneratorPage.name">
</page>
</extension>

<!-- Action for Project Converter in context menu -->
Expand Down Expand Up @@ -809,6 +815,12 @@
</adapt>
</enabledWhen>
</page>
<page
category="org.eclipse.cdt.managedbuilder.ui.properties.Page_head_build"
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.JsonCdbGeneratorPropertyPage"
id="org.eclipse.cdt.managedbuilder.ui.properties.Page_JsonCompilationDatabaseGenerator"
name="%JSONCompilatioDatabaseGeneratorPage.name">
</page>

</extension>

Expand Down Expand Up @@ -917,5 +929,4 @@
label="%CDTToolchainProperty.keyword.toolchain2">
</keyword>
</extension>

</plugin>

0 comments on commit c825859

Please sign in to comment.