Skip to content

Commit

Permalink
Initial merge of Emscripten port!
Browse files Browse the repository at this point in the history
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.

This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jyl?nki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
  • Loading branch information
icculus committed Dec 18, 2014
1 parent a228b67 commit fe40a17
Show file tree
Hide file tree
Showing 61 changed files with 4,044 additions and 597 deletions.
105 changes: 91 additions & 14 deletions CMakeLists.txt
Expand Up @@ -117,6 +117,12 @@ else()
set(UNIX_OR_MAC_SYS OFF)
endif()

if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten.
set(PTHREADS_ENABLED_BY_DEFAULT ON)
else()
set(PTHREADS_ENABLED_BY_DEFAULT OFF)
endif()

# Default option knobs
if(APPLE OR ARCH_64)
set(OPT_DEF_SSEMATH ON)
Expand Down Expand Up @@ -170,13 +176,19 @@ endif()
set(SDL_LIBS "-lSDL2")
set(SDL_CFLAGS "")

# Emscripten toolchain has a nonempty default value for this, and the checks
# in this file need to change that, so remember the original value, and
# restore back to that afterwards. For check_function_exists() to work in
# Emscripten, this value must be at its default value.
set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})

if(CYGWIN)
# We build SDL on cygwin without the UNIX emulation layer
include_directories("-I/usr/include/mingw")
set(CMAKE_REQUIRED_FLAGS "-mno-cygwin")
check_c_source_compiles("int main(int argc, char **argv) {}"
HAVE_GCC_NO_CYGWIN)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_GCC_NO_CYGWIN)
list(APPEND EXTRA_LDFLAGS "-mno-cygwin")
list(APPEND SDL_LIBS "-mno-cygwin")
Expand All @@ -188,12 +200,35 @@ add_definitions(-DUSING_GENERATED_CONFIG_H)
# General includes
include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include)

if(EMSCRIPTEN)
# Set up default values for the currently supported set of subsystems:
# Emscripten/Javascript does not have assembly support, a dynamic library
# loading architecture, low-level CPU inspection or multithreading.
set(OPT_DEF_ASM FALSE)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF)
set(SDL_THREADS_ENABLED_BY_DEFAULT OFF)
set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF)
set(DLOPEN_ENABLED_BY_DEFAULT OFF)
else()
set(SDL_SHARED_ENABLED_BY_DEFAULT ON)
set(SDL_ATOMIC_ENABLED_BY_DEFAULT ON)
set(SDL_THREADS_ENABLED_BY_DEFAULT ON)
set(SDL_LOADSO_ENABLED_BY_DEFAULT ON)
set(SDL_CPUINFO_ENABLED_BY_DEFAULT ON)
set(DLOPEN_ENABLED_BY_DEFAULT ON)
endif()

set(SDL_SUBSYSTEMS
Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
File Loadso CPUinfo Filesystem)
foreach(_SUB ${SDL_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ON)
if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
set(SDL_${_OPT}_ENABLED_BY_DEFAULT ON)
endif()
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_ENABLED_BY_DEFAULT})
endforeach()

option_string(ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto")
Expand All @@ -216,9 +251,9 @@ dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "
set_option(VIDEO_DUMMY "Use dummy video driver" ON)
set_option(VIDEO_OPENGL "Include OpenGL support" ON)
set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON)
set_option(PTHREADS "Use POSIX threads for multi-threading" ${UNIX_OR_MAC_SYS})
set_option(PTHREADS "Use POSIX threads for multi-threading" ${PTHREADS_ENABLED_BY_DEFAULT})
dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF)
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ON)
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${DLOPEN_ENABLED_BY_DEFAULT})
set_option(OSS "Support the OSS audio API" ${UNIX_SYS})
set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS})
dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF)
Expand Down Expand Up @@ -251,7 +286,7 @@ set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})

# TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here
# The options below are for compatibility to configure's default behaviour.
set(SDL_SHARED ON CACHE BOOL "Build a shared version of the library")
set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library")
set(SDL_STATIC ON CACHE BOOL "Build a static version of the library")

# General source files
Expand Down Expand Up @@ -317,7 +352,7 @@ if(USE_GCC OR USE_CLANG)
set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2")
check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}"
HAVE_GCC_PREFERRED_STACK_BOUNDARY)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})

set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror")
check_c_source_compiles("
Expand All @@ -328,7 +363,7 @@ if(USE_GCC OR USE_CLANG)
if(HAVE_GCC_FVISIBILITY)
list(APPEND EXTRA_CFLAGS "-fvisibility=hidden")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})

