├── Dockerfile ├── LICENSE ├── README.md ├── qt-pipeline.yml ├── qt6-dockerfile └── task-build-container.yml /Dockerfile: -------------------------------------------------------------------------------- 1 | #Base image with emscripten 2 | ARG EMSCRIPTEN_BASE= 3 | 4 | FROM $EMSCRIPTEN_BASE AS qt-build-stage 5 | MAINTAINER Lennart E. 6 | 7 | #Qt5 source 8 | ARG QT_DIRECTORY= 9 | 10 | # Options to be appended to configure 11 | ARG QT_CONFIGURE_OPTIONS= 12 | 13 | # Options to be appended to init-repository --module-subset 14 | ARG QT_MODULE_SUBSET= 15 | 16 | # Additional modules to make 17 | ARG QT_MODULES= 18 | 19 | # Additional modules to make 20 | ARG CPP_STD= 21 | 22 | 23 | #Install git 24 | #RUN apt update && apt install git 25 | 26 | #Copy qt5 source 27 | COPY $QT_DIRECTORY /qt5 28 | 29 | #Change work directory 30 | WORKDIR /qt5/ 31 | 32 | #Build qt5 33 | #RUN ./init-repository --module-subset=qtbase,qtdeclarative,qtquickcontrols2,qtwebsockets,qtsvg,qtcharts,qtgraphicaleffects,qtxmlpatterns,$QT_MODULE_SUBSET -f 34 | #RUN ./init-repository --module-subset=qtbase,qtdeclarative,qtquickcontrols2,qtwebsockets,qtsvg,qtcharts,qtgraphicaleffects,qtxmlpatterns,$QT_MODULE_SUBSET 35 | RUN ./configure -xplatform wasm-emscripten -nomake examples -prefix /qtbase -c++std $CPP_STD -opensource -confirm-license $QT_CONFIGURE_OPTIONS 36 | #RUN make module-qtbase module-qtsvg module-qtdeclarative module-qtwebsockets module-qtxmlpatterns module-qtquickcontrols2 module-qtgraphicaleffects module-qtcharts $QT_MODULES 37 | RUN make -j 24 -l 80 module-qtbase module-qtdeclarative $QT_MODULES 38 | RUN make install 39 | 40 | #Copy files to new stage 41 | FROM $EMSCRIPTEN_BASE AS final-stage 42 | MAINTAINER Lennart E. 43 | COPY --from=qt-build-stage /qtbase /qtbase 44 | ENV PATH="/qtbase/bin:${PATH}" 45 | 46 | #Set workdir to /src to maintain compatibility with older versions of this container 47 | WORKDIR /src/ 48 | 49 | #Create new entrypoint to use emscripten entrypoint and set path, because the 50 | # emscripten entrypoint ignores the path 51 | RUN mkdir -p /qt-webassembly/ ; \ 52 | echo "#""!""/bin/sh" > /qt-webassembly/entrypoint ; \ 53 | echo "if test -f /emsdk_portable/entrypoint ; then /emsdk_portable/entrypoint sh -c \"PATH=\\\"/qtbase/bin:\\\$PATH\\\" \$* \" ; else \$* ; fi" >> /qt-webassembly/entrypoint ; \ 54 | chmod -R a+r /qt-webassembly ; \ 55 | chmod a+x /qt-webassembly/entrypoint 56 | ENTRYPOINT ["/qt-webassembly/entrypoint"] 57 | CMD [] 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Zebreus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | qt-webassembly-docker 2 | ===================== 3 | 4 | A container for building Qt applications for the web platform using [Qt for WebAssembly](https://doc.qt.io/qt-5/wasm.html). 5 | 6 | This container is based on the official emscripten docker image [emscripten/emsdk](https://github.com/emscripten-core/emsdk). 7 | 8 | The [concourse pipeline](https://concourse.madmanfred.com/teams/main/pipelines/qt-webassembly) is constantly building images and putting them on dockerhub [madmanfred/qt-webassembly](https://hub.docker.com/repository/docker/madmanfred/qt-webassembly). 9 | 10 | Please create issues related to this image on the associated [GitHub project](https://github.com/Zebreus/qt-webassembly-docker). 11 | 12 | ## Usage ## 13 | ### bash ### 14 | ```Shell 15 | docker run --rm -v $(pwd):/src/ -u $(id -u):$(id -g) madmanfred/qt-webassembly qmake 16 | docker run --rm -v $(pwd):/src/ -u $(id -u):$(id -g) madmanfred/qt-webassembly make 17 | ``` 18 | ### powershell ### 19 | ```PowerShell 20 | docker run --rm -v $(PWD):/src/ madmanfred/qt-webassembly qmake 21 | docker run --rm -v $(PWD):/src/ madmanfred/qt-webassembly make 22 | ``` 23 | 24 | ## Build status ## 25 | [

](https://concourse.einhorn.jetzt/teams/main/pipelines/qt-webassembly) 26 | 27 | ## Improving build time 28 | Here are some tips to speed up your builds for Qt for WebAssembly: 29 | 30 | - You can add this to use a local directory as cache: 31 | ```Shell 32 | -v ~/.emscripten_cache:/emsdk_portable/.data/cache 33 | ``` 34 | 35 | - If you use some of the [emscripten ported libraries](https://github.com/emscripten-ports), you can reduce the build time by a few seconds by caching `/emsdk_portable/.data/ports`. 36 | 37 | - You can also increase the compilation speed a bit by using a parallel build (`make -j`). 38 | 39 | - If you disable all optimizations you can reduce your build time significantly. Just add this to your project file: 40 | ```QMake 41 | QMAKE_CXXFLAGS_RELEASE -= -O3 42 | QMAKE_CXXFLAGS_RELEASE *= -O0 43 | 44 | QMAKE_LFLAGS_RELEASE -= -O3 45 | QMAKE_LFLAGS_RELEASE *= -O0 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /qt-pipeline.yml: -------------------------------------------------------------------------------- 1 | --- 2 | resources: 3 | - name: qt-webassembly-docker 4 | type: git 5 | source: 6 | uri: https://github.com/Zebreus/qt-webassembly-docker.git 7 | branch: master 8 | - name: qt5-12 9 | type: git 10 | source: 11 | uri: https://code.qt.io/qt/qt5.git 12 | branch: 5.12 13 | - name: qt5-13 14 | type: git 15 | source: 16 | uri: https://code.qt.io/qt/qt5.git 17 | branch: 5.13 18 | - name: qt5-14 19 | type: git 20 | source: 21 | uri: https://code.qt.io/qt/qt5.git 22 | branch: 5.14 23 | - name: qt5-15 24 | type: git 25 | source: 26 | uri: https://code.qt.io/qt/qt5.git 27 | branch: 5.15 28 | - name: qt-webassembly-latest 29 | type: registry-image 30 | source: 31 | repository: ((registry_username))/qt-webassembly 32 | username: ((registry_username)) 33 | password: ((registry_password)) 34 | tag: latest 35 | - name: qt-webassembly-qt5.12 36 | type: registry-image 37 | source: 38 | repository: ((registry_username))/qt-webassembly 39 | username: ((registry_username)) 40 | password: ((registry_password)) 41 | tag: qt5.12 42 | - name: qt-webassembly-qt5.13 43 | type: registry-image 44 | source: 45 | repository: ((registry_username))/qt-webassembly 46 | username: ((registry_username)) 47 | password: ((registry_password)) 48 | tag: qt5.13 49 | - name: qt-webassembly-qt5.14 50 | type: registry-image 51 | source: 52 | repository: ((registry_username))/qt-webassembly 53 | username: ((registry_username)) 54 | password: ((registry_password)) 55 | tag: qt5.14 56 | - name: qt-webassembly-qt5.15 57 | type: registry-image 58 | source: 59 | repository: ((registry_username))/qt-webassembly 60 | username: ((registry_username)) 61 | password: ((registry_password)) 62 | tag: qt5.15 63 | - name: qt-webassembly-qt5.12-em1.38.16 64 | type: registry-image 65 | source: 66 | repository: ((registry_username))/qt-webassembly 67 | username: ((registry_username)) 68 | password: ((registry_password)) 69 | tag: qt5.12-em1.38.16 70 | - name: qt-webassembly-qt5.13-em1.38.27 71 | type: registry-image 72 | source: 73 | repository: ((registry_username))/qt-webassembly 74 | username: ((registry_username)) 75 | password: ((registry_password)) 76 | tag: qt5.13-em1.38.27 77 | - name: qt-webassembly-qt5.13-em1.38.30-threads 78 | type: registry-image 79 | source: 80 | repository: ((registry_username))/qt-webassembly 81 | username: ((registry_username)) 82 | password: ((registry_password)) 83 | tag: qt5.13-em1.38.30-multithreading 84 | - name: qt-webassembly-qt5.14-em1.38.27 85 | type: registry-image 86 | source: 87 | repository: ((registry_username))/qt-webassembly 88 | username: ((registry_username)) 89 | password: ((registry_password)) 90 | tag: qt5.14-em1.38.27 91 | - name: qt-webassembly-qt5.14-em1.38.30-threads 92 | type: registry-image 93 | source: 94 | repository: ((registry_username))/qt-webassembly 95 | username: ((registry_username)) 96 | password: ((registry_password)) 97 | tag: qt5.14-em1.38.30-multithreading 98 | - name: qt-webassembly-qt5.15-em1.39.8 99 | type: registry-image 100 | source: 101 | repository: ((registry_username))/qt-webassembly 102 | username: ((registry_username)) 103 | password: ((registry_password)) 104 | tag: qt5.15-em1.39.8 105 | - name: emscripten-1-38-16 106 | type: registry-image 107 | source: 108 | repository: trzeci/emscripten 109 | tag: sdk-tag-1.38.16-64bit 110 | - name: emscripten-1-38-27 111 | type: registry-image 112 | source: 113 | repository: trzeci/emscripten 114 | tag: sdk-tag-1.38.27-64bit 115 | - name: emscripten-1-38-30 116 | type: registry-image 117 | source: 118 | repository: trzeci/emscripten 119 | tag: sdk-tag-1.38.30-64bit 120 | - name: emscripten-1-39-8 121 | type: registry-image 122 | source: 123 | repository: emscripten/emsdk 124 | tag: 1.39.8-upstream 125 | - name: oci-build-task 126 | type: registry-image 127 | source: 128 | repository: vito/oci-build-task 129 | 130 | jobs: 131 | - name: build-qt5.12-em1.38.16 132 | public: true 133 | serial_groups: [build-qt] 134 | plan: 135 | - get: qt-webassembly-docker 136 | - get: emscripten 137 | resource: emscripten-1-38-16 138 | params: 139 | format: oci 140 | trigger: true 141 | - get: qt 142 | resource: qt5-12 143 | trigger: true 144 | - get: oci-build-task 145 | - task: build-container 146 | file: qt-webassembly-docker/task-build-container.yml 147 | privileged: true 148 | image: oci-build-task 149 | params: 150 | EMSCRIPTEN_BASE: trzeci/emscripten 151 | - put: qt-webassembly-qt5.12-em1.38.16 152 | params: {image: image/image.tar} 153 | - put: qt-webassembly-qt5.12 154 | params: {image: image/image.tar} 155 | - name: build-qt5.13-em1.38.27 156 | public: true 157 | serial_groups: [build-qt] 158 | plan: 159 | - get: qt-webassembly-docker 160 | - get: emscripten 161 | resource: emscripten-1-38-27 162 | params: 163 | format: oci 164 | trigger: true 165 | - get: qt 166 | resource: qt5-13 167 | trigger: true 168 | - get: oci-build-task 169 | - task: build-container 170 | file: qt-webassembly-docker/task-build-container.yml 171 | privileged: true 172 | image: oci-build-task 173 | params: 174 | EMSCRIPTEN_BASE: trzeci/emscripten 175 | - put: qt-webassembly-qt5.13-em1.38.27 176 | params: {image: image/image.tar} 177 | - put: qt-webassembly-qt5.13 178 | params: {image: image/image.tar} 179 | - name: build-qt5.13-em1.38.30-threads 180 | public: true 181 | serial_groups: [build-qt] 182 | plan: 183 | - get: qt-webassembly-docker 184 | - get: emscripten 185 | resource: emscripten-1-38-30 186 | params: 187 | format: oci 188 | trigger: true 189 | - get: qt 190 | resource: qt5-13 191 | trigger: true 192 | - get: oci-build-task 193 | - task: build-container 194 | file: qt-webassembly-docker/task-build-container.yml 195 | privileged: true 196 | image: oci-build-task 197 | params: 198 | EMSCRIPTEN_BASE: trzeci/emscripten 199 | BUILD_ARG_QT_CONFIGURE_OPTIONS: -feature-thread 200 | - put: qt-webassembly-qt5.13-em1.38.30-threads 201 | params: {image: image/image.tar} 202 | - name: build-qt5.14-em1.38.27 203 | public: true 204 | serial_groups: [build-qt] 205 | plan: 206 | - get: qt-webassembly-docker 207 | - get: emscripten 208 | resource: emscripten-1-38-27 209 | params: 210 | format: oci 211 | trigger: true 212 | - get: qt 213 | resource: qt5-14 214 | trigger: true 215 | - get: oci-build-task 216 | - task: build-container 217 | file: qt-webassembly-docker/task-build-container.yml 218 | privileged: true 219 | image: oci-build-task 220 | params: 221 | EMSCRIPTEN_BASE: trzeci/emscripten 222 | - put: qt-webassembly-qt5.14-em1.38.27 223 | params: {image: image/image.tar} 224 | - put: qt-webassembly-qt5.14 225 | params: {image: image/image.tar} 226 | - name: build-qt5.14-em1.38.30-threads 227 | public: true 228 | serial_groups: [build-qt] 229 | plan: 230 | - get: qt-webassembly-docker 231 | - get: emscripten 232 | resource: emscripten-1-38-30 233 | params: 234 | format: oci 235 | trigger: true 236 | - get: qt 237 | resource: qt5-14 238 | trigger: true 239 | - get: oci-build-task 240 | - task: build-container 241 | file: qt-webassembly-docker/task-build-container.yml 242 | privileged: true 243 | image: oci-build-task 244 | params: 245 | EMSCRIPTEN_BASE: trzeci/emscripten 246 | BUILD_ARG_QT_CONFIGURE_OPTIONS: -feature-thread 247 | - put: qt-webassembly-qt5.14-em1.38.30-threads 248 | params: {image: image/image.tar} 249 | - name: build-qt5.15-em1.39.8 250 | public: true 251 | serial_groups: [build-qt] 252 | plan: 253 | - get: qt-webassembly-docker 254 | - get: emscripten 255 | resource: emscripten-1-39-8 256 | params: 257 | format: oci 258 | trigger: true 259 | - get: qt 260 | resource: qt5-15 261 | trigger: true 262 | - get: oci-build-task 263 | - task: build-container 264 | file: qt-webassembly-docker/task-build-container.yml 265 | privileged: true 266 | image: oci-build-task 267 | - put: qt-webassembly-qt5.15-em1.39.8 268 | params: {image: image/image.tar} 269 | - put: qt-webassembly-qt5.15 270 | params: {image: image/image.tar} 271 | - put: qt-webassembly-latest 272 | params: {image: image/image.tar} 273 | 274 | groups: 275 | - name: all 276 | jobs: 277 | - build-qt5.12-em1.38.16 278 | - build-qt5.13-em1.38.27 279 | - build-qt5.13-em1.38.30-threads 280 | - build-qt5.14-em1.38.27 281 | - build-qt5.14-em1.38.30-threads 282 | - build-qt5.15-em1.39.8 283 | - name: qt5-12 284 | jobs: 285 | - build-qt5.12-em1.38.16 286 | - name: qt5-13 287 | jobs: 288 | - build-qt5.13-em1.38.27 289 | - build-qt5.13-em1.38.30-threads 290 | - name: qt5-14 291 | jobs: 292 | - build-qt5.14-em1.38.27 293 | - build-qt5.14-em1.38.30-threads 294 | - name: qt5-15 295 | jobs: 296 | - build-qt5.15-em1.39.8 297 | -------------------------------------------------------------------------------- /qt6-dockerfile: -------------------------------------------------------------------------------- 1 | #Base image with emscripten 2 | ARG EMSCRIPTEN_BASE=emscripten/emsdk:2.0.15 3 | 4 | FROM $EMSCRIPTEN_BASE AS emscripten-cmake 5 | MAINTAINER Lennart E. 6 | RUN apt update -y && apt upgrade -y && apt install -y wget git 7 | RUN version=3.19 ;\ 8 | build=1 ;\ 9 | cd $(mktemp -d) ;\ 10 | wget https://cmake.org/files/v$version/cmake-$version.$build-Linux-x86_64.sh ;\ 11 | mkdir -p /opt/cmake ;\ 12 | bash cmake-$version.$build-Linux-x86_64.sh --skip-license --prefix=/opt/cmake 13 | ENV PATH="/opt/cmake/bin:${PATH}" 14 | 15 | FROM emscripten-cmake AS prepared-build-stage 16 | MAINTAINER Lennart E. 17 | RUN apt update -y && apt upgrade -y && apt install -y perl python gperf bison flex build-essential libclang-dev clang freeglut3-dev ninja-build 18 | #All modules working for webassembly 19 | #RUN git clone -b dev git://code.qt.io/qt/qt5.git /qt5 && cd /qt5 && ./init-repository --module-subset=qtbase,qtdeclarative,qttools,qttranslations,qtdoc,qtrepotools,qtqa,qtquickcontrols2,qtsvg,qtwayland,qtquicktimeline,qtquick3d,qtshadertools,qtlocation,qtimageformats,qtcharts,qtdatavis3d,qtscxml,qtlottie,qtmqtt,qtquickcontrols,qt5compat 20 | RUN git clone -b dev git://code.qt.io/qt/qt5.git /qt5 && cd /qt5 && ./init-repository --module-subset=essential 21 | 22 | FROM prepared-build-stage AS qt6-host-build-stage 23 | MAINTAINER Lennart E. 24 | RUN mkdir /build-host && cd /build-host && /qt5/configure -prefix /qtbase-host -platform linux-g++-64 -cmake-generator Ninja 25 | RUN cd /build-host && cmake --build . --parallel 8 26 | RUN cd /build-host && cmake --install . 27 | 28 | FROM prepared-build-stage AS qt6-wasm-build-stage 29 | MAINTAINER Lennart E. 30 | COPY --from=qt6-host-build-stage /qtbase-host /qtbase-host 31 | ENV PATH="/qtbase-host/bin:${PATH}" 32 | # For some reason configure with qttools fails, if these files are not there while configuring. I should look into this. 33 | RUN cd /qt5/qtbase/src/plugins/platforms/wasm && install -t /build-wasm/qtbase/plugins/platforms/ qtloader.js qtlogo.svg wasm_shell.html -D 34 | #TODO figure out how to enable webp support, as -webp qt does not work. 35 | RUN mkdir -p /build-wasm && cd /build-wasm && /qt5/configure -prefix /qtbase -qt-host-path /qtbase-host -xplatform wasm-emscripten -cmake-generator Ninja -nomake tests -nomake examples -developer-build -no-warnings-are-errors 36 | RUN cd /build-wasm && cmake --build . --parallel 8 37 | RUN cd /build-wasm && cmake --install . 38 | 39 | #Copy files to new stage 40 | FROM emscripten-cmake AS final-stage 41 | MAINTAINER Lennart E. 42 | RUN apt update -y && apt upgrade -y && apt install -y perl python gperf bison flex build-essential libclang-dev clang freeglut3-dev ninja-build 43 | 44 | # Copy host qt tools 45 | COPY --from=qt6-host-build-stage /qtbase-host /qtbase-host 46 | ENV PATH="/qtbase-host/bin:${PATH}" 47 | # Copy qt library 48 | COPY --from=qt6-wasm-build-stage /qtbase /qtbase 49 | ENV PATH="/qtbase/bin:${PATH}" 50 | 51 | #Set workdir to /src to maintain compatibility with older versions of this container 52 | WORKDIR /src/ 53 | 54 | #Create new entrypoint to use emscripten entrypoint and set path, because the 55 | # emscripten entrypoint ignores the path 56 | RUN mkdir -p /qt-webassembly/ ; \ 57 | echo "#""!""/bin/sh" > /qt-webassembly/entrypoint ; \ 58 | echo "if test -f /emsdk_portable/entrypoint ; then /emsdk_portable/entrypoint sh -c \"PATH=\\\"/qtbase/bin:\\\$PATH\\\" \$* \" ; else \$* ; fi" >> /qt-webassembly/entrypoint ; \ 59 | chmod -R a+r /qt-webassembly ; \ 60 | chmod a+x /qt-webassembly/entrypoint 61 | ENTRYPOINT ["/qt-webassembly/entrypoint"] 62 | CMD [] 63 | -------------------------------------------------------------------------------- /task-build-container.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | params: 4 | DOCKERFILE: ./qt-webassembly-docker/Dockerfile 5 | BUILD_ARG_QT_DIRECTORY: qt/ 6 | BUILD_ARG_QT_MODULES: module-qtgraphicaleffects module-qtcharts module-qtsvg module-qtwebsockets module-qtxmlpatterns module-qtquickcontrols2 7 | BUILD_ARG_CPP_STD: c++14 8 | EMSCRIPTEN_BASE: emscripten/emsdk 9 | inputs: 10 | - name: qt-webassembly-docker 11 | - name: qt 12 | - name: emscripten 13 | outputs: 14 | - name: image 15 | caches: 16 | - path: cache 17 | run: 18 | path: sh 19 | args: 20 | - -ceux 21 | - | 22 | export BUILD_ARG_EMSCRIPTEN_BASE="${EMSCRIPTEN_BASE}@$(cat emscripten/digest)" 23 | build 24 | --------------------------------------------------------------------------------