/* * Copyright 2014-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.SourcePath; import com.facebook.buck.util.immutables.BuckStyleImmutable; import com.google.common.collect.ImmutableSet; import java.util.List; import java.util.Optional; import org.immutables.value.Value; /** * Describes a source file written in the C programming language or a derivative (C++, Objective-C, * Objective-C++, etc.) and the various paths it uses from input to output. */ @Value.Immutable @BuckStyleImmutable // PMD is disabled for the line below. We have a check that Abstract immutable types are // package-private. The Immutables generator is super-helpeful and makes references to the abstract // version of Immutables if they're referenced from other immutables, not just the generated // immutable type. So if any Immutables are defined in other packages which have a getter which // returns a CxxSource, internally an AbstractCxxSource is referenced in the generated code, which // doesn't have visibility to access this type, causing a compile error. public abstract class AbstractCxxSource { // NOPMD public enum Type { C("c", "cpp-output", Optional.of("c-header"), "c"), CXX( "c++", "c++-cpp-output", Optional.of("c++-header"), "cc", "cp", "cxx", "cpp", "CPP", "c++", "C"), OBJC("objective-c", "objective-c-cpp-output", Optional.of("objective-c-header"), "m"), OBJCXX("objective-c++", "objective-c++-cpp-output", Optional.of("objective-c++-header"), "mm"), CUDA("cuda", "cuda-cpp-output", "cu"), C_CPP_OUTPUT("cpp-output", "cpp-output", "i"), CXX_CPP_OUTPUT("c++-cpp-output", "c++-cpp-output", "ii"), OBJC_CPP_OUTPUT("objective-c-cpp-output", "objective-c-cpp-output", "mi"), OBJCXX_CPP_OUTPUT("objective-c++-cpp-output", "objective-c++-cpp-output", "mii"), CUDA_CPP_OUTPUT("cuda-cpp-output", "cuda-cpp-output", "cui"), // Note, this is declared before ASSEMBLER so .s files are recognized as needing preprocessor. ASSEMBLER_WITH_CPP("assembler-with-cpp", "assembler", "s", "S"), ASSEMBLER("assembler", "assembler", "s"), // Assembly files built with nasm/yasm. ASM_WITH_CPP("asm-with-cpp", "asm", "asmpp"), ASM("asm", "asm", "asm"), ; private final String language; private final String preprocessedLanguage; private final Optional<String> precompiledHeaderLanguage; private final ImmutableSet<String> extensions; Type(String language, String preprocessedLanguage, String... extensions) { this(language, preprocessedLanguage, Optional.empty(), extensions); } Type( String language, String preprocessedLanguage, Optional<String> precompiledHeaderLanguage, String... extensions) { this.language = language; this.preprocessedLanguage = preprocessedLanguage; this.precompiledHeaderLanguage = precompiledHeaderLanguage; this.extensions = ImmutableSet.copyOf(extensions); } public static Optional<Type> fromExtension(String extension) { for (Type type : values()) { if (type.extensions.contains(extension)) { return Optional.of(type); } } return Optional.empty(); } public String getLanguage() { return language; } public String getPreprocessedLanguage() { return preprocessedLanguage; } /** * "Language" type to pass to the compiler in order to generate a precompiled header. * * <p>Will be {@code absent} for source types which do not support precompiled headers. */ public Optional<String> getPrecompiledHeaderLanguage() { return precompiledHeaderLanguage; } public boolean isPreprocessable() { return !preprocessedLanguage.equals(language); } public ImmutableSet<String> getExtensions() { return extensions; } public boolean isAssembly() { return this == ASSEMBLER || this == ASSEMBLER_WITH_CPP; } } @Value.Parameter public abstract Type getType(); @Value.Parameter public abstract SourcePath getPath(); @Value.Parameter public abstract List<String> getFlags(); }