WebAssembly: Initial commit

This change adds WebAssembly support in the shape of a plugin.

- Auto-detection of the emsdk toolchain
- Handling of "asmjs-unknown-emscripten" Abi
- Binary detection of WebAssembly libraries
- Auto-creation of a "WebAssembly runtime" device (with icon)
- Runconfiguration that launches the application via the "emrun"
  tool which spawns a local web server and runs the application on
  the chosen web browser.

Limitations:
- So far only tested on Windows/MinGW and Linux
- Not yet tested with Qt WebAssembly installation form the installer
  Only tested with self-built Qt and manually added kit
- The attempt to launch an application via emrun, while a previous
  application is still running, will fail. The reason is that the
  web servers spawned by emrun listen to the same default port but
  serve only the content of one application.
  Possible solutions: We could either spawn the different web servers
  with different ports, or we could use one single web server instance
  which serves the whole default project location (home directory).

Task-number: QTCREATORBUG-21068
Task-number: QTCREATORBUG-22249
Change-Id: I1a16fbe52382d45c37e9bc624a943a6ca475fa09
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Alessandro Portale
2019-07-12 13:40:00 +02:00
parent 16a2241e7d
commit b89ad81293
31 changed files with 1204 additions and 1 deletions

View File

@@ -83,3 +83,4 @@ add_subdirectory(qbsprojectmanager)
#add_subdirectory(boot2qt)
add_subdirectory(qmldesigner)
add_subdirectory(qnx)
add_subdirectory(webassembly)

View File

@@ -61,7 +61,8 @@ SUBDIRS = \
cppcheck \
compilationdatabaseprojectmanager \
qmlpreview \
studiowelcome
studiowelcome \
webassembly
qtHaveModule(serialport) {
SUBDIRS += serialterminal

View File

@@ -74,6 +74,7 @@ Project {
"updateinfo/updateinfo.qbs",
"valgrind/valgrind.qbs",
"vcsbase/vcsbase.qbs",
"webassembly/webassembly.qbs",
"welcome/welcome.qbs",
"winrt/winrt.qbs"
].concat(project.additionalPlugins)

View File

@@ -161,6 +161,8 @@ static Abi::Architecture architectureFromQt()
return Abi::ShArchitecture;
if (arch.startsWith("avr")) // Not in Qt documentation!
return Abi::AvrArchitecture;
if (arch.startsWith("asmjs"))
return Abi::AsmJsArchitecture;
return Abi::UnknownArchitecture;
}
@@ -411,6 +413,11 @@ static Abis abiOf(const QByteArray &data)
result.append(macAbiForCpu(type));
pos += 20;
}
} else if (getUint8(data, 0) == 'B' && getUint8(data, 1) == 'C'
&& getUint8(data, 2) == 0xc0 && getUint8(data, 3) == 0xde) {
// https://llvm.org/docs/BitCodeFormat.html#llvm-ir-magic-number
result.append(Abi(Abi::AsmJsArchitecture, Abi::UnknownOS, Abi::UnknownFlavor,
Abi::EmscriptenFormat, 32));
} else if (data.size() >= 64){
// Windows PE: values are LE (except for a few exceptions which we will not use here).
@@ -543,6 +550,11 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
os = QnxOS;
flavor = GenericFlavor;
format = ElfFormat;
} else if (p.startsWith("emscripten")) {
format = EmscriptenFormat;
width = 32;
} else if (p.startsWith("asmjs")) {
arch = AsmJsArchitecture;
} else if (p == "none") {
os = BareMetalOS;
flavor = GenericFlavor;
@@ -677,6 +689,8 @@ QString Abi::toString(const Architecture &a)
return QLatin1String("itanium");
case ShArchitecture:
return QLatin1String("sh");
case AsmJsArchitecture:
return QLatin1String("asmjs");
case UnknownArchitecture:
Q_FALLTHROUGH();
default:
@@ -734,6 +748,8 @@ QString Abi::toString(const BinaryFormat &bf)
return QLatin1String("ubrof");
case OmfFormat:
return QLatin1String("omf");
case EmscriptenFormat:
return QLatin1String("emscripten");
case UnknownFormat:
Q_FALLTHROUGH();
default:
@@ -813,6 +829,8 @@ Abi::Architecture Abi::architectureFromString(const QStringRef &a)
return ShArchitecture;
else if (a == "xtensa")
return XtensaArchitecture;
if (a == "asmjs")
return AsmJsArchitecture;
return UnknownArchitecture;
}
@@ -865,6 +883,8 @@ Abi::BinaryFormat Abi::binaryFormatFromString(const QStringRef &bf)
return OmfFormat;
if (bf == "qml_rt")
return RuntimeQmlFormat;
if (bf == "emscripten")
return EmscriptenFormat;
return UnknownFormat;
}
@@ -1150,6 +1170,9 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiOfBinary_data()
QTest::newRow("static QtCore: linux 64bit")
<< QString::fromLatin1("%1/static/linux-64bit-release.a").arg(prefix)
<< (QStringList() << QString::fromLatin1("x86-linux-generic-elf-64bit"));
QTest::newRow("static QtCore: asmjs emscripten 32bit")
<< QString::fromLatin1("%1/static/asmjs-emscripten.a").arg(prefix)
<< (QStringList() << QString::fromLatin1("asmjs-unknown-unknown-emscripten-32bit"));
QTest::newRow("static stdc++: mac fat")
<< QString::fromLatin1("%1/static/mac-fat.a").arg(prefix)
@@ -1350,6 +1373,10 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data()
QTest::newRow("avr") << int(Abi::AvrArchitecture)
<< int(Abi::BareMetalOS) << int(Abi::GenericFlavor)
<< int(Abi::ElfFormat) << 16;
QTest::newRow("asmjs-unknown-emscripten") << int(Abi::AsmJsArchitecture)
<< int(Abi::UnknownOS) << int(Abi::UnknownFlavor)
<< int(Abi::EmscriptenFormat) << 32;
}
void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet()

