Skip to content

Commit 224f231

Browse files
committed
Created JSON Compilation Database Generator preference page and set file
generation on false by default. Added JUnit test to test the generation of the file
1 parent e6fb475 commit 224f231

File tree

14 files changed

+547
-17
lines changed

14 files changed

+547
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2019, 2020 Marc-Andre Laperle.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.cdt.managedbuilder.core.tests;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertFalse;
15+
import static org.junit.jupiter.api.Assertions.assertTrue;
16+
17+
import java.io.FileReader;
18+
import java.io.IOException;
19+
20+
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
21+
import org.eclipse.cdt.managedbuilder.core.jsoncdb.CompilationDatabaseInformation;
22+
import org.eclipse.cdt.managedbuilder.testplugin.AbstractBuilderTest;
23+
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
24+
import org.eclipse.core.resources.IFile;
25+
import org.eclipse.core.resources.IProject;
26+
import org.eclipse.core.resources.IncrementalProjectBuilder;
27+
import org.eclipse.core.runtime.CoreException;
28+
import org.eclipse.core.runtime.preferences.InstanceScope;
29+
import org.eclipse.jface.preference.IPreferenceStore;
30+
import org.eclipse.ui.preferences.ScopedPreferenceStore;
31+
import org.junit.Ignore;
32+
import org.junit.Test;
33+
34+
import com.google.gson.Gson;
35+
import com.google.gson.JsonArray;
36+
import com.google.gson.JsonElement;
37+
import com.google.gson.JsonIOException;
38+
39+
public class CompilationDatabaseGenerationTest extends AbstractBuilderTest {
40+
41+
/**
42+
* Tests generation of compile_commands.json in "build" folder
43+
* @throws CoreException
44+
*/
45+
@Test
46+
public void testCompilationDatabaseGeneration() throws CoreException {
47+
setWorkspace("regressions");
48+
final IProject app = loadProject("helloworldC");
49+
isGenerateFileOptionEnabled(true);
50+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
51+
IFile compilationDatabase = app.getFile("build/compile_commands.json");
52+
assertTrue(compilationDatabase.exists());
53+
}
54+
55+
/**
56+
* Tests format for compile_commands.json. JSON array is expected, containing an element for the c file
57+
* @throws JsonIOException
58+
* @throws CoreException
59+
*/
60+
@Test
61+
public void testJsonFormat() throws JsonIOException, CoreException {
62+
setWorkspace("regressions");
63+
final IProject app = loadProject("helloworldC");
64+
isGenerateFileOptionEnabled(true);
65+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
66+
IFile commandsFile = app.getFile("build/compile_commands.json");
67+
if (commandsFile.exists()) {
68+
69+
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
70+
Gson gson = new Gson();
71+
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
72+
System.out.println(jsonArray);
73+
for (JsonElement element : jsonArray) {
74+
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
75+
CompilationDatabaseInformation.class);
76+
77+
assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
78+
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
79+
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
80+
assertTrue(compileCommand.file().endsWith("src/helloworldC.c"));
81+
}
82+
83+
} catch (IOException e) {
84+
assertTrue(false);
85+
}
86+
87+
}
88+
}
89+
90+
/**
91+
* Test that compile_commands.json is correctly generated when more than one .c file is present as a source file
92+
* @throws CoreException
93+
*/
94+
@Test
95+
public void testMultipleFiles() throws CoreException {
96+
setWorkspace("regressions");
97+
final IProject app = loadProject("helloworldC");
98+
IFile aFile = ManagedBuildTestHelper.createFile(app, "src/newFile.c");
99+
isGenerateFileOptionEnabled(true);
100+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
101+
IFile commandsFile = app.getFile("build/compile_commands.json");
102+
int numberOfElementsFound = 0;
103+
boolean helloworldCIsPresent = false;
104+
boolean newFileIsPresent = false;
105+
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
106+
Gson gson = new Gson();
107+
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
108+
System.out.println(jsonArray);
109+
for (JsonElement element : jsonArray) {
110+
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
111+
CompilationDatabaseInformation.class);
112+
numberOfElementsFound++;
113+
if (compileCommand.file().endsWith("helloworldC.c")) {
114+
helloworldCIsPresent = true;
115+
}
116+
if (compileCommand.file().endsWith("newFile.c")) {
117+
newFileIsPresent = true;
118+
}
119+
}
120+
assertEquals(2, numberOfElementsFound);
121+
assertTrue(helloworldCIsPresent);
122+
assertTrue(newFileIsPresent);
123+
} catch (IOException e) {
124+
assertTrue(false);
125+
}
126+
127+
}
128+
129+
/**
130+
* Tests that cpp files are handled by compile_commands.json file generator
131+
* @throws CoreException
132+
*/
133+
@Test
134+
@Ignore("This will be temporary skipped due to builder error")
135+
public void isCPPFileAllowed() throws CoreException {
136+
setWorkspace("regressions");
137+
final IProject app = loadProject("helloworldCPP");
138+
isGenerateFileOptionEnabled(true);
139+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
140+
System.out.println(app.getLocation());
141+
IFile commandsFile = app.getFile("build/compile_commands.json");
142+
if (commandsFile.exists()) {
143+
144+
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
145+
Gson gson = new Gson();
146+
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
147+
System.out.println(jsonArray);
148+
for (JsonElement element : jsonArray) {
149+
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
150+
CompilationDatabaseInformation.class);
151+
152+
assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
153+
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
154+
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
155+
assertTrue(compileCommand.file().endsWith("src/helloworldCPP.cpp"));
156+
}
157+
158+
} catch (IOException e) {
159+
assertTrue(false);
160+
}
161+
}
162+
}
163+
164+
/**
165+
* Tests that compilation database is not generated when feature is disabled
166+
* @throws CoreException
167+
*/
168+
@Test
169+
public void testCompilationDatabaseGenerationNotEnabled() throws CoreException {
170+
setWorkspace("regressions");
171+
final IProject app = loadProject("helloworldC");
172+
isGenerateFileOptionEnabled(false);
173+
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
174+
IFile compilationDatabase = app.getFile("build/compile_commands.json");
175+
assertFalse(compilationDatabase.exists());
176+
}
177+
178+
public static boolean isGenerateFileOptionEnabled(boolean value) {
179+
try {
180+
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
181+
"org.eclipse.cdt.managedbuilder.ui"); //$NON-NLS-1$
182+
preferenceStore.setDefault("generateFile", value);
183+
return preferenceStore.getBoolean("generateFile");
184+
} catch (Exception e) {
185+
ManagedBuilderCorePlugin.log(e);
186+
}
187+
return false;
188+
}
189+
}

