use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.
the class NativeDepsHelper method createNativeDepsAction.
public static NativeDepsRunfiles createNativeDepsAction(final RuleContext ruleContext, CcLinkParams linkParams, Collection<String> extraLinkOpts, BuildConfiguration configuration, CcToolchainProvider toolchain, Artifact nativeDeps, String libraryIdentifier, Root bindirIfShared, boolean useDynamicRuntime) throws InterruptedException {
Preconditions.checkState(ruleContext.isLegalFragment(CppConfiguration.class), "%s does not have access to CppConfiguration", ruleContext.getRule().getRuleClass());
List<String> linkopts = new ArrayList<>(extraLinkOpts);
linkopts.addAll(linkParams.flattenedLinkopts());
Map<Artifact, NestedSet<Artifact>> linkstamps = CppHelper.resolveLinkstamps(ruleContext, linkParams);
List<Artifact> buildInfoArtifacts = linkstamps.isEmpty() ? ImmutableList.<Artifact>of() : ruleContext.getAnalysisEnvironment().getBuildInfo(ruleContext, CppBuildInfo.KEY, configuration);
boolean shareNativeDeps = configuration.getFragment(CppConfiguration.class).shareNativeDeps();
NestedSet<LibraryToLink> linkerInputs = linkParams.getLibraries();
Artifact sharedLibrary;
if (shareNativeDeps) {
PathFragment sharedPath = getSharedNativeDepsPath(LinkerInputs.toLibraryArtifacts(linkerInputs), linkopts, linkstamps.keySet(), buildInfoArtifacts, ruleContext.getFeatures());
libraryIdentifier = sharedPath.getPathString();
sharedLibrary = ruleContext.getShareableArtifact(sharedPath.replaceName(sharedPath.getBaseName() + ".so"), configuration.getBinDirectory(ruleContext.getRule().getRepository()));
} else {
sharedLibrary = nativeDeps;
}
FdoSupportProvider fdoSupport = CppHelper.getFdoSupport(ruleContext, ":cc_toolchain");
CppLinkActionBuilder builder = new CppLinkActionBuilder(ruleContext, sharedLibrary, configuration, toolchain, fdoSupport);
if (useDynamicRuntime) {
builder.setRuntimeInputs(ArtifactCategory.DYNAMIC_LIBRARY, toolchain.getDynamicRuntimeLinkMiddleman(), toolchain.getDynamicRuntimeLinkInputs());
} else {
builder.setRuntimeInputs(ArtifactCategory.STATIC_LIBRARY, toolchain.getStaticRuntimeLinkMiddleman(), toolchain.getStaticRuntimeLinkInputs());
}
CppLinkAction linkAction = builder.setLinkArtifactFactory(SHAREABLE_LINK_ARTIFACT_FACTORY).setCrosstoolInputs(toolchain.getLink()).addLibraries(linkerInputs).setLinkType(LinkTargetType.DYNAMIC_LIBRARY).setLinkStaticness(LinkStaticness.MOSTLY_STATIC).setLibraryIdentifier(libraryIdentifier).addLinkopts(linkopts).setNativeDeps(true).addLinkstamps(linkstamps).build();
ruleContext.registerAction(linkAction);
Artifact linkerOutput = linkAction.getPrimaryOutput();
if (shareNativeDeps) {
// Collect dynamic-linker-resolvable symlinks for C++ runtime library dependencies.
// Note we only need these symlinks when --share_native_deps is on, as shared native deps
// mangle path names such that the library's conventional _solib RPATH entry
// no longer resolves (because the target directory's relative depth gets lost).
List<Artifact> runtimeSymlinks;
if (useDynamicRuntime) {
runtimeSymlinks = new LinkedList<>();
for (final Artifact runtimeInput : toolchain.getDynamicRuntimeLinkInputs()) {
final Artifact runtimeSymlink = ruleContext.getPackageRelativeArtifact(getRuntimeLibraryPath(ruleContext, runtimeInput), bindirIfShared);
// Since runtime library symlinks are underneath the target's output directory and
// multiple targets may share the same output directory, we need to make sure this
// symlink's generating action is only set once.
ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), runtimeInput, runtimeSymlink, null));
runtimeSymlinks.add(runtimeSymlink);
}
} else {
runtimeSymlinks = ImmutableList.of();
}
ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), linkerOutput, nativeDeps, null));
return new NativeDepsRunfiles(nativeDeps, runtimeSymlinks);
}
return new NativeDepsRunfiles(linkerOutput, ImmutableList.<Artifact>of());
}
use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.
the class CcLibraryHelper method computePublicHeaders.
private PublicHeaders computePublicHeaders() {
if (!ruleContext.attributes().has("strip_include_prefix", Type.STRING) || !ruleContext.attributes().has("include_prefix", Type.STRING)) {
return new PublicHeaders(ImmutableList.copyOf(Iterables.concat(publicHeaders, nonModuleMapHeaders)), ImmutableList.copyOf(publicHeaders), null);
}
PathFragment prefix = ruleContext.attributes().isAttributeValueExplicitlySpecified("include_prefix") ? new PathFragment(ruleContext.attributes().get("include_prefix", Type.STRING)) : null;
PathFragment stripPrefix;
if (ruleContext.attributes().isAttributeValueExplicitlySpecified("strip_include_prefix")) {
stripPrefix = new PathFragment(ruleContext.attributes().get("strip_include_prefix", Type.STRING));
if (stripPrefix.isAbsolute()) {
stripPrefix = ruleContext.getLabel().getPackageIdentifier().getRepository().getSourceRoot().getRelative(stripPrefix.toRelative());
} else {
stripPrefix = ruleContext.getPackageDirectory().getRelative(stripPrefix);
}
} else if (prefix != null) {
stripPrefix = ruleContext.getPackageDirectory();
} else {
stripPrefix = null;
}
if (stripPrefix == null && prefix == null) {
// Simple case, no magic needed
return new PublicHeaders(ImmutableList.copyOf(Iterables.concat(publicHeaders, nonModuleMapHeaders)), ImmutableList.copyOf(publicHeaders), null);
}
if (stripPrefix.containsUplevelReferences()) {
ruleContext.attributeError("strip_include_prefix", "should not contain uplevel references");
}
if (prefix != null && prefix.containsUplevelReferences()) {
ruleContext.attributeError("include_prefix", "should not contain uplevel references");
}
if (prefix != null && prefix.isAbsolute()) {
ruleContext.attributeError("include_prefix", "should be a relative path");
}
if (ruleContext.hasErrors()) {
return new PublicHeaders(ImmutableList.<Artifact>of(), ImmutableList.<Artifact>of(), null);
}
ImmutableList.Builder<Artifact> moduleHeadersBuilder = ImmutableList.builder();
for (Artifact originalHeader : publicHeaders) {
if (!originalHeader.getRootRelativePath().startsWith(stripPrefix)) {
ruleContext.ruleError(String.format("header '%s' is not under the specified strip prefix '%s'", originalHeader.getExecPathString(), stripPrefix.getPathString()));
continue;
}
PathFragment includePath = originalHeader.getRootRelativePath().relativeTo(stripPrefix);
if (prefix != null) {
includePath = prefix.getRelative(includePath);
}
if (!originalHeader.getExecPath().equals(includePath)) {
Artifact virtualHeader = ruleContext.getUniqueDirectoryArtifact("_virtual_includes", includePath, ruleContext.getBinOrGenfilesDirectory());
ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), originalHeader, virtualHeader, "Symlinking virtual headers for " + ruleContext.getLabel()));
moduleHeadersBuilder.add(virtualHeader);
} else {
moduleHeadersBuilder.add(originalHeader);
}
}
ImmutableList<Artifact> moduleMapHeaders = moduleHeadersBuilder.build();
ImmutableList<Artifact> virtualHeaders = ImmutableList.<Artifact>builder().addAll(moduleMapHeaders).addAll(nonModuleMapHeaders).build();
return new PublicHeaders(virtualHeaders, moduleMapHeaders, ruleContext.getBinOrGenfilesDirectory().getExecPath().getRelative(ruleContext.getUniqueDirectory("_virtual_includes")));
}
use of com.google.devtools.build.lib.analysis.actions.SymlinkAction in project bazel by bazelbuild.
the class XcodeSupport method addDummySource.
/**
* Adds a dummy source file to the Xcode target. This is needed if the target does not have any
* source files but Xcode requires one.
*
* @return this xcode support
*/
XcodeSupport addDummySource(XcodeProvider.Builder xcodeProviderBuilder) {
ruleContext.registerAction(new SymlinkAction(ruleContext.getActionOwner(), ruleContext.getPrerequisiteArtifact("$dummy_source", Mode.TARGET), intermediateArtifacts.dummySource(), "Symlinking dummy artifact"));
xcodeProviderBuilder.addAdditionalSources(intermediateArtifacts.dummySource());
return this;
}
Aggregations