/* * 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.util.HumanReadableException; import com.google.common.collect.ImmutableList; /** Utilities for working with C-like source types. */ public class CxxSourceTypes { // Utility class; do not instantiate. private CxxSourceTypes() {} /** Returns true for source types which can be run through the C preprocessor. */ public static boolean isPreprocessableType(CxxSource.Type sourceType) { return sourceType == CxxSource.Type.C || sourceType == CxxSource.Type.CXX || sourceType == CxxSource.Type.ASSEMBLER_WITH_CPP || sourceType == CxxSource.Type.OBJC || sourceType == CxxSource.Type.OBJCXX || sourceType == CxxSource.Type.CUDA || sourceType == CxxSource.Type.ASM_WITH_CPP; } /** * Returns true for source types which can be built with the C compiler without a preprocessor. */ public static boolean isCompilableType(CxxSource.Type sourceType) { return sourceType == CxxSource.Type.C_CPP_OUTPUT || sourceType == CxxSource.Type.CXX_CPP_OUTPUT || sourceType == CxxSource.Type.ASSEMBLER || sourceType == CxxSource.Type.OBJC_CPP_OUTPUT || sourceType == CxxSource.Type.OBJCXX_CPP_OUTPUT || sourceType == CxxSource.Type.CUDA_CPP_OUTPUT || sourceType == CxxSource.Type.ASM; } /** @return the appropriate {@link com.facebook.buck.rules.Tool} representing the preprocessor. */ public static PreprocessorProvider getPreprocessor(CxxPlatform cxxPlatform, CxxSource.Type type) { PreprocessorProvider preprocessor; switch (type) { case ASSEMBLER_WITH_CPP: preprocessor = cxxPlatform.getAspp(); break; case C: preprocessor = cxxPlatform.getCpp(); break; case CXX: preprocessor = cxxPlatform.getCxxpp(); break; case OBJC: preprocessor = cxxPlatform.getCpp(); break; case OBJCXX: preprocessor = cxxPlatform.getCxxpp(); break; case CUDA: if (!cxxPlatform.getCudapp().isPresent()) { throw new HumanReadableException("%s: no cuda preprocessor set", cxxPlatform.getFlavor()); } preprocessor = cxxPlatform.getCudapp().get(); break; case ASM_WITH_CPP: if (!cxxPlatform.getAsmpp().isPresent()) { throw new HumanReadableException("%s: no asm preprocessor set", cxxPlatform.getFlavor()); } preprocessor = cxxPlatform.getAsmpp().get(); break; // $CASES-OMITTED$ default: throw new IllegalStateException(String.format("unexpected type: %s", type)); } return preprocessor; } /** @return the platform-specific preprocessor flags for the given {@link CxxPlatform}. */ public static ImmutableList<String> getPlatformPreprocessFlags( CxxPlatform cxxPlatform, CxxSource.Type type) { ImmutableList.Builder<String> flags = ImmutableList.builder(); switch (type) { case ASSEMBLER_WITH_CPP: flags.addAll(cxxPlatform.getAsppflags()); break; case C: flags.addAll(cxxPlatform.getCppflags()); break; case CXX: flags.addAll(cxxPlatform.getCxxppflags()); break; case OBJC: flags.addAll(cxxPlatform.getCppflags()); break; case OBJCXX: flags.addAll(cxxPlatform.getCxxppflags()); break; case CUDA: flags.addAll(cxxPlatform.getCudappflags()); break; case ASM_WITH_CPP: flags.addAll(cxxPlatform.getAsmppflags()); break; // $CASES-OMITTED$ default: throw new IllegalStateException(String.format("unexpected type: %s", type)); } return flags.build(); } /** @return the type produces from preprocessing the given input source type. */ public static CxxSource.Type getPreprocessorOutputType(CxxSource.Type type) { CxxSource.Type outputType; switch (type) { case ASSEMBLER_WITH_CPP: outputType = CxxSource.Type.ASSEMBLER; break; case C: outputType = CxxSource.Type.C_CPP_OUTPUT; break; case CXX: outputType = CxxSource.Type.CXX_CPP_OUTPUT; break; case OBJC: outputType = CxxSource.Type.OBJC_CPP_OUTPUT; break; case OBJCXX: outputType = CxxSource.Type.OBJCXX_CPP_OUTPUT; break; case CUDA: outputType = CxxSource.Type.CUDA_CPP_OUTPUT; break; case ASM_WITH_CPP: outputType = CxxSource.Type.ASM; break; // $CASES-OMITTED$ default: throw new IllegalStateException(String.format("unexpected type: %s", type)); } return outputType; } /** @return the appropriate compiler for the given language type. */ public static CompilerProvider getCompiler(CxxPlatform cxxPlatform, CxxSource.Type type) { CompilerProvider compiler; switch (type) { case ASSEMBLER: compiler = cxxPlatform.getAs(); break; case C_CPP_OUTPUT: compiler = cxxPlatform.getCc(); break; case CXX_CPP_OUTPUT: compiler = cxxPlatform.getCxx(); break; case OBJC_CPP_OUTPUT: compiler = cxxPlatform.getCc(); break; case OBJCXX_CPP_OUTPUT: compiler = cxxPlatform.getCxx(); break; case CUDA_CPP_OUTPUT: if (!cxxPlatform.getCuda().isPresent()) { throw new HumanReadableException("%s: no cuda compiler set", cxxPlatform.getFlavor()); } compiler = cxxPlatform.getCuda().get(); break; case ASM: if (!cxxPlatform.getAsm().isPresent()) { throw new HumanReadableException("%s: no asm compiler set", cxxPlatform.getFlavor()); } compiler = cxxPlatform.getAsm().get(); break; // $CASES-OMITTED$ default: throw new IllegalStateException(String.format("unexpected type: %s", type)); } return compiler; } /** @return the platform-specific compiler flags for the given {@link CxxPlatform}. */ public static ImmutableList<String> getPlatformCompilerFlags( CxxPlatform cxxPlatform, CxxSource.Type type) { ImmutableList.Builder<String> flags = ImmutableList.builder(); switch (type) { case ASSEMBLER: flags.addAll(cxxPlatform.getAsflags()); break; case C_CPP_OUTPUT: flags.addAll(cxxPlatform.getCflags()); break; case CXX_CPP_OUTPUT: flags.addAll(cxxPlatform.getCxxflags()); break; case OBJC_CPP_OUTPUT: flags.addAll(cxxPlatform.getCflags()); break; case OBJCXX_CPP_OUTPUT: flags.addAll(cxxPlatform.getCxxflags()); break; case CUDA_CPP_OUTPUT: flags.addAll(cxxPlatform.getCudaflags()); break; case ASM: flags.addAll(cxxPlatform.getAsmflags()); break; // $CASES-OMITTED$ default: throw new IllegalStateException(String.format("unexpected type: %s", type)); } return flags.build(); } }