build/org.eclipse.cdt.managedbuilder.core/schema/compilationDatabaseContributor.exsd

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969

7070
</documentation>
7171
<appInfo>
72-
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.managedbuilder.core.jsoncdb.generator.api.ICompilationDatabaseContributor"/>
72+
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.managedbuilder.core.jsoncdb.ICompilationDatabaseContributor"/>
7373
</appInfo>
7474
</annotation>
7575
</attribute>

build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java

+20-3
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@
5151
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
5252
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
5353
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
54-
import org.eclipse.cdt.managedbuilder.core.jsoncdb.generator.CompilationDatabaseGenerator;
5554
import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildDescription;
5655
import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildStateManager;
5756
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IBuildModelBuilder;
5857
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IConfigurationBuildState;
5958
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IProjectBuildState;
6059
import org.eclipse.cdt.managedbuilder.internal.buildmodel.StepBuilder;
60+
import org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator.CompilationDatabaseGenerator;
6161
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
6262
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
6363
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
@@ -86,6 +86,9 @@
8686
import org.eclipse.core.runtime.SubProgressMonitor;
8787
import org.eclipse.core.runtime.jobs.ISchedulingRule;
8888
import org.eclipse.core.runtime.jobs.Job;
89+
import org.eclipse.core.runtime.preferences.InstanceScope;
90+
import org.eclipse.jface.preference.IPreferenceStore;
91+
import org.eclipse.ui.preferences.ScopedPreferenceStore;
8992

9093
public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuilder2 {
9194

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

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

508512
for (int i = 0; i < num; i++) {
509-
CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg);
510-
generator.generate();
513+
if (isGenerateFileOptionEnabled()) {
514+
CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg);
515+
generator.generate();
516+
}
511517
//bug 219337
512518
if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
513519
if (buildConfigResourceChanges()) { //only build projects with project resource changes
@@ -1378,4 +1384,15 @@ public ISchedulingRule getRule(int trigger, Map args) {
13781384
// Success!
13791385
return null;
13801386
}
1387+
1388+
public static boolean isGenerateFileOptionEnabled() {
1389+
try {
1390+
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
1391+
"org.eclipse.cdt.managedbuilder.ui"); //$NON-NLS-1$
1392+
return preferenceStore.getBoolean(COMPILATION_DATABASE_ENABLEMENT);
1393+
} catch (Exception e) {
1394+
ManagedBuilderCorePlugin.log(e);
1395+
}
1396+
return false;
1397+
}
13811398
}
+12-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* SPDX-License-Identifier: EPL-2.0
99
********************************************************************************/
10-
package org.eclipse.cdt.managedbuilder.core.jsoncdb.generator;
10+
package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;
1111

