Skip to content

Commit

Permalink
Port wasm build to cmake (#4085)
Browse files Browse the repository at this point in the history
* Port wasm build to cmake

* Remove qmake for wasm

* Fix taskcluster builds
  • Loading branch information
bakulf authored Aug 1, 2022
1 parent f9556b8 commit 3ae9aea
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 192 deletions.
21 changes: 9 additions & 12 deletions .github/workflows/wasm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,6 @@ jobs:
python3 -m aqt install-qt -O /opt linux desktop $QTVERSION
python3 -m aqt install-qt -O /opt linux desktop $QTVERSION wasm_32 -m qtcharts qtwebsockets qt5compat
- name: Patching Qt
shell: bash
run: |
# see: https://wiki.qt.io/Qt_6.2_Known_Issues#WebAssembly
sed '/sse/,+5 d' /opt/$QTVERSION/wasm_32/mkspecs/features/wasm/wasm.prf > /tmp/wasm.prf
mv /tmp/wasm.prf /opt/$QTVERSION/wasm_32/mkspecs/features/wasm/wasm.prf
ln -s /opt/$QTVERSION/gcc_64/bin/lconvert /opt/$QTVERSION/wasm_32/bin/
ln -s /opt/$QTVERSION/gcc_64/bin/lupdate /opt/$QTVERSION/wasm_32/bin/
ln -s /opt/$QTVERSION/gcc_64/bin/lrelease /opt/$QTVERSION/wasm_32/bin/
- name: Install python dependencies
shell: bash
run: |
Expand All @@ -64,7 +54,15 @@ jobs:
shell: bash
run: |
export PATH=/opt/$QTVERSION/wasm_32/bin:/opt/$QTVERSION/gcc_64/bin:$PATH
./scripts/wasm/compile.sh
mkdir build
/opt/$QTVERSION/wasm_32/bin/qt-cmake -S . -B build -DQT_HOST_PATH=/opt/$QTVERSION/gcc_64 -DQT_HOST_PATH_CMAKE_DIR=/opt/$QTVERSION/gcc_64/lib/cmake
cmake --build build -j4
cp $(pwd)/build/src/mozillavpn.wasm wasm
cp $(pwd)/build/src/mozillavpn.js wasm
cp $(pwd)/build/src/qtloader.js wasm
cp $(pwd)/tests/functional/fxa_endpoints.js wasm
cp $(pwd)/tests/functional/guardian_endpoints.js wasm
cp -r $(pwd)/tools/logviewer wasm
- name: Generate tasklist
id: testGen
Expand Down Expand Up @@ -223,7 +221,6 @@ jobs:

- name: Install dependecies
run: |
sudo apt install ./build/archive/*.deb
sudo apt install --no-upgrade firefox xvfb -y
pip3 install -r requirements.txt
npm install
Expand Down
20 changes: 13 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,20 @@ find_package(Qt6 COMPONENTS
Core
Gui
Network
NetworkAuth
Qml
Quick
QuickTest
Sql
Test
WebSockets
Widgets
Xml
)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
find_package(Qt6 COMPONENTS
NetworkAuth
Sql
)
endif()
message("Using Qt version ${Qt6_VERSION}")
add_definitions(-DQT_DEPRECATED_WARNINGS)
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050F00)
Expand All @@ -108,14 +112,16 @@ set_target_properties(build_tests PROPERTIES
EXCLUDE_FROM_ALL $<NOT:$<BOOL:${BUILD_TESTING}>>
FOLDER "Tests"
)
add_subdirectory(tests/auth)
add_subdirectory(tests/nativemessaging)
add_subdirectory(tests/unit)
add_subdirectory(tests/qml)

# Web Extension build targets
if(NOT CMAKE_CROSSCOMPILING)
# Web Extension build targets
add_subdirectory(extension)

# Tests
add_subdirectory(tests/auth)
add_subdirectory(tests/nativemessaging)
add_subdirectory(tests/unit)
add_subdirectory(tests/qml)
endif()

# Extra platform targets
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,15 @@ Read the following pages to know more:
- https://emscripten.org/docs/getting_started/index.html
- https://doc.qt.io/qt-6/wasm.html

When you are ready, use this script to generate the build:
When you are ready, create a build directory and configure the project for
building using `qt-cmake` + `cmake`:
```bash
scripts/wasm/compile.sh
mkdir build && qt-cmake cmake -S . -B build
```

Compile the source code:
```bash
cmake --build build -j$(nproc)
```

## Testing
Expand Down
7 changes: 6 additions & 1 deletion glean/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
add_library(glean STATIC)

set_target_properties(glean PROPERTIES FOLDER "Libs")
target_link_libraries(glean PRIVATE Qt6::Core Qt6::Qml Qt6::Sql)
target_link_libraries(glean PRIVATE Qt6::Core Qt6::Qml)

if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
target_link_libraries(glean PRIVATE Qt6::Sql)
endif()

target_include_directories(glean PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(glean PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

Expand Down
4 changes: 0 additions & 4 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ TODO:
- ./windows/compile.bat - compile the client
- ./windows/utils/commons.sh - common functions for cross-platform scrips

# Wasm-specific scripts

- ./wasm/compile.sh - compile the client for Wasm. See the main README.md file.

# CI tools

- ./ci/check_qrc.py - check qrc files to avoid duplicate entries and other errors
Expand Down
83 changes: 0 additions & 83 deletions scripts/wasm/compile.sh

This file was deleted.

15 changes: 12 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
qt_add_executable(mozillavpn MANUAL_FINALIZATION)

target_link_libraries(mozillavpn PRIVATE
Qt6::NetworkAuth
Qt6::Quick
Qt6::Test
Qt6::WebSockets
Qt6::Widgets
)

if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
target_link_libraries(mozillavpn PRIVATE
Qt6::NetworkAuth
)
endif()

target_link_libraries(mozillavpn PRIVATE glean lottie nebula translations)

include(cmake/sources.cmake)
Expand All @@ -34,13 +39,17 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
set(MVPN_PLATFORM_NAME "android")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
set(MVPN_PLATFORM_NAME "ios")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
set(MVPN_PLATFORM_NAME "wasm")
endif()

add_compile_definitions("$<$<CONFIG:Debug>:MVPN_DEBUG>")
add_compile_definitions("MVPN_$<UPPER_CASE:${MVPN_PLATFORM_NAME}>")
include(cmake/${MVPN_PLATFORM_NAME}.cmake)

add_subdirectory(crashreporter)
target_link_libraries(mozillavpn PRIVATE crashreporter)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
add_subdirectory(crashreporter)
target_link_libraries(mozillavpn PRIVATE crashreporter)
endif()

qt_finalize_target(mozillavpn)
2 changes: 0 additions & 2 deletions src/addonmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ bool AddonManager::validateIndex(const QByteArray& index,
for (const AddonData& addonData : addons) {
if (!m_addons.contains(addonData.m_addonId) &&
validateAndLoad(addonData.m_addonId, addonData.m_sha256)) {
Q_ASSERT(m_addons.contains(addonData.m_addonId));
Q_ASSERT(m_addons[addonData.m_addonId].m_sha256 == addonData.m_sha256);
continue;
}

Expand Down
29 changes: 29 additions & 0 deletions src/cmake/wasm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

target_sources(mozillavpn PRIVATE
platforms/dummy/dummycontroller.cpp
platforms/dummy/dummycontroller.h
platforms/dummy/dummycryptosettings.cpp
platforms/macos/macosmenubar.cpp
platforms/macos/macosmenubar.h
platforms/wasm/wasmauthenticationlistener.cpp
platforms/wasm/wasmauthenticationlistener.h
platforms/wasm/wasmnetworkrequest.cpp
platforms/wasm/wasmnetworkrequest.h
platforms/wasm/wasmnetworkwatcher.cpp
platforms/wasm/wasmnetworkwatcher.h
platforms/wasm/wasmwindowcontroller.cpp
platforms/wasm/wasmwindowcontroller.h
platforms/wasm/wasmiaphandler.cpp
platforms/wasm/wasmiaphandler.h
platforms/wasm/wasminspector.cpp
platforms/wasm/wasminspector.h
systemtraynotificationhandler.cpp
systemtraynotificationhandler.h
tasks/purchase/taskpurchase.cpp
tasks/purchase/taskpurchase.h
)

add_compile_definitions("MVPN_DUMMY")
30 changes: 22 additions & 8 deletions src/networkrequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ QList<QSslCertificate> s_intervention_certs;

NetworkRequest::NetworkRequest(Task* parent, int status,
bool setAuthorizationHeader)
: QObject(parent), m_status(status) {
: QObject(parent), m_expectedStatusCode(status) {
MVPN_COUNT_CTOR(NetworkRequest);
logger.debug() << "Network request created by" << parent->name();

Expand Down Expand Up @@ -913,12 +913,10 @@ void NetworkRequest::replyFinished() {
}
#endif

m_completed = true;
m_timer.stop();

int status = statusCode();

QString expect = m_status ? QString::number(m_status) : "any";
QString expect =
m_expectedStatusCode ? QString::number(m_expectedStatusCode) : "any";
logger.debug() << "Network reply received - status:" << status
<< "- expected:" << expect;

Expand All @@ -929,6 +927,13 @@ void NetworkRequest::replyFinished() {
void NetworkRequest::processData(QNetworkReply::NetworkError error,
const QString& errorString, int status,
const QByteArray& data) {
m_completed = true;
m_timer.stop();

#ifdef MVPN_WASM
m_finalStatusCode = status;
#endif

if (error != QNetworkReply::NoError) {
QUrl::FormattingOptions options = QUrl::RemoveQuery | QUrl::RemoveUserInfo;
logger.error() << "Network error:" << errorString
Expand All @@ -941,9 +946,9 @@ void NetworkRequest::processData(QNetworkReply::NetworkError error,

// This is an extra check for succeeded requests (status code 200 vs 201, for
// instance). The real network status check is done in the previous if-stmt.
if (m_status && status != m_status) {
if (m_expectedStatusCode && status != m_expectedStatusCode) {
logger.error() << "Status code unexpected - status code:" << status
<< "- expected:" << m_status;
<< "- expected:" << m_expectedStatusCode;
emit requestFailed(QNetworkReply::ConnectionRefusedError, data);
return;
}
Expand Down Expand Up @@ -995,12 +1000,17 @@ void NetworkRequest::handleRedirect(const QUrl& redirectUrl) {
}

void NetworkRequest::timeout() {
#ifndef MVPN_WASM
Q_ASSERT(m_reply);
Q_ASSERT(!m_reply->isFinished());
#endif
Q_ASSERT(!m_completed);

m_completed = true;
m_reply->abort();

if (m_reply) {
m_reply->abort();
}

logger.error() << "Network request timeout";
emit requestFailed(QNetworkReply::TimeoutError, QByteArray());
Expand Down Expand Up @@ -1070,6 +1080,10 @@ void NetworkRequest::maybeDeleteLater() {
}

int NetworkRequest::statusCode() const {
#ifdef MVPN_WASM
return m_finalStatusCode;
#endif

Q_ASSERT(m_reply);

QVariant statusCode =
Expand Down
8 changes: 7 additions & 1 deletion src/networkrequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,13 @@ class NetworkRequest final : public QObject {
#endif

QNetworkReply* m_reply = nullptr;
int m_status = 0;
int m_expectedStatusCode = 0;
#ifdef MVPN_WASM
// In wasm network request, m_reply is null. So we need to store the "status
// code" in a variable member.
int m_finalStatusCode = 0;
#endif

bool m_completed = false;
bool m_aborted = false;

Expand Down
Loading

0 comments on commit 3ae9aea

Please sign in to comment.