Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMakeLists: Add support for targeting Emscripten/WebAssembly #12918

Merged
merged 8 commits into from
Mar 4, 2024
59 changes: 48 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,22 @@ if(QML)
add_compile_definitions(MIXXX_USE_QML)
endif()

if(APPLE)
if(VCPKG_TARGET_TRIPLET MATCHES "^wasm(32|64)-emscripten")
message(STATUS "Targeting Emscripten (${VCPKG_TARGET_TRIPLET})")
if(DEFINED ENV{EMSDK})
message(STATUS "Found EMSDK at $ENV{EMSDK}")
else()
message(FATAL_ERROR "Please make sure emsdk is installed and the environment variable EMSDK is set (see https://emscripten.org/docs/getting_started/downloads.html)")
endif()
if(NOT DEFINED VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "$ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" CACHE STRING "")
endif()
Comment on lines +157 to +159
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be redundant, since the vcpkg triplet (wasm32-emscripten or any of its derivatives) should already set this.

# Enabling this causes Qt's FindWrapRt C++ compile check to fail as it tries
# to run `clang-scan-deps` (because we set the C++ standard to 20). Emscripten
# does not ship this binary yet, though. Potentially relevant upstream bug:
# https://github.com/emscripten-core/emscripten/issues/21042
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
elseif(APPLE)
# Check if xcode-select is installed
execute_process(COMMAND xcode-select -v
RESULT_VARIABLE XCODE_SELECT_RESULT
Expand Down Expand Up @@ -459,15 +474,20 @@ elseif(GNU_GCC OR LLVM_CLANG)
# portable: sse2 CPU (>= Pentium 4)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i[3456]86|x86|x64|x86_64|AMD64)$")
message(STATUS "Enabling SSE2 CPU optimizations (>= Pentium 4)")
add_compile_options(-mtune=generic)
if(NOT EMSCRIPTEN)
add_compile_options(-mtune=generic)
endif()
# -mtune=generic picks the most common, but compatible options.
# on arm platforms equivalent to -march=arch
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
# the sse flags are not set by default on 32 bit builds
# but are not supported on arm builds
add_compile_options(
-msse2
-mfpmath=sse)
add_compile_options(-msse2)
if(EMSCRIPTEN)
add_compile_options(-msimd128)
else()
add_compile_options(-mfpmath=sse)
endif()
endif()
# TODO(rryan): macOS can use SSE3, and possibly SSE 4.1 once
# we require macOS 10.12.
Expand Down Expand Up @@ -2551,7 +2571,13 @@ if(IOS)
else()
set(OpenGL_GL_PREFERENCE "GLVND")
find_package(OpenGL REQUIRED)
target_link_libraries(mixxx-lib PRIVATE OpenGL::GL)
if(EMSCRIPTEN)
# Emscripten's FindOpenGL.cmake does not create OpenGL::GL
target_link_libraries(mixxx-lib PRIVATE ${OPENGL_gl_LIBRARY})
target_compile_definitions(mixxx-lib PUBLIC QT_OPENGL_ES_2)
else()
target_link_libraries(mixxx-lib PRIVATE OpenGL::GL)
endif()
endif()

# Ogg
Expand Down Expand Up @@ -2750,10 +2776,6 @@ if(Qt_IS_STATIC)
# into Qt .libs by default.

target_link_libraries(mixxx-lib PRIVATE
# platform plugins
Qt${QT_VERSION_MAJOR}::QOffscreenIntegrationPlugin
Qt${QT_VERSION_MAJOR}::QMinimalIntegrationPlugin

# imageformats plugins
Qt${QT_VERSION_MAJOR}::QGifPlugin
Qt${QT_VERSION_MAJOR}::QICOPlugin
Expand All @@ -2764,6 +2786,18 @@ if(Qt_IS_STATIC)
Qt${QT_VERSION_MAJOR}::QSQLiteDriverPlugin
)

if(EMSCRIPTEN)
target_link_libraries(mixxx-lib PRIVATE
Qt${QT_VERSION_MAJOR}::QWasmIntegrationPlugin
)
else()
target_link_libraries(mixxx-lib PRIVATE
# platform plugins
Qt${QT_VERSION_MAJOR}::QOffscreenIntegrationPlugin
Qt${QT_VERSION_MAJOR}::QMinimalIntegrationPlugin
)
endif()

if(WIN32)
target_link_libraries(mixxx-lib PRIVATE
Qt${QT_VERSION_MAJOR}::QWindowsIntegrationPlugin
Expand Down Expand Up @@ -2964,7 +2998,7 @@ if(APPLE)
"-weak_framework IOKit"
)
endif()
elseif(UNIX AND NOT APPLE)
elseif(UNIX AND NOT APPLE AND NOT EMSCRIPTEN)
if(QT6)
find_package(X11)
else()
Expand Down Expand Up @@ -3195,6 +3229,9 @@ if(BATTERY)
target_sources(mixxx-lib PRIVATE src/util/battery/batterymac.cpp)
endif()
elseif(UNIX)
if(EMSCRIPTEN)
message(FATAL_ERROR "Battery support is not implemented for Emscripten (WebAssembly)")
endif()
find_package(Upower REQUIRED)
find_package(GLIB COMPONENTS gobject REQUIRED)
target_include_directories(mixxx-lib SYSTEM PUBLIC ${GLIB_INCLUDE_DIRS})
Expand Down
8 changes: 8 additions & 0 deletions src/proto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ else()
message(FATAL_ERROR "Protobuf or Protobuf-lite libraries are required to compile Mixxx.")
endif()

if(EMSCRIPTEN)
# If we try linking in a proto lib built without -pthread we get
# wasm-ld: error: --shared-memory is disallowed by keys.pb.cc.o
# because it was not compiled with 'atomics' or 'bulk-memory' features.
# See https://groups.google.com/g/emscripten-discuss/c/G4nwFprZFYo
target_compile_options(mixxx-proto PRIVATE -pthread)
endif()

protobuf_generate(
LANGUAGE cpp
TARGET mixxx-proto
Expand Down