/* * Copyright 2013, The Android Open Source Project * * 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. */ #ifndef ABCC_ABCC_H #define ABCC_ABCC_H #include <list> #include <map> #include <string> #include <vector> namespace abcc { enum ReturnCode { RET_OK, RET_FAIL_RUN_CMD, RET_FAIL_UNSUPPORT_ABI, RET_FAIL_PREPARE_BITCODE, RET_FAIL_PREPARE_TOOL, RET_FAIL_CLEANUP, RET_FAIL_TRANSLATE, RET_FAIL_COMPILE, RET_FAIL_LINK }; enum Command { CMD_TRANSLATE = 0, CMD_COMPILE, CMD_LINK, CMD_LINK_RUNTIME }; class TargetAbi { public: enum Abi { ARMEABI = 0, ARMEABI_V7A, X86, MIPS }; private: Abi mAbi; public: TargetAbi(const std::string &abi); operator int() const { return (int)mAbi; } operator const char*() const { if (mAbi == ARMEABI) return "armeabi"; if (mAbi == ARMEABI_V7A) return "armeabi-v7a"; if (mAbi == X86) return "x86"; if (mAbi == MIPS) return "mips"; return 0; } const char* getArch() const { if (mAbi == ARMEABI || mAbi == ARMEABI_V7A) return "arm"; if (mAbi == X86) return "x86"; if (mAbi == MIPS) return "mips"; return 0; } }; struct TargetAttributes { const char *mArch; const char *mTriple; const char *mLinkEmulation; const char *mBaseCFlags; const char *mBaseLDFlags; }; const TargetAttributes kGlobalTargetAttrs[] = { {"arm", "armv5te-linux-androideabi", "armelf_linux_eabi", "", ""}, #ifdef FORCE_ARM {"arm", "armv7-linux-androideabi", "armelf_linux_eabi", "", ""}, #else {"arm", "thumbv7-linux-androideabi", "armelf_linux_eabi", "", ""}, #endif {"x86", "i686-linux-android", "elf_i386", "-disable-fp-elim -force-align-stack -mattr=-ssse3,-sse41,-sse42,-sse4a,-popcnt", ""}, {"mips", "mipsel-linux-android", "elf32ltsmip", "", ""}, }; // Used when computing mutual dependency class BitcodeCompiler; class BitcodeInfo; typedef std::map<std::string/*soname*/, BitcodeInfo> SONameMap; class BitcodeInfo { public: BitcodeInfo() {} // Only for stl use BitcodeInfo(const std::string &bc); int readWrapper(BitcodeCompiler &); static void dropExternalLDLibs(SONameMap &map); bool mShared; int mOptimizationLevel; std::string mBCPath; std::string mTargetBCPath; std::string mObjPath; std::string mOutPath; std::string mSOName; std::string mLDFlags; // --no-undefined, ... std::list<std::string> mLDLibs; // -lxxx, will be removed one-by-one until empty std::string mLDLibsStr; // Immutable once read in public: static int transferBytesToNumLe(const unsigned char *buffer, size_t n); }; class BitcodeCompiler { protected: TargetAbi mAbi; std::string mSysroot; std::string mWorkingDir; // Target-independent, but global std::string mGlobalCFlags; std::string mGlobalLDFlags; std::string mGlobalLDLibs; ReturnCode mRet; std::vector<BitcodeInfo> mBitcodeFiles; SONameMap mSonameMap; std::string mExecutableToolsPath[(unsigned)CMD_LINK_RUNTIME+1]; public: BitcodeCompiler(const std::string &abi, const std::string &sysroot, const std::string &working_dir, const bool savetemps); const ReturnCode returnCode() const { return mRet; } virtual void cleanupPre() {} virtual void cleanupPost() {} void prepare() { prepareBitcodes(); if (returnCode() != RET_OK) return; prepareToolchain(); if (returnCode() != RET_OK) return; } void execute() { translate(); if (returnCode() != RET_OK) return; compile(); if (returnCode() != RET_OK) return; link(); if (returnCode() != RET_OK) return; } private: bool mSaveTemps; void prepareBitcodes(); void createSONameMapping(); virtual void getBitcodeFiles() = 0; virtual void prepareToolchain() = 0; virtual void copyRuntime(const BitcodeInfo &info) = 0; virtual void removeIntermediateFile(const std::string &path) = 0; void translate(); void compile(); void link(); public: virtual int parseLDFlags(BitcodeInfo &info, const std::string &str) = 0; protected: void runCmd(std::string cmd, bool dump = false); }; } // namespace abcc // FIXME: We use LOGV, LOGE in Abcc.cpp, how to prevent this anti dependency? #if ON_DEVICE #include "Abcc_device.h" #else #include "Abcc_host.h" #endif #endif