Wasm: Some steps towards making it work on docker

To start using the docker bits the emsdk location has to
be specified manually in the path selector as
docker://<id-of-image>/<path/to/emsdk>

Change-Id: I70c6e7a334762953c3931105b7f697c608523159
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2021-07-06 14:15:29 +02:00
parent 05545adb93
commit b998ad621b
5 changed files with 44 additions and 39 deletions

View File

@@ -1168,11 +1168,8 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path)
&& getUint8(data, 6) == '>' && getUint8(data, 7) == 0x0a) {
// We got an ar file: possibly a static lib for ELF, PE or Mach-O
// FIXME: Implement remote
QTC_ASSERT(!path.needsDevice(), return tmp);
QFile f(path.toString());
if (!f.open(QFile::ReadOnly))
return tmp;
const bool canRead = f.open(QFile::ReadOnly);
data = data.mid(8); // Cut of ar file magic
quint64 offset = 8;
@@ -1199,6 +1196,11 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path)
if (!tmp.isEmpty() && tmp.at(0).binaryFormat() != MachOFormat)
break;
if (!canRead) {
// FIXME: Implement remote
QTC_ASSERT(!path.needsDevice(), return {});
}
offset += (offset % 2); // ar is 2 byte aligned
f.seek(offset);
data = f.read(1024);

View File