View File

@@ -58,6 +58,7 @@ public:
AvrArchitecture,
XtensaArchitecture,
Mcs51Architecture,
AsmJsArchitecture,
UnknownArchitecture
};
@@ -114,6 +115,7 @@ public:
RuntimeQmlFormat,
UbrofFormat,
OmfFormat,
EmscriptenFormat,
UnknownFormat
};

View File

@@ -1439,6 +1439,8 @@ QStringList ClangToolChain::suggestedMkspecList() const
return {"linux-clang", "unsupported/linux-clang"};
if (abi.os() == Abi::WindowsOS)
return {"win32-clang-g++"};
if (abi.architecture() == Abi::AsmJsArchitecture && abi.binaryFormat() == Abi::EmscriptenFormat)
return {"wasm-emscripten"};
return {}; // Note: Not supported by Qt yet, so default to the mkspec the Qt was build with
}

View File

@@ -0,0 +1,14 @@
add_qtc_plugin(WebAssembly
DEPENDS Qt5::Core
PLUGIN_DEPENDS Core ProjectExplorer QtSupport
SOURCES
webassembly.qrc
webassembly_global.h
webassemblyconstants.h
webassemblydevice.cpp webassemblydevice.h
webassemblyplugin.cpp webassemblyplugin.h
webassemblyqtversion.cpp webassemblyqtversion.h
webassemblyrunconfigurationaspects.cpp webassemblyrunconfigurationaspects.h
webassemblyrunconfiguration.cpp webassemblyrunconfiguration.h
webassemblytoolchain.cpp webassemblytoolchain.h
)

View File

@@ -0,0 +1,20 @@
{
\"Name\" : \"WebAssembly\",
\"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
\"Experimental\" : true,
\"Vendor\" : \"The Qt Company Ltd\",
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
\"License\" : [ \"Commercial Usage\",
\"\",
\"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company.\",
\"\",
\"GNU General Public License Usage\",
\"\",
\"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\"
],
\"Category\" : \"Device Support\",
\"Description\" : \"Helper for WebAssembly projects.\",
\"Url\" : \"http://www.qt.io\",
$$dependencyList
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

