/* * 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.cxx; import com.facebook.buck.rules.SourcePathResolver; import com.facebook.buck.rules.coercer.FrameworkPath; import com.facebook.buck.util.MoreIterables; import com.facebook.buck.util.immutables.BuckStyleTuple; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Ordering; import java.nio.file.Path; import java.util.Collections; import java.util.Iterator; import java.util.Optional; import org.immutables.value.Value; @Value.Immutable @BuckStyleTuple abstract class AbstractCxxIncludePaths { /** Paths added with {@code -I} */ public abstract ImmutableSet<CxxHeaders> getIPaths(); /** Framework paths added with {@code -F} */ public abstract ImmutableSet<FrameworkPath> getFPaths(); /** * Merge all the given {@link CxxIncludePaths}. * * <p>Combinines their path lists, deduping them (keeping the earlier of the repeated instance). */ public static CxxIncludePaths concat(Iterator<CxxIncludePaths> itemIter) { ImmutableSet.Builder<CxxHeaders> ipathBuilder = ImmutableSet.<CxxHeaders>builder(); ImmutableSet.Builder<FrameworkPath> fpathBuilder = ImmutableSet.<FrameworkPath>builder(); while (itemIter.hasNext()) { CxxIncludePaths item = itemIter.next(); ipathBuilder.addAll(item.getIPaths()); fpathBuilder.addAll(item.getFPaths()); } return CxxIncludePaths.of(ipathBuilder.build(), fpathBuilder.build()); } public static CxxIncludePaths empty() { return concat(Collections.emptyIterator()); } /** * Build a list of compiler flag strings representing the contained paths. * * <p>This method's parameters allow the caller to do some massaging and cleaning-up of paths. * * @param pathResolver * @param pathShortener used to shorten the {@code -I} and {@code -isystem} paths * @param frameworkPathTransformer used to shorten/convert/transmogrify framework {@code -F} paths */ public ImmutableList<String> getFlags( SourcePathResolver pathResolver, PathShortener pathShortener, Function<FrameworkPath, Path> frameworkPathTransformer, Preprocessor preprocessor) { ImmutableList.Builder<String> builder = ImmutableList.builder(); builder.addAll( CxxHeaders.getArgs(getIPaths(), pathResolver, Optional.of(pathShortener), preprocessor)); builder.addAll( MoreIterables.zipAndConcat( Iterables.cycle("-F"), FluentIterable.from(getFPaths()) .transform(frameworkPathTransformer) .transform(Object::toString) .toSortedSet(Ordering.natural()))); return builder.build(); } public CxxToolFlags toToolFlags( SourcePathResolver resolver, PathShortener pathShortener, Function<FrameworkPath, Path> frameworkPathTransformer, Preprocessor preprocessor) { return CxxToolFlags.explicitBuilder() .addAllRuleFlags(getFlags(resolver, pathShortener, frameworkPathTransformer, preprocessor)) .build(); } /** * Build a list of compiler flag strings representing the contained paths. * * <p>Paths are inserted into the compiler flag list as-is, without transformation or shortening. */ public ImmutableList<String> getFlags( SourcePathResolver pathResolver, Preprocessor preprocessor) { ImmutableList.Builder<String> builder = ImmutableList.builder(); builder.addAll(CxxHeaders.getArgs(getIPaths(), pathResolver, Optional.empty(), preprocessor)); // TODO(steveo) gotta handle framework paths! return builder.build(); } public CxxToolFlags toToolFlags(SourcePathResolver resolver, Preprocessor preprocessor) { return CxxToolFlags.explicitBuilder().addAllRuleFlags(getFlags(resolver, preprocessor)).build(); } }