check_c_compiler_flag(-Wall HAVE_GCC_WALL)
if(HAVE_GCC_WALL)
Expand Down Expand Up @@ -376,7 +411,7 @@ if(ASSEMBLY)
if(HAVE_MMX)
list(APPEND EXTRA_CFLAGS "-mmmx")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(3DNOW)
Expand All @@ -393,7 +428,7 @@ if(ASSEMBLY)
if(HAVE_3DNOW)
list(APPEND EXTRA_CFLAGS "-m3dnow")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSE)
Expand All @@ -416,7 +451,7 @@ if(ASSEMBLY)
if(HAVE_SSE)
list(APPEND EXTRA_CFLAGS "-msse")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSE2)
Expand All @@ -439,7 +474,7 @@ if(ASSEMBLY)
if(HAVE_SSE2)
list(APPEND EXTRA_CFLAGS "-msse2")
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SSEMATH)
Expand All @@ -464,7 +499,7 @@ if(ASSEMBLY)
return vec_splat_u32(0);
}
int main(int argc, char **argv) { }" HAVE_ALTIVEC)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR)
set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set
list(APPEND EXTRA_CFLAGS "-maltivec")
Expand Down Expand Up @@ -642,7 +677,49 @@ if(SDL_VIDEO)
endif()

# Platform-specific options and settings
if(UNIX AND NOT APPLE)
if(EMSCRIPTEN)
# Hide noisy warnings that intend to aid mostly during initial stages of porting a new
# project. Uncomment at will for verbose cross-compiling -I/../ path info.
add_definitions(-Wno-warn-absolute-paths)
if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_AUDIO_SOURCES})
set(HAVE_SDL_AUDIO TRUE)
endif()
if(SDL_FILESYSTEM)
set(SDL_FILESYSTEM_EMSCRIPTEN 1)
file(GLOB EM_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_FILESYSTEM_SOURCES})
set(HAVE_SDL_FILESYSTEM TRUE)
endif()
if(SDL_JOYSTICK)
set(SDL_JOYSTICK_EMSCRIPTEN 1)
file(GLOB EM_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_JOYSTICK_SOURCES})
set(HAVE_SDL_JOYSTICK TRUE)
endif()
if(SDL_POWER)
set(SDL_POWER_EMSCRIPTEN 1)
file(GLOB EM_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES})
set(HAVE_SDL_POWER TRUE)
endif()
if(SDL_VIDEO)
set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_VIDEO_SOURCES})
set(HAVE_SDL_VIDEO TRUE)

#enable gles
if(VIDEO_OPENGLES)
set(SDL_VIDEO_OPENGL_EGL 1)
set(HAVE_VIDEO_OPENGLES TRUE)
set(SDL_VIDEO_OPENGL_ES2 1)
set(SDL_VIDEO_RENDER_OGL_ES2 1)
endif()
endif()
elseif(UNIX AND NOT APPLE)
if(SDL_AUDIO)
if(SYSV5 OR SOLARIS OR HPUX)
set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
Expand Down Expand Up @@ -829,7 +906,7 @@ elseif(WINDOWS)
link_directories($ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH})
include_directories($ENV{DXSDK_DIR}\\Include)
endif()
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif()

if(SDL_AUDIO)
Expand Down
2 changes: 2 additions & 0 deletions build-scripts/config.sub
Expand Up @@ -1534,6 +1534,8 @@ case $os in
-pnacl*)
os=-pnacl
;;
-emscripten*)
;;
-none)
;;
*)
Expand Down
133 changes: 133 additions & 0 deletions configure
Expand Up @@ -21385,6 +21385,78 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h
fi
}

CheckEmscriptenGLES()
{
if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5
$as_echo_n "checking for EGL support... " >&6; }
video_opengl_egl=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

#include <EGL/egl.h>

int
main ()
{


;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

video_opengl_egl=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5
$as_echo "$video_opengl_egl" >&6; }
if test x$video_opengl_egl = xyes; then

$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h

fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5
$as_echo_n "checking for OpenGL ES v2 headers... " >&6; }
video_opengles_v2=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

int
main ()
{


;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

video_opengles_v2=yes

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5
$as_echo "$video_opengles_v2" >&6; }
if test x$video_opengles_v2 = xyes; then

$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h


$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h

SUMMARY_video="${SUMMARY_video} opengl_es2"
fi
fi
}

CheckInputEvents()
{
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5
Expand Down Expand Up @@ -23483,7 +23555,68 @@ $as_echo "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c"
have_filesystem=yes
fi
;;
*-*-emscripten* )
if test x$enable_video = xyes; then

$as_echo "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/video/emscripten/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} emscripten"
fi

if test x$enable_audio = xyes; then

$as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/audio/emscripten/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} emscripten"
fi

CheckVisibilityHidden
CheckDummyVideo
CheckDiskAudio
CheckDummyAudio
CheckDLOPEN
CheckClockGettime
CheckEmscriptenGLES

# Set up files for the power library
if test x$enable_power = xyes; then

$as_echo "#define SDL_POWER_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c"
have_power=yes
fi

# Set up files for the power library
if test x$enable_joystick = xyes; then

$as_echo "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c"
have_joystick=yes
fi

# Set up files for the filesystem library
if test x$enable_filesystem = xyes; then

$as_echo "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/filesystem/emscripten/*.c"
have_filesystem=yes
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then

$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
;;
*)
as_fn_error $? "
Expand Down

0 comments on commit fe40a17

Please sign in to comment.