1212
import java.util.Collections;
1313
import java.util.HashMap;
@@ -32,9 +32,17 @@
3232
private static final String ATTRIB_TOOLCHAIN_ID = "toolchainID"; //$NON-NLS-1$
3333
private static final String ID_COMPILATIONDATABASE = "compilationDatabase"; //$NON-NLS-1$
3434
private static final String EXTENSION_ID = "compilationDatabaseContributor"; //$NON-NLS-1$
35+
/**
36+
* Map of tool chain IDs (see {@link IToolChain#getId()} to
37+
* loaded instances of {@link ICompilationDatabaseContributor}
38+
*/
3539
@NonNull
36-
private final Map<String, ICompilationDatabaseContributor> loadedInstances;
37-
private final Map<String, IConfigurationElement> factoryExtensions;
40+
private final Map<String, ICompilationDatabaseContributor> loadedInstances = new HashMap<>();
41+
/**
42+
* Map of tool chain IDs (see {@link IToolChain#getId()} to
43+
* extension point information for the compilationDatabaseContributor extension.
44+
*/
45+
private final Map<String, IConfigurationElement> factoryExtensions = new HashMap<>();
3846

3947
private class EmptyCompilationDatabaseContributor implements ICompilationDatabaseContributor {
4048

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

4957
private CompilationDatabaseContributionManager() {
50-
this.factoryExtensions = new HashMap<>();
51-
this.loadedInstances = new HashMap<>();
5258
initalise();
5359
}
5460

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

6268
private void initalise() {
63-
Map<String, IConfigurationElement> loadedExtension = new HashMap<>();
64-
6569
IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(
6670
"org.eclipse.cdt.managedbuilder.core", CompilationDatabaseContributionManager.EXTENSION_ID); //$NON-NLS-1$
6771
if (extension != null) {
@@ -75,14 +79,12 @@ private void initalise() {
7579
String className = configElement
7680
.getAttribute(CompilationDatabaseContributionManager.ATTRIB_RUNNER);
7781
if (toolchainId != null && className != null) {
78-
loadedExtension.put(toolchainId, configElement);
82+
factoryExtensions.put(toolchainId, configElement);
7983
}
8084
}
8185
}
8286
}
8387
}
84-
85-
this.factoryExtensions.putAll(loadedExtension);
8688
}
8789

8890
/**
+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* SPDX-License-Identifier: EPL-2.0
99
********************************************************************************/
10-
package org.eclipse.cdt.managedbuilder.core.jsoncdb.generator;
10+
package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;
1111

1212
import java.io.ByteArrayInputStream;
1313
import java.io.InputStream;

build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.ui; singleton:=true
5-
Bundle-Version: 9.4.0.qualifier
5+
Bundle-Version: 9.4.100.qualifier
66
Bundle-Activator: org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

build/org.eclipse.cdt.managedbuilder.ui/plugin.properties

+2
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,5 @@ Configurations.menu=Build Configurations
119119

120120
buildDefinitionsUI.ep.name = Build Definitions UI
121121
extension-point.name = Custom MBS New Wizard Pages
122+
123+
JSONCompilatioDatabaseGeneratorPage.name = JSON Compilation Database Generator

build/org.eclipse.cdt.managedbuilder.ui/plugin.xml

+12-1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@
340340
id="org.eclipse.cdt.managedbuilder.ui.preferences.PrefPage_MultiConfig"
341341
name="%multicfg">
342342
</page>
343+
<page
344+
category="org.eclipse.cdt.ui.preferences.BuildSettings"
345+
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.JsonCdbGeneratorPreferencePage"
346+
id="org.eclipse.cdt.managedbuilder.ui.compilationdatabase.JsonCdbPreferencePage"
347+
name="%JSONCompilatioDatabaseGeneratorPage.name">
348+
</page>
343349
</extension>
344350

345351
<!-- Action for Project Converter in context menu -->
@@ -809,6 +815,12 @@
809815
</adapt>
810816
</enabledWhen>
811817
</page>
818+
<page
819+
category="org.eclipse.cdt.managedbuilder.ui.properties.Page_head_build"
820+
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.JsonCdbGeneratorPropertyPage"
821+
id="org.eclipse.cdt.managedbuilder.ui.properties.Page_JsonCompilationDatabaseGenerator"
822+
name="%JSONCompilatioDatabaseGeneratorPage.name">
823+
</page>
812824

813825
</extension>
814826

@@ -917,5 +929,4 @@
917929
label="%CDTToolchainProperty.keyword.toolchain2">
918930
</keyword>
919931
</extension>
920-
921932
</plugin>

0 commit comments

Comments
 (0)