@@ -321,7 +321,9 @@ FilePath IDevice::searchExecutableInPath(const QString &fileName) const
FilePath IDevice::searchExecutable(const QString &fileName, const FilePaths &dirs) const
{
for (const FilePath &dir : dirs) {
for (FilePath dir : dirs) {
if (!handlesFile(dir)) // Allow device-local dirs to be used.
dir = mapToGlobalPath(dir);
QTC_CHECK(handlesFile(dir));
const FilePath candidate = dir / fileName;
if (isExecutableFile(candidate))

View File

@@ -43,35 +43,36 @@ using namespace Utils;
namespace WebAssembly {
namespace Internal {
using EmSdkEnvCache = QCache<QString, QByteArray>;
using EmSdkEnvCache = QCache<QString, QString>;
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkEnvCache, emSdkEnvCache, (10))
using EmSdkVersionCache = QCache<QString, QVersionNumber>;
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkVersionCache, emSdkVersionCache, (10))
static QByteArray emSdkEnvOutput(const FilePath &sdkRoot)
static QString emSdkEnvOutput(const FilePath &sdkRoot)
{
const QString cacheKey = sdkRoot.toString();
const bool isWindows = sdkRoot.osType() == OsTypeWindows;
if (!emSdkEnvCache()->contains(cacheKey)) {
const QString scriptFile = sdkRoot.pathAppended(QLatin1String("emsdk_env") +
(HostOsInfo::isWindowsHost() ? ".bat" : ".sh")).toString();
(isWindows ? ".bat" : ".sh")).path();
QtcProcess emSdkEnv;
if (HostOsInfo::isWindowsHost()) {
if (isWindows) {
emSdkEnv.setCommand(CommandLine(scriptFile));
} else {
// File needs to be source'd, not executed.
emSdkEnv.setCommand({"bash", {"-c", ". " + scriptFile}});
emSdkEnv.setCommand({FilePath::fromString("bash").onDevice(sdkRoot),
{"-c", ". " + scriptFile}});
}
emSdkEnv.start();
if (!emSdkEnv.waitForFinished())
return {};
emSdkEnvCache()->insert(cacheKey, new QByteArray(emSdkEnv.readAllStandardError()));
emSdkEnv.runBlocking();
const QString output = emSdkEnv.allOutput();
emSdkEnvCache()->insert(cacheKey, new QString(output));
}
return *emSdkEnvCache()->object(cacheKey);
}
static void parseEmSdkEnvOutputAndAddToEnv(const QByteArray &output, Environment &env)
static void parseEmSdkEnvOutputAndAddToEnv(const QString &output, Environment &env)
{
const QStringList lines = QString::fromLocal8Bit(output).split('\n');
const QStringList lines = output.split('\n');
for (const QString &line : lines) {
const QStringList prependParts = line.trimmed().split(" += ");
@@ -104,18 +105,17 @@ QVersionNumber WebAssemblyEmSdk::version(const FilePath &sdkRoot)
return {};
const QString cacheKey = sdkRoot.toString();
if (!emSdkVersionCache()->contains(cacheKey)) {
Environment env = Environment::systemEnvironment();
Environment env;
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
const QString scriptFile =
QLatin1String("emcc") + QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : "");
const CommandLine command(env.searchInPath(scriptFile), {"-dumpversion"});
QLatin1String scriptFile{sdkRoot.osType() == OsType::OsTypeWindows ? "emcc.bat" : "emcc"};
FilePath script =
FilePath::fromString(scriptFile).onDevice(sdkRoot).searchOnDevice(env.path());
const CommandLine command(script, {"-dumpversion"});
QtcProcess emcc;
emcc.setCommand(command);
emcc.setEnvironment(env);
emcc.start();
if (!emcc.waitForFinished())
return {};
const QString version = QLatin1String(emcc.readAllStandardOutput());
emcc.runBlocking();
const QString version = emcc.stdOut();
emSdkVersionCache()->insert(cacheKey,
new QVersionNumber(QVersionNumber::fromString(version)));
}
@@ -148,7 +148,7 @@ void WebAssemblyEmSdk::clearCaches()
void WebAssemblyPlugin::testEmSdkEnvParsing()
{
// Output of "emsdk_env"
const QByteArray emSdkEnvOutput = HostOsInfo::isWindowsHost() ?
const QString emSdkEnvOutput = QString::fromLatin1(HostOsInfo::isWindowsHost() ?
R"(
Adding directories to PATH:
PATH += C:\Users\user\dev\emsdk
@@ -177,7 +177,7 @@ EMSDK = /home/user/dev/emsdk
EM_CONFIG = /home/user/dev/emsdk/.emscripten
EM_CACHE = /home/user/dev/emsdk/upstream/emscripten/cache
EMSDK_NODE = /home/user/dev/emsdk/node/12.18.1_64bit/bin/node
)";
)");
Environment env;
parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env);

View File

@@ -129,7 +129,7 @@ static QString environmentDisplay(const FilePath &sdkRoot)
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
QString result;
result.append(WebAssemblyOptionsWidget::tr("<h4>Adding directories to PATH:</h4>"));
result.append(env.value("PATH").replace(HostOsInfo::pathListSeparator(), "<br/>"));
result.append(env.value("PATH").replace(OsSpecificAspects::pathListSeparator(sdkRoot.osType()), "<br/>"));
result.append(WebAssemblyOptionsWidget::tr("<h4>Setting environment variables:</h4>"));
for (const QString &envVar : env.toStringList()) {
if (!envVar.startsWith("PATH")) // Path was already printed out above

View File

@@ -27,20 +27,20 @@
#include "webassemblyconstants.h"
#include "webassemblyemsdk.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/toolchainmanager.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <QDir>
#include <QSettings>
using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils;
@@ -73,7 +73,7 @@ static void addRegisteredMinGWToEnvironment(Environment &env)
void WebAssemblyToolChain::addToEnvironment(Environment &env) const
{
WebAssemblyEmSdk::addToEnvironment(WebAssemblyEmSdk::registeredEmSdk(), env);
if (HostOsInfo::isWindowsHost())
if (env.osType() == OsTypeWindows)
addRegisteredMinGWToEnvironment(env);
}
@@ -88,9 +88,9 @@ WebAssemblyToolChain::WebAssemblyToolChain() :
FilePath WebAssemblyToolChain::makeCommand(const Environment &environment) const
{
// Diverged duplicate of ClangToolChain::makeCommand and MingwToolChain::makeCommand
const QStringList makes
= HostOsInfo::isWindowsHost() ? QStringList({"mingw32-make.exe", "make.exe"})
: QStringList({"make"});
const QStringList makes = environment.osType() == OsTypeWindows
? QStringList({"mingw32-make.exe", "make.exe"})
: QStringList({"make"});
FilePath tmp;
for (const QString &make : makes) {
@@ -162,13 +162,12 @@ QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect(
const IDevice::Ptr &device)
{
Q_UNUSED(alreadyKnown)
Q_UNUSED(device)
const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk();
if (!WebAssemblyEmSdk::isValid(sdk))
return {};
Environment env;
Environment env = sdk.deviceEnvironment();
WebAssemblyEmSdk::addToEnvironment(sdk, env);
QList<ToolChain *> result;
@@ -178,9 +177,11 @@ QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect(
toolChain->setLanguage(languageId);
toolChain->setDetection(ToolChain::AutoDetection);
const bool cLanguage = languageId == ProjectExplorer::Constants::C_LANGUAGE_ID;
const QString scriptFile = QLatin1String(cLanguage ? "emcc" : "em++")
+ QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : "");
toolChain->setCompilerCommand(env.searchInPath(scriptFile));
const QString script = QLatin1String(cLanguage ? "emcc" : "em++")
+ QLatin1String(sdk.osType() == OsTypeWindows ? ".bat" : "");
const FilePath scriptFile =
FilePath::fromString(script).onDevice(sdk).searchOnDevice(env.path());
toolChain->setCompilerCommand(scriptFile);
const QString displayName = WebAssemblyToolChain::tr("Emscripten Compiler %1 for %2")
.arg(toolChain->version(), QLatin1String(cLanguage ? "C" : "C++"));