#include <cassert>
#include <cstdlib>
#include <list>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/OptTable.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include "Compiler.h"
// FIXME: Add parameter feature '-D macro=xxx'
static llvm::cl::opt<std::string>
InputFilename(llvm::cl::Positional, llvm::cl::Required,
llvm::cl::desc("<input file>"));
static llvm::cl::list<std::string>
HeaderSearchDirs("I", llvm::cl::desc("Header search directory"), llvm::cl::Prefix);
static llvm::cl::list<std::string>
PreDefinedSymbols("D", llvm::cl::desc("Pre-define symbol"));
static llvm::cl::opt<std::string>
OutputFilename(llvm::cl::Required, "o", llvm::cl::desc("Override output filename"));
// split "xxx" => "xxx" ""
// split "xxx=yyy" => "xxx" "yyy"
static void splitPreDefinedSymbol(const std::string& In,
std::string& Key, std::string& Value) {
size_t FoundPos = In.find("=");
if (FoundPos == std::string::npos) {
Key = In;
Value = "";
} else {
Key = In.substr(0, FoundPos);
Value = In.substr(FoundPos+1, std::string::npos);
}
}
int main(int argc, char** argv) {
llvm::llvm_shutdown_obj _ShutdownObj;
llvm::cl::ParseCommandLineOptions(argc, argv, "P-NDK Compile Tool");
clang::TextDiagnosticPrinter* DiagClient =
new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
DiagClient->setPrefix(argv[0]);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>
DiagIDs(new clang::DiagnosticIDs());
clang::Diagnostic Diags(DiagIDs, DiagClient, true);
if (Diags.hasErrorOccurred())
return 1;
std::vector<std::string> IncludePaths;
for(unsigned i = 0, e = HeaderSearchDirs.size(); i<e; ++i) {
IncludePaths.push_back(HeaderSearchDirs[i]);
}
std::map<std::string, std::string> PreDefinedSymbolMap;
for(unsigned i = 0, e = PreDefinedSymbols.size(); i<e; ++i) {
std::string Key;
std::string Value;
splitPreDefinedSymbol(PreDefinedSymbols[i], Key, Value);
PreDefinedSymbolMap.insert(
std::pair<std::string, std::string>(Key,Value));
}
ndkpc::Compiler Compiler;
Compiler.init(std::string(),
std::string(),
std::vector<std::string>(),
llvm::StringRef(InputFilename).endswith(".cpp"));
Compiler.setInputSource(InputFilename);
Compiler.setIncludePaths(IncludePaths);
Compiler.setOutput(OutputFilename.c_str());
Compiler.setPreDefinedSymbol(PreDefinedSymbolMap);
int ret = Compiler.compile();
return ret;
}