View File

@@ -0,0 +1,22 @@
include(../../qtcreatorplugin.pri)
HEADERS += \
webassembly_global.h \
webassemblyconstants.h \
webassemblydevice.h \
webassemblyplugin.h \
webassemblyqtversion.h \
webassemblyrunconfigurationaspects.h \
webassemblyrunconfiguration.h \
webassemblytoolchain.h
SOURCES += \
webassemblydevice.cpp \
webassemblyplugin.cpp \
webassemblyqtversion.cpp \
webassemblyrunconfigurationaspects.cpp \
webassemblyrunconfiguration.cpp \
webassemblytoolchain.cpp
RESOURCES += \
webassembly.qrc

View File

@@ -0,0 +1,31 @@
import qbs 1.0
QtcPlugin {
name: "WebAssembly"
Depends { name: "Qt.core" }
Depends { name: "Qt.widgets" }
Depends { name: "Utils" }
Depends { name: "Core" }
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
files: [
"webassembly.qrc",
"webassembly_global.h",
"webassemblyconstants.h",
"webassemblydevice.cpp",
"webassemblydevice.h",
"webassemblyplugin.cpp",
"webassemblyplugin.h",
"webassemblyqtversion.cpp",
"webassemblyqtversion.h",
"webassemblyrunconfigurationaspects.cpp",
"webassemblyrunconfigurationaspects.h",
"webassemblyrunconfiguration.cpp",
"webassemblyrunconfiguration.h",
"webassemblytoolchain.cpp",
"webassemblytoolchain.h",
]
}

View File

@@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/webassembly">
<file>images/webassemblydevice.png</file>
<file>images/webassemblydevice@2x.png</file>
<file>images/webassemblydevicesmall.png</file>
<file>images/webassemblydevicesmall@2x.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,10 @@
QTC_PLUGIN_NAME = WebAssembly
QTC_LIB_DEPENDS += \
extensionsystem \
utils
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer \
qtsupport

View File

@@ -0,0 +1,34 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QtGlobal>
#if defined(WEBASSEMBLY_LIBRARY)
# define WEBASSEMBLYSHARED_EXPORT Q_DECL_EXPORT
#else
# define WEBASSEMBLYSHARED_EXPORT Q_DECL_IMPORT
#endif

View File

@@ -0,0 +1,38 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
namespace WebAssembly {
namespace Constants {
const char WEBASSEMBLY_TOOLCHAIN_TYPEID[] = "WebAssembly.ToolChain.Emscripten";
const char WEBASSEMBLY_DEVICE_TYPE[] = "WebAssemblyDeviceType";
const char WEBASSEMBLY_DEVICE_DEVICE_ID[] = "WebAssembly Device";
const char WEBASSEMBLY_QT_VERSION[] = "Qt4ProjectManager.QtVersion.WebAssembly";
const char WEBASSEMBLY_RUNCONFIGURATION_EMRUN[] = "WebAssembly.RunConfiguration.Emrun";
} // namespace WebAssembly
} // namespace Constants

View File

