use of com.facebook.buck.model.Pair in project buck by facebook.
the class AbstractPrebuiltCxxLibraryGroupDescription method getStaticLinkArgs.
/**
* @return the link args formed from the user-provided static link line after resolving library
* macro references.
*/
private Iterable<Arg> getStaticLinkArgs(BuildTarget target, ImmutableList<SourcePath> libs, ImmutableList<String> args) {
ImmutableList.Builder<Arg> builder = ImmutableList.builder();
for (String arg : args) {
Optional<Pair<String, String>> libRef = getLibRef(ImmutableSet.of(LIB_MACRO), arg);
if (libRef.isPresent()) {
int index;
try {
index = Integer.parseInt(libRef.get().getSecond());
} catch (NumberFormatException e) {
throw new HumanReadableException("%s: ", target);
}
if (index < 0 || index >= libs.size()) {
throw new HumanReadableException("%s: ", target);
}
builder.add(SourcePathArg.of(libs.get(index)));
} else {
builder.add(StringArg.of(arg));
}
}
return builder.build();
}
use of com.facebook.buck.model.Pair in project buck by facebook.
the class RecordingProjectFileHashCache method findSymlinkRoot.
// For given symlink, finds the highest level symlink in the path that points outside the
// project. This is to avoid collisions/redundant symlink creation during re-materialization.
// Example notes:
// In the below examples, /a is the root of the project, and /e is outside the project.
// Example 1:
// /a/b/symlink_to_x_y/d -> /e/f/x/y/d
// (where /a/b -> /e/f, and /e/f/symlink_to_x_y -> /e/f/x/y)
// returns /a/b -> /e/f
// Example 2:
// /a/b/symlink_to_c/d -> /e/f/d
// (where /a/b/symlink_to_c -> /a/b/c and /a/b/c -> /e/f)
// returns /a/b/symlink_to_c -> /e/f
// Note: when re-materializing symlinks we skip any intermediate symlinks inside the project
// (in Example 2 we will re-materialize /a/b/symlink_to_c -> /e/f, and skip /a/b/c).
private Pair<Path, Path> findSymlinkRoot(Path symlinkPath) {
int projectPathComponents = projectFilesystem.getRootPath().getNameCount();
for (int pathEndIndex = (projectPathComponents + 1); pathEndIndex <= symlinkPath.getNameCount(); pathEndIndex++) {
// Note: subpath(..) does not return a rooted path, so we need to prepend an additional '/'.
Path symlinkSubpath = symlinkPath.getRoot().resolve(symlinkPath.subpath(0, pathEndIndex));
Path realSymlinkSubpath = findRealPath(symlinkSubpath);
boolean realPathOutsideProject = !projectFilesystem.getPathRelativeToProjectRoot(realSymlinkSubpath).isPresent();
if (realPathOutsideProject) {
return new Pair<>(projectFilesystem.getPathRelativeToProjectRoot(symlinkSubpath).get(), realSymlinkSubpath);
}
}
throw new RuntimeException(String.format("Failed to find root symlink for symlink with path [%s]", symlinkPath.toAbsolutePath()));
}
use of com.facebook.buck.model.Pair in project buck by facebook.
the class ServerHealthManager method calculateBestServer.
private Optional<URI> calculateBestServer() throws NoHealthyServersException {
ServerHealthManagerEventData.Builder data = ServerHealthManagerEventData.builder();
Map<URI, PerServerData.Builder> allPerServerData = Maps.newHashMap();
try {
long epochMillis = clock.currentTimeMillis();
List<Pair<URI, Long>> serverLatencies = Lists.newArrayList();
for (ServerHealthState state : servers.values()) {
URI server = state.getServer();
PerServerData.Builder perServerData = PerServerData.builder().setServer(server);
allPerServerData.put(server, perServerData);
float errorPercentage = state.getErrorPercentage(epochMillis, errorCheckTimeRangeMillis);
long latencyMillis = state.getPingLatencyMillis(epochMillis, latencyCheckTimeRangeMillis);
if (errorPercentage <= maxErrorPercentage && latencyMillis <= maxAcceptableLatencyMillis) {
serverLatencies.add(new Pair<>(state.getServer(), latencyMillis));
} else {
perServerData.setServerUnhealthy(true);
}
}
if (serverLatencies.size() == 0) {
data.setNoHealthyServersAvailable(true);
return Optional.empty();
}
Collections.sort(serverLatencies, LATENCY_COMPARATOR);
URI bestServer = serverLatencies.get(0).getFirst();
Preconditions.checkNotNull(allPerServerData.get(bestServer)).setBestServer(true);
return Optional.of(bestServer);
} finally {
for (PerServerData.Builder builder : allPerServerData.values()) {
data.addPerServerData(builder.build());
}
eventBus.post(new ServerHealthManagerEvent(data.build()));
}
}
use of com.facebook.buck.model.Pair in project buck by facebook.
the class NdkLibraryDescription method generateMakefile.
/**
* @return a {@link BuildRule} which generates a Android.mk which pulls in the local Android.mk
* file and also appends relevant preprocessor and linker flags to use C/C++ library deps.
*/
private Pair<String, Iterable<BuildRule>> generateMakefile(BuildRuleParams params, BuildRuleResolver resolver) throws NoSuchBuildTargetException {
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
ImmutableList.Builder<String> outputLinesBuilder = ImmutableList.builder();
ImmutableSortedSet.Builder<BuildRule> deps = ImmutableSortedSet.naturalOrder();
for (Map.Entry<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> entry : cxxPlatforms.entrySet()) {
CxxPlatform cxxPlatform = entry.getValue().getCxxPlatform();
// Collect the preprocessor input for all C/C++ library deps. We search *through* other
// NDK library rules.
CxxPreprocessorInput cxxPreprocessorInput = CxxPreprocessorInput.concat(CxxPreprocessables.getTransitiveCxxPreprocessorInput(cxxPlatform, params.getDeps(), NdkLibrary.class::isInstance));
// We add any dependencies from the C/C++ preprocessor input to this rule, even though
// it technically should be added to the top-level rule.
deps.addAll(cxxPreprocessorInput.getDeps(resolver, ruleFinder));
// Add in the transitive preprocessor flags contributed by C/C++ library rules into the
// NDK build.
ImmutableList.Builder<String> ppFlags = ImmutableList.builder();
ppFlags.addAll(cxxPreprocessorInput.getPreprocessorFlags().get(CxxSource.Type.C));
Preprocessor preprocessor = CxxSourceTypes.getPreprocessor(cxxPlatform, CxxSource.Type.C).resolve(resolver);
ppFlags.addAll(CxxHeaders.getArgs(cxxPreprocessorInput.getIncludes(), pathResolver, Optional.empty(), preprocessor));
String localCflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), ppFlags.build()));
// Collect the native linkable input for all C/C++ library deps. We search *through* other
// NDK library rules.
NativeLinkableInput nativeLinkableInput = NativeLinkables.getTransitiveNativeLinkableInput(cxxPlatform, params.getDeps(), Linker.LinkableDepType.SHARED, NdkLibrary.class::isInstance);
// We add any dependencies from the native linkable input to this rule, even though
// it technically should be added to the top-level rule.
deps.addAll(nativeLinkableInput.getArgs().stream().flatMap(arg -> arg.getDeps(ruleFinder).stream()).iterator());
// Add in the transitive native linkable flags contributed by C/C++ library rules into the
// NDK build.
String localLdflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), com.facebook.buck.rules.args.Arg.stringify(nativeLinkableInput.getArgs(), pathResolver)));
// Write the relevant lines to the generated makefile.
if (!localCflags.isEmpty() || !localLdflags.isEmpty()) {
NdkCxxPlatforms.TargetCpuType targetCpuType = entry.getKey();
String targetArchAbi = getTargetArchAbi(targetCpuType);
outputLinesBuilder.add(String.format("ifeq ($(TARGET_ARCH_ABI),%s)", targetArchAbi));
if (!localCflags.isEmpty()) {
outputLinesBuilder.add("BUCK_DEP_CFLAGS=" + localCflags);
}
if (!localLdflags.isEmpty()) {
outputLinesBuilder.add("BUCK_DEP_LDFLAGS=" + localLdflags);
}
outputLinesBuilder.add("endif");
outputLinesBuilder.add("");
}
}
// GCC-only magic that rewrites non-deterministic parts of builds
String ndksubst = NdkCxxPlatforms.ANDROID_NDK_ROOT;
outputLinesBuilder.addAll(ImmutableList.copyOf(new String[] { // We're evaluated once per architecture, but want to add the cflags only once.
"ifeq ($(BUCK_ALREADY_HOOKED_CFLAGS),)", "BUCK_ALREADY_HOOKED_CFLAGS := 1", // Only GCC supports -fdebug-prefix-map
"ifeq ($(filter clang%,$(NDK_TOOLCHAIN_VERSION)),)", // Replace absolute paths with machine-relative ones.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(NDK_ROOT)/=" + ndksubst + "/", "NDK_APP_CFLAGS += -fdebug-prefix-map=$(abspath $(BUCK_PROJECT_DIR))/=./", // repository root.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(BUCK_PROJECT_DIR)/=./", "NDK_APP_CFLAGS += -fdebug-prefix-map=./=" + ".$(subst $(abspath $(BUCK_PROJECT_DIR)),,$(abspath $(CURDIR)))/", "NDK_APP_CFLAGS += -fno-record-gcc-switches", "ifeq ($(filter 4.6,$(TOOLCHAIN_VERSION)),)", // headers either.
"NDK_APP_CPPFLAGS += -fno-canonical-system-headers", // detailed command line argument information anyway.
"NDK_APP_CFLAGS += -gno-record-gcc-switches", // !GCC 4.6
"endif", // !clang
"endif", // absolute path, but only for modules under the project root.
"BUCK_SAVED_IMPORTS := $(__ndk_import_dirs)", "__ndk_import_dirs :=", "$(foreach __dir,$(BUCK_SAVED_IMPORTS),\\", "$(call import-add-path-optional,\\", "$(if $(filter $(abspath $(BUCK_PROJECT_DIR))%,$(__dir)),\\", "$(BUCK_PROJECT_DIR)$(patsubst $(abspath $(BUCK_PROJECT_DIR))%,%,$(__dir)),\\", "$(__dir))))", // !already hooked
"endif", // generic paths.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(TOOLCHAIN_PREBUILT_ROOT)/=" + "@ANDROID_NDK_ROOT@/toolchains/$(TOOLCHAIN_NAME)/prebuilt/@BUILD_HOST@/" }));
outputLinesBuilder.add("include Android.mk");
String contents = Joiner.on(System.lineSeparator()).join(outputLinesBuilder.build());
return new Pair<String, Iterable<BuildRule>>(contents, deps.build());
}
use of com.facebook.buck.model.Pair in project buck by facebook.
the class DistBuildService method uploadBuckDotFiles.
public ListenableFuture<Void> uploadBuckDotFiles(final StampedeId id, final ProjectFilesystem filesystem, FileHashCache fileHashCache, ListeningExecutorService executorService) throws IOException {
ListenableFuture<Pair<List<FileInfo>, List<PathInfo>>> filesFuture = executorService.submit(() -> {
List<Path> buckDotFilesExceptConfig = Lists.newArrayList();
for (Path path : filesystem.getDirectoryContents(filesystem.getRootPath())) {
String fileName = path.getFileName().toString();
if (!filesystem.isDirectory(path) && !filesystem.isSymLink(path) && fileName.startsWith(".") && fileName.contains("buck") && !fileName.startsWith(".buckconfig")) {
buckDotFilesExceptConfig.add(path);
}
}
List<FileInfo> fileEntriesToUpload = new LinkedList<>();
List<PathInfo> pathEntriesToUpload = new LinkedList<>();
for (Path path : buckDotFilesExceptConfig) {
FileInfo fileInfoObject = new FileInfo();
fileInfoObject.setContent(filesystem.readFileIfItExists(path).get().getBytes());
fileInfoObject.setContentHash(fileHashCache.get(path.toAbsolutePath()).toString());
fileEntriesToUpload.add(fileInfoObject);
PathInfo pathInfoObject = new PathInfo();
pathInfoObject.setPath(path.toString());
pathInfoObject.setContentHash(fileHashCache.get(path.toAbsolutePath()).toString());
pathEntriesToUpload.add(pathInfoObject);
}
return new Pair<>(fileEntriesToUpload, pathEntriesToUpload);
});
ListenableFuture<Void> setFilesFuture = Futures.transformAsync(filesFuture, filesAndPaths -> {
setBuckDotFiles(id, filesAndPaths.getSecond());
return Futures.immediateFuture(null);
}, executorService);
ListenableFuture<Void> uploadFilesFuture = Futures.transformAsync(filesFuture, filesAndPaths -> {
uploadMissingFilesFromList(filesAndPaths.getFirst(), executorService);
return Futures.immediateFuture(null);
}, executorService);
return Futures.transform(Futures.allAsList(ImmutableList.of(setFilesFuture, uploadFilesFuture)), new Function<List<Void>, Void>() {
@Nullable
@Override
public Void apply(@Nullable List<Void> input) {
return null;
}
});
}
Aggregations