mirror of
https://github.com/Relintai/osxcross.git
synced 2025-02-03 22:45:56 +01:00
add a minimalistic implementation of xcrun
This commit is contained in:
parent
7734f4f0ed
commit
02e1cb2a9e
@ -9,7 +9,9 @@ OSXCROSS_LINKER_VERSION ?= 134.9
|
|||||||
OSXCROSS_LIBLTO_PATH ?=
|
OSXCROSS_LIBLTO_PATH ?=
|
||||||
OSXCROSS_CXXFLAGS ?=
|
OSXCROSS_CXXFLAGS ?=
|
||||||
|
|
||||||
override CXXFLAGS=-std=c++0x -Wall -Wextra -pedantic -I. -O$(OPTIMIZE) -g
|
override CXXFLAGS=-std=c++0x -Wall -Wextra -pedantic
|
||||||
|
override CXXFLAGS+=-Wno-missing-field-initializers
|
||||||
|
override CXXFLAGS+=-I. -O$(OPTIMIZE) -g
|
||||||
|
|
||||||
ifeq ($(LTO), 1)
|
ifeq ($(LTO), 1)
|
||||||
override CXXFLAGS+=-flto
|
override CXXFLAGS+=-flto
|
||||||
@ -43,7 +45,8 @@ SRCS= \
|
|||||||
programs/osxcross-conf.cpp \
|
programs/osxcross-conf.cpp \
|
||||||
programs/osxcross-cmp.cpp \
|
programs/osxcross-cmp.cpp \
|
||||||
programs/sw_vers.cpp \
|
programs/sw_vers.cpp \
|
||||||
programs/pkg-config.cpp
|
programs/pkg-config.cpp \
|
||||||
|
programs/xcrun.cpp
|
||||||
|
|
||||||
OBJS=$(subst .cpp,.o,$(SRCS))
|
OBJS=$(subst .cpp,.o,$(SRCS))
|
||||||
|
|
||||||
|
@ -149,6 +149,7 @@ create_wrapper_link pkg-config
|
|||||||
if [ "$PLATFORM" != "Darwin" ]; then
|
if [ "$PLATFORM" != "Darwin" ]; then
|
||||||
create_wrapper_link sw_vers 1
|
create_wrapper_link sw_vers 1
|
||||||
create_wrapper_link dsymutil 1
|
create_wrapper_link dsymutil 1
|
||||||
|
create_wrapper_link xcrun 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd &>/dev/null
|
popd &>/dev/null
|
||||||
|
207
wrapper/programs/xcrun.cpp
Normal file
207
wrapper/programs/xcrun.cpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
* OSXCross Compiler Wrapper *
|
||||||
|
* Copyright (C) 2014, 2015 by Thomas Poechtrager *
|
||||||
|
* t.poechtrager@gmail.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "proginc.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace tools;
|
||||||
|
using namespace target;
|
||||||
|
|
||||||
|
namespace program {
|
||||||
|
|
||||||
|
static bool showCommand = false;
|
||||||
|
|
||||||
|
bool getSDKPath(Target &target, std::string &SDKPath) {
|
||||||
|
if (!target.getSDKPath(SDKPath)) {
|
||||||
|
err << "xcrun: cannot find MacOSX SDK" << err.endl();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getToolPath(Target &target, std::string &toolpath, const char *tool) {
|
||||||
|
toolpath = target.execpath;
|
||||||
|
toolpath += "/";
|
||||||
|
toolpath += getArchName(target.arch);
|
||||||
|
toolpath += "-";
|
||||||
|
toolpath += getDefaultVendor();
|
||||||
|
toolpath += "-";
|
||||||
|
toolpath += getDefaultTarget();
|
||||||
|
toolpath += "-";
|
||||||
|
toolpath += tool;
|
||||||
|
|
||||||
|
if (!fileExists(toolpath.c_str())) {
|
||||||
|
// Fall back to system executables so 'xcrun git status' etc. works.
|
||||||
|
toolpath.clear();
|
||||||
|
|
||||||
|
if (realPath(tool, toolpath))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
err << "xcrun: cannot find '" << tool << "' executable" << err.endl();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int help(Target&, char **) {
|
||||||
|
std::cerr << "https://developer.apple.com/library/mac/documentation/Darwin/"
|
||||||
|
"Reference/ManPages/man1/xcrun.1.html" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int version(Target&, char **) {
|
||||||
|
std::cout << "xcrun version: 0." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sdk(Target&, char **argv) {
|
||||||
|
if (strcmp(argv[0], "macosx")) {
|
||||||
|
err << "xcrun: expected 'macosx' for '-sdk'" << err.endl();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int log(Target&, char**) {
|
||||||
|
showCommand = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find(Target &target, char **argv) {
|
||||||
|
if (argv[1])
|
||||||
|
return 1;
|
||||||
|
std::string toolpath;
|
||||||
|
if (!getToolPath(target, toolpath, argv[0]))
|
||||||
|
return 1;
|
||||||
|
std::cout << toolpath << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run(Target &target, char **argv) {
|
||||||
|
std::string toolpath;
|
||||||
|
std::string command;
|
||||||
|
if (!getToolPath(target, toolpath, argv[0]))
|
||||||
|
exit(1); // Should never return.
|
||||||
|
std::vector<char *> args;
|
||||||
|
args.push_back(const_cast<char *>(toolpath.c_str()));
|
||||||
|
for (char **arg = &argv[1]; *arg; ++arg)
|
||||||
|
args.push_back(*arg);
|
||||||
|
args.push_back(nullptr);
|
||||||
|
if (showCommand) {
|
||||||
|
for (size_t i = 0; i < args.size() - 1; ++i) {
|
||||||
|
std::cout << args[i];
|
||||||
|
if (i != args.size() - 2)
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
execvp(args[0], args.data());
|
||||||
|
err << "xcrun: cannot execute '" << args[0] << "'" << err.endl();
|
||||||
|
exit(1);
|
||||||
|
// Silence -Wreturn-type warnings in case exit() is not marked as
|
||||||
|
// "no-return" for whatever reason.
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int showSDKPath(Target &target, char **) {
|
||||||
|
std::string SDKPath;
|
||||||
|
if (!getSDKPath(target, SDKPath))
|
||||||
|
return 1;
|
||||||
|
std::cout << SDKPath << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int showSDKVersion(Target &target, char **) {
|
||||||
|
std::cout << target.getSDKOSNum().shortStr() << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xcrun(int argc, char **argv, Target &target) {
|
||||||
|
if (getenv("xcrun_log"))
|
||||||
|
showCommand = true;
|
||||||
|
|
||||||
|
constexpr const char *ENVVARS[] = {
|
||||||
|
"DEVELOPER_DIR", "SDKROOT", "TOOLCHAINS",
|
||||||
|
"xcrun_verbose"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const char *evar : ENVVARS) {
|
||||||
|
if (getenv(evar)) {
|
||||||
|
warn << "xcrun: ignoring environment variable '" << evar << "'"
|
||||||
|
<< warn.endl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dummy = [](Target&, char**) { return 0; };
|
||||||
|
|
||||||
|
ArgParser<int (*)(Target&, char**), 19> argParser = {{
|
||||||
|
{"h", help},
|
||||||
|
{"help", help},
|
||||||
|
{"version", version},
|
||||||
|
{"v", dummy},
|
||||||
|
{"verbose", dummy},
|
||||||
|
{"k", dummy},
|
||||||
|
{"kill-cache", dummy},
|
||||||
|
{"n", dummy},
|
||||||
|
{"no-cache", dummy},
|
||||||
|
{"sdk", sdk, 1},
|
||||||
|
{"toolchain", dummy, 1},
|
||||||
|
{"l", log },
|
||||||
|
{"log", log},
|
||||||
|
{"f", find, 1},
|
||||||
|
{"find", find, 1},
|
||||||
|
{"r", run, 1},
|
||||||
|
{"run", run, 1},
|
||||||
|
{"show-sdk-path", showSDKPath},
|
||||||
|
{"show-sdk-version", showSDKVersion}
|
||||||
|
}};
|
||||||
|
|
||||||
|
int retVal = 1;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
auto b = argParser.parseArg(argc, argv, i);
|
||||||
|
|
||||||
|
if (!b) {
|
||||||
|
if (argv[i][0] == '-') {
|
||||||
|
err << "xcrun: unknown argument: '" << argv[i] << "'" << err.endl();
|
||||||
|
retVal = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
run(target, &argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = b->fun(target, &argv[i + 1]);
|
||||||
|
|
||||||
|
if (retVal != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
i += b->numArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace program
|
@ -75,6 +75,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
int sw_vers(int argc, char **argv, target::Target &target);
|
int sw_vers(int argc, char **argv, target::Target &target);
|
||||||
|
int xcrun(int argc, char **argv, Target &target);
|
||||||
|
|
||||||
namespace osxcross {
|
namespace osxcross {
|
||||||
int version();
|
int version();
|
||||||
@ -87,6 +88,7 @@ int pkg_config(int argc, char **argv, Target &target);
|
|||||||
static int dummy() { return 0; }
|
static int dummy() { return 0; }
|
||||||
|
|
||||||
constexpr prog programs[] = { { "sw_vers", sw_vers },
|
constexpr prog programs[] = { { "sw_vers", sw_vers },
|
||||||
|
{ "xcrun", xcrun },
|
||||||
{ "dsymutil", dummy },
|
{ "dsymutil", dummy },
|
||||||
{ "osxcross", osxcross::version },
|
{ "osxcross", osxcross::version },
|
||||||
{ "osxcross-env", osxcross::env },
|
{ "osxcross-env", osxcross::env },
|
||||||
|
@ -229,6 +229,15 @@ bool Target::isCXX11orNewer() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &Target::getDefaultTriple(std::string &triple) const {
|
||||||
|
triple = getArchName(Arch::x86_64);
|
||||||
|
triple += "-";
|
||||||
|
triple += getDefaultVendor();
|
||||||
|
triple += "-";
|
||||||
|
triple += getDefaultTarget();
|
||||||
|
return triple;
|
||||||
|
}
|
||||||
|
|
||||||
void Target::setCompilerPath() {
|
void Target::setCompilerPath() {
|
||||||
if (isGCC()) {
|
if (isGCC()) {
|
||||||
compilerpath = execpath;
|
compilerpath = execpath;
|
||||||
|
@ -73,9 +73,10 @@ constexpr OSVersion getDefaultMinTarget() { return OSVersion(); }
|
|||||||
|
|
||||||
struct Target {
|
struct Target {
|
||||||
Target()
|
Target()
|
||||||
: vendor(getDefaultVendor()), target(getDefaultTarget()),
|
: vendor(getDefaultVendor()), arch(Arch::x86_64),
|
||||||
stdlib(StdLib::unset), usegcclibs(), nocodegen(),
|
target(getDefaultTarget()), stdlib(StdLib::unset), usegcclibs(),
|
||||||
compilername(getDefaultCompiler()), lang(), langstd(), sourcefile(),
|
nocodegen(), compilername(getDefaultCompiler()), lang(), langstd(),
|
||||||
|
sourcefile(),
|
||||||
outputname() {
|
outputname() {
|
||||||
if (!getExecutablePath(execpath, sizeof(execpath)))
|
if (!getExecutablePath(execpath, sizeof(execpath)))
|
||||||
abort();
|
abort();
|
||||||
@ -131,6 +132,7 @@ struct Target {
|
|||||||
const char *getLangName();
|
const char *getLangName();
|
||||||
bool isCXX11orNewer() const;
|
bool isCXX11orNewer() const;
|
||||||
|
|
||||||
|
const std::string &getDefaultTriple(std::string &triple) const;
|
||||||
const std::string &getTriple() const { return triple; }
|
const std::string &getTriple() const { return triple; }
|
||||||
|
|
||||||
void setCompilerPath();
|
void setCompilerPath();
|
||||||
|
@ -163,6 +163,43 @@ inline const char *getFileExtension(const std::string &file) {
|
|||||||
return getFileExtension(file.c_str());
|
return getFileExtension(file.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Argument Parsing
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T, size_t size = 0> struct ArgParser {
|
||||||
|
const struct Bind {
|
||||||
|
const char *name;
|
||||||
|
T fun;
|
||||||
|
int numArgs;
|
||||||
|
} binds[size];
|
||||||
|
|
||||||
|
const Bind *parseArg(int argc, char **argv, const int numArg = 1) {
|
||||||
|
const char *arg = argv[numArg];
|
||||||
|
|
||||||
|
if (*arg != '-')
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
while (*arg && *arg == '-')
|
||||||
|
++arg;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
const Bind &bind = binds[i];
|
||||||
|
|
||||||
|
if (!strcmp(arg, bind.name)) {
|
||||||
|
if (argc - numArg <= bind.numArgs) {
|
||||||
|
err << "too few arguments for '-" << bind.name << "'" << err.endl();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &bind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Time
|
// Time
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user