@@ -0,0 +1,80 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblyconstants.h"
#include "webassemblydevice.h"
namespace WebAssembly {
namespace Internal {
WebAssemblyDevice::WebAssemblyDevice()
{
setupId(IDevice::AutoDetected, Constants::WEBASSEMBLY_DEVICE_DEVICE_ID);
setType(Constants::WEBASSEMBLY_DEVICE_TYPE);
const QString displayNameAndType = tr("Web Browser");
setDisplayName(displayNameAndType);
setDisplayType(displayNameAndType);
setDeviceState(IDevice::DeviceStateUnknown);
setMachineType(IDevice::Hardware);
}
ProjectExplorer::IDevice::Ptr WebAssemblyDevice::create()
{
auto device = new WebAssemblyDevice;
return ProjectExplorer::IDevice::Ptr(device);
}
Utils::OsType WebAssemblyDevice::osType() const
{
return Utils::OsTypeOther;
}
ProjectExplorer::IDeviceWidget *WebAssemblyDevice::createWidget()
{
return nullptr;
}
ProjectExplorer::DeviceProcessSignalOperation::Ptr WebAssemblyDevice::signalOperation() const
{
return {};
}
WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
: ProjectExplorer::IDeviceFactory(Constants::WEBASSEMBLY_DEVICE_TYPE)
{
setDisplayName(tr("WebAssembly Runtime"));
setCombinedIcon(":/webassembly/images/webassemblydevicesmall.png",
":/webassembly/images/webassemblydevice.png");
setCanCreate(true);
setConstructionFunction(&WebAssemblyDevice::create);
}
ProjectExplorer::IDevice::Ptr WebAssemblyDeviceFactory::create() const
{
return WebAssemblyDevice::create();
}
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/devicesupport/idevicefactory.h>
#include <QCoreApplication>
namespace WebAssembly {
namespace Internal {
class WebAssemblyDevice : public ProjectExplorer::IDevice
{
Q_DECLARE_TR_FUNCTIONS(WebAssembly::Internal::WebAssemblyDevice)
public:
static ProjectExplorer::IDevice::Ptr create();
Utils::OsType osType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
private:
WebAssemblyDevice();
};
class WebAssemblyDeviceFactory : public ProjectExplorer::IDeviceFactory
{
Q_OBJECT
public:
WebAssemblyDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,83 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblyplugin.h"
#include "webassemblyconstants.h"
#include "webassemblydevice.h"
#include "webassemblyqtversion.h"
#include "webassemblyrunconfiguration.h"
#include "webassemblytoolchain.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <QMenu>
#include <QMessageBox>
namespace WebAssembly {
namespace Internal {
class WebAssemblyPluginPrivate
{
public:
WebAssemblyToolChainFactory toolChainFactory;
WebAssemblyDeviceFactory deviceFactory;
WebAssemblyQtVersionFactory qtVersionFactory;
EmrunRunConfigurationFactory emrunRunConfigurationFactory;
};
static WebAssemblyPluginPrivate *dd = nullptr;
WebAssemblyPlugin::WebAssemblyPlugin()
{
setObjectName("WebAssemblyPlugin");
}
WebAssemblyPlugin::~WebAssemblyPlugin()
{
delete dd;
dd = nullptr;
}
bool WebAssemblyPlugin::initialize(const QStringList& arguments, QString* errorString)
{
Q_UNUSED(arguments)
Q_UNUSED(errorString)
dd = new WebAssemblyPluginPrivate;
return true;
}
void WebAssemblyPlugin::extensionsInitialized()
{
ProjectExplorer::DeviceManager::instance()->addDevice(WebAssemblyDevice::create());
}
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,49 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "webassembly_global.h"
#include <extensionsystem/iplugin.h>
namespace WebAssembly {
namespace Internal {
class WebAssemblyPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "WebAssembly.json")
public:
WebAssemblyPlugin();
~WebAssemblyPlugin() override;
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override;
};
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,65 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblyconstants.h"
#include "webassemblyqtversion.h"
#include <projectexplorer/abi.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <remotelinux/remotelinux_constants.h>
#include <coreplugin/featureprovider.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QFileInfo>
namespace WebAssembly {
namespace Internal {
WebAssemblyQtVersion::WebAssemblyQtVersion() = default;
QString WebAssemblyQtVersion::description() const
{
return QCoreApplication::translate("WebAssemblyPlugin", "WebAssembly",
"Qt Version is meant for WebAssembly");
}
QSet<Core::Id> WebAssemblyQtVersion::targetDeviceTypes() const
{
return {Constants::WEBASSEMBLY_DEVICE_TYPE};
}
WebAssemblyQtVersionFactory::WebAssemblyQtVersionFactory()
{
setQtVersionCreator([] { return new WebAssemblyQtVersion; });
setSupportedType(Constants::WEBASSEMBLY_QT_VERSION);
setPriority(1);
}
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,51 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <qtsupport/qtversionfactory.h>
#include <qtsupport/baseqtversion.h>
namespace WebAssembly {
namespace Internal {
class WebAssemblyQtVersion : public QtSupport::BaseQtVersion
{
public:
WebAssemblyQtVersion();
QString description() const override;
QSet<Core::Id> targetDeviceTypes() const override;
};
class WebAssemblyQtVersionFactory : public QtSupport::QtVersionFactory
{
public:
WebAssemblyQtVersionFactory();
};
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,91 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblyrunconfigurationaspects.h"
#include "webassemblyrunconfiguration.h"
#include "webassemblyconstants.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/target.h>
#include <QDir>
namespace WebAssembly {
namespace Internal {
EmrunRunConfiguration::EmrunRunConfiguration(ProjectExplorer::Target *target,
Core::Id id)
: ProjectExplorer::CustomExecutableRunConfiguration(target, id)
{
auto executableAspect = aspect<ProjectExplorer::ExecutableAspect>();
executableAspect->setExecutable(
target->activeBuildConfiguration()->environment().searchInPath("python"));
executableAspect->setVisible(false);
auto workingDirectoryAspect = aspect<ProjectExplorer::WorkingDirectoryAspect>();
workingDirectoryAspect->setVisible(false);
auto terminalAspect = aspect<ProjectExplorer::TerminalAspect>();
terminalAspect->setVisible(false);
auto argumentsAspect = aspect<ProjectExplorer::ArgumentsAspect>();
argumentsAspect->setVisible(false);
auto webBrowserAspect = addAspect<WebBrowserSelectionAspect>(target);
connect(webBrowserAspect, &WebBrowserSelectionAspect::changed,
this, &EmrunRunConfiguration::updateConfiguration);
connect(target->activeBuildConfiguration(),
&ProjectExplorer::BuildConfiguration::buildDirectoryChanged,
this, &EmrunRunConfiguration::updateConfiguration);
addAspect<EffectiveEmrunCallAspect>();
updateConfiguration();
}
EmrunRunConfigurationFactory::EmrunRunConfigurationFactory()
: ProjectExplorer::FixedRunConfigurationFactory(
EmrunRunConfiguration::tr("Launch with emrun"))
{
registerRunConfiguration<EmrunRunConfiguration>(Constants::WEBASSEMBLY_RUNCONFIGURATION_EMRUN);
addSupportedTargetDeviceType(Constants::WEBASSEMBLY_DEVICE_TYPE);
}
void EmrunRunConfiguration::updateConfiguration()
{
const QFileInfo emrunScript =
target()->activeBuildConfiguration()->environment().searchInPath("emrun").toFileInfo();
const QString arguments =
emrunScript.absolutePath() + "/" + emrunScript.baseName() + ".py "
+ QString("--browser %1 ").arg(aspect<WebBrowserSelectionAspect>()->currentBrowser())
+ "--no_emrun_detect "
+ target()->activeBuildConfiguration()->buildDirectory().toString()
+ macroExpander()->expandProcessArgs("/%{CurrentProject:Name}.html");
aspect<ProjectExplorer::ArgumentsAspect>()->setArguments(arguments);
aspect<EffectiveEmrunCallAspect>()->setValue(commandLine().toUserOutput());
}
} // namespace Internal
} // namespace Webassembly

View File

@@ -0,0 +1,55 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/customexecutablerunconfiguration.h>
namespace ProjectExplorer {
class Target;
}
namespace WebAssembly {
namespace Internal {
// Runs a webassembly application via emscripten's "emrun" tool
// https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html
class EmrunRunConfiguration : public ProjectExplorer::CustomExecutableRunConfiguration
{
public:
EmrunRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
private:
void updateConfiguration();
};
class EmrunRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
{
public:
EmrunRunConfigurationFactory();
};
} // namespace Internal
} // namespace Webassembly

View File

@@ -0,0 +1,114 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblyrunconfigurationaspects.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
#include <QComboBox>
#include <QFormLayout>
namespace WebAssembly {
namespace Internal {
static const char BROWSER_KEY[] = "WASM.WebBrowserSelectionAspect.Browser";
static QStringList detectedBrowsers(ProjectExplorer::Target *target)
{
static QStringList result;
if (result.isEmpty()) {
const Utils::Environment environment = target->activeBuildConfiguration()->environment();
const Utils::FilePath emrunPath = environment.searchInPath("emrun");
QProcess browserLister;
browserLister.setProcessEnvironment(environment.toProcessEnvironment());
browserLister.setProgram(emrunPath.toString());
browserLister.setArguments({"--list_browsers"});
browserLister.start(QIODevice::ReadOnly);
if (browserLister.waitForFinished()) {
const QByteArray output = browserLister.readAllStandardOutput();
QTextStream ts(output);
QString line;
const QRegularExpression regExp(" - (.*):.*");
while (ts.readLineInto(&line)) {
const QRegularExpressionMatch match = regExp.match(line);
if (match.hasMatch())
result << match.captured(1);
}
}
}
return result;
}
WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *target)
: m_availableBrowsers(detectedBrowsers(target))
{
m_currentBrowser = m_availableBrowsers.first();
setDisplayName(tr("Web browser"));
setId("WebBrowserAspect");
setSettingsKey("RunConfiguration.WebBrowser");
}
void WebBrowserSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
{
QTC_CHECK(!m_webBrowserComboBox);
m_webBrowserComboBox = new QComboBox(layout->parentWidget());
m_webBrowserComboBox->addItems(m_availableBrowsers);
m_webBrowserComboBox->setCurrentText(m_currentBrowser);
connect(m_webBrowserComboBox, &QComboBox::currentTextChanged,
[this](const QString &selectedBrowser){
m_currentBrowser = selectedBrowser;
emit changed();
});
layout->addRow(tr("Web browser:"), m_webBrowserComboBox);
}
void WebBrowserSelectionAspect::fromMap(const QVariantMap &map)
{
m_currentBrowser = map.value(BROWSER_KEY, m_availableBrowsers.first()).toString();
}
void WebBrowserSelectionAspect::toMap(QVariantMap &map) const
{
map.insert(BROWSER_KEY, m_currentBrowser);
}
QString WebBrowserSelectionAspect::currentBrowser() const
{
return m_currentBrowser;
}
EffectiveEmrunCallAspect::EffectiveEmrunCallAspect()
{
setLabelText(tr("Effective emrun call:"));
setDisplayStyle(BaseStringAspect::TextEditDisplay);
setReadOnly(true);
}
} // namespace Internal
} // namespace Webassembly

View File

@@ -0,0 +1,64 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/runconfigurationaspects.h>
QT_FORWARD_DECLARE_CLASS(QComboBox)
namespace WebAssembly {
namespace Internal {
class WebBrowserSelectionAspect : public ProjectExplorer::ProjectConfigurationAspect
{
Q_OBJECT
public:
WebBrowserSelectionAspect(ProjectExplorer::Target *target);
void addToConfigurationLayout(QFormLayout *layout) override;
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
QString currentBrowser() const;
private:
QComboBox *m_webBrowserComboBox = nullptr;
QString m_currentBrowser;
QStringList m_availableBrowsers;
};
class EffectiveEmrunCallAspect : public ProjectExplorer::BaseStringAspect
{
Q_OBJECT
public:
EffectiveEmrunCallAspect();
};
} // namespace Internal
} // namespace Webassembly

View File

@@ -0,0 +1,170 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "webassemblytoolchain.h"
#include "webassemblyconstants.h"
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <projectexplorer/abiwidget.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/toolchainmanager.h>
#include <QDir>
#include <QSettings>
namespace WebAssembly {
namespace Internal {
// See https://emscripten.org/docs/tools_reference/emsdk.html#compiler-configuration-file
struct CompilerConfiguration
{
Utils::FilePath emSdk;
Utils::FilePath llvmRoot;
Utils::FilePath emConfig;
Utils::FilePath emscriptenNativeOptimizer;
Utils::FilePath binaryEnRoot;
Utils::FilePath emSdkNode;
Utils::FilePath emSdkPython;
Utils::FilePath javaHome;
Utils::FilePath emScripten;
};
static Utils::FilePath compilerConfigurationFile()
{
return Utils::FilePath::fromString(QDir::homePath() + "/.emscripten");
}
static CompilerConfiguration compilerConfiguration()
{
const QSettings configuration(compilerConfigurationFile().toString(), QSettings::IniFormat);
auto configPath = [&configuration](const QString &key){
return Utils::FilePath::fromString(configuration.value(key).toString().remove('\''));
};
const Utils::FilePath llvmRoot = configPath("LLVM_ROOT");
return {
llvmRoot.parentDir().parentDir(),
llvmRoot,
compilerConfigurationFile(),
configPath("EMSCRIPTEN_NATIVE_OPTIMIZER"),
configPath("BINARYEN_ROOT"),
configPath("NODE_JS"),
configPath("PYTHON"),
configPath("JAVA").parentDir().parentDir(),
configPath("EMSCRIPTEN_ROOT")
};
}
static ProjectExplorer::Abi toolChainAbi()
{
return {
ProjectExplorer::Abi::AsmJsArchitecture,
ProjectExplorer::Abi::UnknownOS,
ProjectExplorer::Abi::UnknownFlavor,
ProjectExplorer::Abi::EmscriptenFormat,
32
};
}
void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const
{
const CompilerConfiguration configuration = compilerConfiguration();
env.prependOrSetPath(configuration.emScripten.toUserOutput());
env.prependOrSetPath(configuration.javaHome.toUserOutput() + "/bin");
env.prependOrSetPath(configuration.emSdkPython.parentDir().toUserOutput());
env.prependOrSetPath(configuration.emSdkNode.parentDir().toUserOutput());
env.prependOrSetPath(configuration.llvmRoot.toUserOutput());
env.prependOrSetPath(configuration.emSdk.toUserOutput());
env.set("EMSDK", configuration.emSdk.toUserOutput());
env.set("EM_CONFIG", configuration.emConfig.toUserOutput());
env.set("LLVM_ROOT", configuration.llvmRoot.toUserOutput());
env.set("EMSCRIPTEN_NATIVE_OPTIMIZER", configuration.emscriptenNativeOptimizer.toUserOutput());
env.set("BINARYEN_ROOT", configuration.binaryEnRoot.toUserOutput());
env.set("EMSDK_NODE", configuration.emSdkNode.toUserOutput());
env.set("EMSDK_PYTHON", configuration.emSdkPython.toUserOutput());
env.set("JAVA_HOME", configuration.javaHome.toUserOutput());
env.set("EMSCRIPTEN", configuration.emScripten.toUserOutput());
}
WebAssemblyToolChain::WebAssemblyToolChain() :
ClangToolChain(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID)
{
const CompilerConfiguration configuration = compilerConfiguration();
const QString command = configuration.llvmRoot.toString()
+ Utils::HostOsInfo::withExecutableSuffix("/clang");
setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
setCompilerCommand(Utils::FilePath::fromString(command));
setSupportedAbis({toolChainAbi()});
setTargetAbi(toolChainAbi());
const QString typeAndDisplayName = WebAssemblyToolChainFactory::tr("Emscripten Compiler");
setDisplayName(typeAndDisplayName);
setTypeDisplayName(typeAndDisplayName);
}
bool WebAssemblyToolChain::fromMap(const QVariantMap &data)
{
if (!ClangToolChain::fromMap(data))
return false;
// TODO: HACK: GccToolChain::fromMap() filters out abis with UnknownOS. Re-add it, here.
if (supportedAbis().isEmpty())
setSupportedAbis({toolChainAbi()});
return true;
}
WebAssemblyToolChainFactory::WebAssemblyToolChainFactory()
{
setDisplayName(tr("WebAssembly"));
setSupportedToolChainType(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID);
setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID,
ProjectExplorer::Constants::CXX_LANGUAGE_ID});
setToolchainConstructor([] { return new WebAssemblyToolChain; });
setUserCreatable(true);
}
QList<ProjectExplorer::ToolChain *> WebAssemblyToolChainFactory::autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown)
{
Q_UNUSED(alreadyKnown)
auto cToolChain = new WebAssemblyToolChain;
cToolChain->setLanguage(ProjectExplorer::Constants::C_LANGUAGE_ID);
cToolChain->setDetection(ProjectExplorer::ToolChain::AutoDetection);
auto cxxToolChain = new WebAssemblyToolChain;
cxxToolChain->setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
cxxToolChain->setDetection(ProjectExplorer::ToolChain::AutoDetection);
return {cToolChain, cxxToolChain};
}
} // namespace Internal
} // namespace WebAssembly

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/gcctoolchain.h>
namespace WebAssembly {
namespace Internal {
class WebAssemblyToolChain final : public ProjectExplorer::ClangToolChain
{
public:
void addToEnvironment(Utils::Environment &env) const override;
protected:
bool fromMap(const QVariantMap &data) override;
private:
WebAssemblyToolChain();
friend class WebAssemblyToolChainFactory;
};
class WebAssemblyToolChainFactory : public ProjectExplorer::ToolChainFactory
{
Q_OBJECT
public:
WebAssemblyToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown) override;
};
} // namespace Internal
} // namespace WebAssembly

View File

@@ -10205,6 +10205,54 @@
width="100%"
height="100%" />
</g>
<g
id="src/plugins/webassembly/images/webassemblydevice"
transform="translate(-67.75,310.5)">
<use
height="100%"
width="100%"
id="use6196"
xlink:href="#backgroundRect_32_28"
y="0"
x="0"
style="display:inline"
transform="translate(458.75,5.5)" />
<path
sodipodi:nodetypes="czcccccc"
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 519.75,48.5 c 0,1.5 -1.25,3 -3,3 -1.75,0 -3,-1.5 -3,-3 h -9 v 24 h 24 v -24 z"
id="path2499" />
<path
sodipodi:nodetypes="cccccccccccccccccccccccccccc"
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="m 510.13397,61.5 h 1.60194 l 1.1035,6.125017 L 514.1637,61.5 h 1.49846 l 1.19888,6.200194 L 518.11917,61.5 h 1.57114 l -2.04153,9 h -1.58969 L 514.86632,64.374983 513.59062,70.5 h -1.61932 z m 11.36247,0 h 2.52534 l 2.50797,9 h -1.65249 l -0.8658,-3 h -2.3347 l -0.64281,3 h -1.60945 z m 0.99617,2 -0.63495,3 h 1.97747 l -0.73843,-3 z"
id="path2501" />
</g>
<g
transform="translate(-138,27)"
id="src/plugins/webassembly/images/webassemblydevicesmall">
<use
transform="translate(586,-73)"
height="100%"
width="100%"
id="use6204"
xlink:href="#backgroundRect"
y="0"
x="0" />
<path
sodipodi:nodetypes="czcccccc"
style="fill:#000000"
inkscape:connector-curvature="0"
d="m 580,365 c 0,0.75 -0.5,2 -2,2 -1.5,0 -2,-1.25 -2,-2 h -4 v 12 h 12 v -12 z"
id="path2499-9" />
<path
id="path2526"
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel"
d="m 579.5,373.5 h 3 m -3,2.5 v -4 l 1.5,-2 1.5,2 v 4 m -9,-6 v 3 l 1,3 1,-4 1,4 1,-3 v -3"
inkscape:connector-curvature="0" />
</g>
<g
id="src/plugins/winrt/images/winrtdevice"
transform="translate(-206,-74)">

Before

Width:  |  Height:  |  Size: 376 KiB

After

Width:  |  Height:  |  Size: 378 KiB