/* * Copyright 2016-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.swift; import static com.facebook.buck.model.UnflavoredBuildTarget.BUILD_TARGET_PREFIX; import com.facebook.buck.cxx.CxxPlatform; import com.facebook.buck.cxx.Linker; import com.facebook.buck.cxx.NativeLinkable; import com.facebook.buck.cxx.NativeLinkableInput; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.parser.NoSuchBuildTargetException; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.args.StringArg; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.nio.file.Path; import java.nio.file.Paths; /** Pseudo linkable for representing Swift runtime library's linker arguments. */ final class SwiftRuntimeNativeLinkable implements NativeLinkable { private static final String SWIFT_RUNTIME = "_swift_runtime"; private static final BuildTarget PSEUDO_BUILD_TARGET = BuildTarget.builder( Paths.get(SWIFT_RUNTIME), BUILD_TARGET_PREFIX + SWIFT_RUNTIME, SWIFT_RUNTIME) .build(); private final SwiftPlatform swiftPlatform; SwiftRuntimeNativeLinkable(SwiftPlatform swiftPlatform) { this.swiftPlatform = swiftPlatform; } @Override public BuildTarget getBuildTarget() { return PSEUDO_BUILD_TARGET; } @Override public Iterable<? extends NativeLinkable> getNativeLinkableDeps() { return ImmutableSet.of(); } @Override public Iterable<? extends NativeLinkable> getNativeLinkableExportedDeps() { return ImmutableSet.of(); } @Override public NativeLinkableInput getNativeLinkableInput( CxxPlatform cxxPlatform, Linker.LinkableDepType type) throws NoSuchBuildTargetException { NativeLinkableInput.Builder inputBuilder = NativeLinkableInput.builder(); ImmutableSet<Path> swiftRuntimePaths = type == Linker.LinkableDepType.SHARED ? ImmutableSet.of() : swiftPlatform.getSwiftStaticRuntimePaths(); // Fall back to shared if static isn't supported on this platform. if (type == Linker.LinkableDepType.SHARED || swiftRuntimePaths.isEmpty()) { inputBuilder.addAllArgs( StringArg.from( "-Xlinker", "-rpath", "-Xlinker", "@executable_path/Frameworks", "-Xlinker", "-rpath", "-Xlinker", "@loader_path/Frameworks")); swiftRuntimePaths = swiftPlatform.getSwiftRuntimePaths(); } else { // Static linking requires force-loading Swift libs, since the dependency // discovery mechanism is disabled otherwise. inputBuilder.addAllArgs(StringArg.from("-Xlinker", "-force_load_swift_libs")); } for (Path swiftRuntimePath : swiftRuntimePaths) { inputBuilder.addAllArgs(StringArg.from("-L", swiftRuntimePath.toString())); } return inputBuilder.build(); } @Override public Linkage getPreferredLinkage(CxxPlatform cxxPlatform) { return Linkage.ANY; } @Override public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException { return ImmutableMap.of(); } }