Skip to content

Commit 252e9aa

Browse files
committed
Use build CWD for object path processing within GNU archive files
1 parent f7a6337 commit 252e9aa

File tree

4 files changed

+97
-10
lines changed

4 files changed

+97
-10
lines changed

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

Lines changed: 1 addition & 1 deletion
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.gnu.ui; singleton:=true
5-
Bundle-Version: 8.6.0.qualifier
5+
Bundle-Version: 8.6.100.qualifier
66
Bundle-Activator: org.eclipse.cdt.managedbuilder.gnu.ui.GnuUIPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@
471471
id="gnu.lib.category.general">
472472
</optionCategory>
473473
<option
474-
defaultValue="-r"
474+
defaultValue="-r -P"
475475
name="%Option.Posix.Archiver.Flags"
476476
category="gnu.lib.category.general"
477477
valueType="string"

core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Archive.java

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,39 @@
1212
* QNX Software Systems - Initial API and implementation
1313
* Anton Leherbauer (Wind River Systems)
1414
* John Dallaway - Adapt for IBinaryFile (#413)
15+
* John Dallaway - Fix object path processing (#630)
1516
*******************************************************************************/
1617
package org.eclipse.cdt.internal.core.model;
1718

1819
import java.util.Map;
20+
import java.util.Optional;
1921

22+
import org.eclipse.cdt.core.CCorePlugin;
2023
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
2124
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
25+
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
26+
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
2227
import org.eclipse.cdt.core.model.CModelException;
28+
import org.eclipse.cdt.core.model.CoreModel;
2329
import org.eclipse.cdt.core.model.IArchive;
2430
import org.eclipse.cdt.core.model.IBinary;
2531
import org.eclipse.cdt.core.model.ICElement;
2632
import org.eclipse.cdt.core.model.ICProject;
33+
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
34+
import org.eclipse.cdt.core.settings.model.ICOutputEntry;
35+
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
36+
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
37+
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
38+
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
2739
import org.eclipse.cdt.internal.core.util.MementoTokenizer;
2840
import org.eclipse.core.resources.IFile;
41+
import org.eclipse.core.resources.IProject;
2942
import org.eclipse.core.resources.IResource;
43+
import org.eclipse.core.resources.ResourcesPlugin;
3044
import org.eclipse.core.runtime.Assert;
3145
import org.eclipse.core.runtime.IPath;
3246
import org.eclipse.core.runtime.IProgressMonitor;
47+
import org.eclipse.core.runtime.Path;
3348

3449
public class Archive extends Openable implements IArchive {
3550

@@ -75,16 +90,30 @@ protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map<ICE
7590

7691
public boolean computeChildren(OpenableInfo info, IResource res) {
7792
IBinaryArchive ar = getBinaryArchive();
78-
if (ar != null) {
79-
IBinaryObject[] objects = ar.getObjects();
80-
for (final IBinaryObject obj : objects) {
81-
Binary binary = new Binary(this, ar.getPath().append(obj.getName()), obj);
93+
IPath location = res.getLocation();
94+
if (ar != null && location != null) {
95+
// find the build CWD for the archive file
96+
IPath buildCWD = Optional.ofNullable(findBuildConfiguration(res)).map(Archive::getBuildCWD)
97+
.orElse(location.removeLastSegments(1));
98+
for (IBinaryObject obj : ar.getObjects()) {
99+
// assume object names are paths as specified on the archiver command line ("ar -P")
100+
IPath objPath = new Path(obj.getName());
101+
if (!objPath.isAbsolute()) {
102+
// assume path is relative to the build CWD
103+
objPath = buildCWD.append(objPath);
104+
}
105+
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(objPath);
106+
if (file == null) { // if object path is external to the workspace
107+
// fallback to legacy behaviour
108+
// TODO: support external paths in Binary class as we do in TranslationUnit
109+
objPath = ar.getPath().append(objPath.lastSegment());
110+
}
111+
Binary binary = new Binary(this, objPath, obj);
82112
info.addChild(binary);
83113
}
84-
} else {
85-
return false;
114+
return true;
86115
}
87-
return true;
116+
return false;
88117
}
89118

90119
@Override
@@ -133,4 +162,50 @@ protected char getHandleMementoDelimiter() {
133162
return 0;
134163
}
135164

165+
private static ICConfigurationDescription findBuildConfiguration(IResource resource) {
166+
IPath location = resource.getLocation();
167+
IProject project = resource.getProject();
168+
ICProjectDescription projectDesc = CoreModel.getDefault().getProjectDescription(project, false);
169+
if (projectDesc == null) {
170+
return null; // not a CDT project
171+
}
172+
// for each build configuration of the project
173+
for (ICConfigurationDescription configDesc : projectDesc.getConfigurations()) {
174+
CConfigurationData configData = configDesc.getConfigurationData();
175+
if (configData == null) {
176+
continue; // no configuration data
177+
}
178+
CBuildData buildData = configData.getBuildData();
179+
if (buildData == null) {
180+
continue; // no build data
181+
}
182+
// for each build output directory of the build configuration
183+
for (ICOutputEntry dir : buildData.getOutputDirectories()) {
184+
IPath dirLocation = CDataUtil.makeAbsolute(project, dir).getLocation();
185+
// if the build output directory is an ancestor of the resource
186+
if ((dirLocation != null) && dirLocation.isPrefixOf(location)) {
187+
return configDesc; // build configuration found
188+
}
189+
}
190+
}
191+
return null;
192+
}
193+
194+
private static IPath getBuildCWD(ICConfigurationDescription configDesc) {
195+
IPath builderCWD = configDesc.getBuildSetting().getBuilderCWD();
196+
if (builderCWD != null) {
197+
ICdtVariableManager manager = CCorePlugin.getDefault().getCdtVariableManager();
198+
try {
199+
String cwd = builderCWD.toString();
200+
cwd = manager.resolveValue(cwd, "", null, configDesc); //$NON-NLS-1$
201+
if (!cwd.isEmpty()) {
202+
return new Path(cwd);
203+
}
204+
} catch (CdtVariableException e) {
205+
CCorePlugin.log(e);
206+
}
207+
}
208+
return null;
209+
}
210+
136211
}

core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Openable.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2014 QNX Software Systems and others.
2+
* Copyright (c) 2000, 2023 QNX Software Systems and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,11 +10,13 @@
1010
*
1111
* Contributors:
1212
* QNX Software Systems - Initial API and implementation
13+
* John Dallaway - Use file path when testing for equality (#630)
1314
*******************************************************************************/
1415
package org.eclipse.cdt.internal.core.model;
1516

1617
import java.util.Enumeration;
1718
import java.util.Map;
19+
import java.util.Objects;
1820

1921
import org.eclipse.cdt.core.model.BufferChangedEvent;
2022
import org.eclipse.cdt.core.model.CModelException;
@@ -104,6 +106,16 @@ protected void closing(Object info) throws CModelException {
104106
closeBuffer();
105107
}
106108

109+
/**
110+
* Tests if an element has the same name, type, parent and path.
111+
* Path comparison is required for multiple object files with the
112+
* same filename under an ArchiveContainer or BinaryContainer.
113+
*/
114+
@Override
115+
public boolean equals(Object o) {
116+
return super.equals(o) && (o instanceof Openable openable) && Objects.equals(getPath(), openable.getPath());
117+
}
118+
107119
/**
108120
* @see org.eclipse.cdt.core.model.IOpenable#getBuffer()
109121
*/

0 commit comments

Comments
 (0)