aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2014-02-24 08:46:09 -0800
committerDan Gohman <sunfish@google.com>2014-02-25 11:58:53 -0800
commitc600155b1fef26a248d6467a89030328db0fedab (patch)
tree5a72da7c752516383151913320d9713fd103eaa6
parent377e75950fd04ed2705befe00b0c46f0e88a0cf7 (diff)
Begin using the Emscripten toolchain in clang.
With the Emscripten toolchain, we can make clang do more of what we need directly rather than in the wrapper scripts.
-rw-r--r--system/include/EGL/eglplatform.h2
-rw-r--r--system/include/SDL/SDL_config_minimal.h2
-rw-r--r--system/include/SDL/SDL_stdinc.h2
-rw-r--r--system/include/emscripten/emscripten.h12
-rw-r--r--system/include/jansson.h2
-rw-r--r--system/lib/compiler-rt/int_endianness.h2
-rw-r--r--system/lib/dlmalloc.c2
-rw-r--r--tests/asmjs-unknown-emscripten.c98
-rw-r--r--tests/test_core.py5
-rw-r--r--tools/shared.py33
10 files changed, 136 insertions, 24 deletions
diff --git a/system/include/EGL/eglplatform.h b/system/include/EGL/eglplatform.h
index 2db2cc47..77e885a8 100644
--- a/system/include/EGL/eglplatform.h
+++ b/system/include/EGL/eglplatform.h
@@ -75,7 +75,7 @@ typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
-#elif defined(EMSCRIPTEN)
+#elif defined(__EMSCRIPTEN__)
typedef int EGLNativeDisplayType;
typedef int EGLNativeWindowType;
diff --git a/system/include/SDL/SDL_config_minimal.h b/system/include/SDL/SDL_config_minimal.h
index ea0cec10..18951f18 100644
--- a/system/include/SDL/SDL_config_minimal.h
+++ b/system/include/SDL/SDL_config_minimal.h
@@ -33,7 +33,7 @@
#include <stddef.h>
#include <stdarg.h>
-#if !defined(EMSCRIPTEN) && !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H)
+#if !defined(__EMSCRIPTEN__) && !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H)
typedef unsigned int size_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
diff --git a/system/include/SDL/SDL_stdinc.h b/system/include/SDL/SDL_stdinc.h
index c4ce7ccd..508ecdb4 100644
--- a/system/include/SDL/SDL_stdinc.h
+++ b/system/include/SDL/SDL_stdinc.h
@@ -65,7 +65,7 @@
#endif
#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
-#elif defined(EMSCRIPTEN) || defined(HAVE_STDINT_H)
+#elif defined(__EMSCRIPTEN__) || defined(HAVE_STDINT_H)
# include <stdint.h>
#endif
#ifdef HAVE_CTYPE_H
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 852a8e0d..c36bec63 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -14,7 +14,7 @@
extern "C" {
#endif
-#if !EMSCRIPTEN
+#if !__EMSCRIPTEN__
#include <SDL/SDL.h> /* for SDL_Delay in async_call */
#endif
@@ -141,7 +141,7 @@ extern void emscripten_async_load_script(const char *script, void (*onload)(), v
* you created an object on the stack, it will be cleaned up
* before the main loop will be called the first time.
*/
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
extern void emscripten_set_main_loop(void (*func)(), int fps, int simulate_infinite_loop);
extern void emscripten_set_main_loop_arg(void (*func)(void*), void *arg, int fps, int simulate_infinite_loop);
extern void emscripten_pause_main_loop();
@@ -166,7 +166,7 @@ extern void emscripten_cancel_main_loop();
* are not counted, do not block the main loop, and can fire
* at specific time in the future.
*/
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
extern void _emscripten_push_main_loop_blocker(void (*func)(void *), void *arg, const char *name);
extern void _emscripten_push_uncounted_main_loop_blocker(void (*func)(void *), void *arg, const char *name);
#else
@@ -188,7 +188,7 @@ inline void _emscripten_push_uncounted_main_loop_blocker(void (*func)(void *), v
* to 10, then push 10 blockers, as they complete the user will
* see x/10 and so forth.
*/
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
extern void emscripten_set_main_loop_expected_blockers(int num);
#else
inline void emscripten_set_main_loop_expected_blockers(int num) {}
@@ -203,7 +203,7 @@ inline void emscripten_set_main_loop_expected_blockers(int num) {}
* If millis is negative, the browser's requestAnimationFrame
* mechanism is used.
*/
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
extern void emscripten_async_call(void (*func)(void *), void *arg, int millis);
#else
inline void emscripten_async_call(void (*func)(void *), void *arg, int millis) {
@@ -247,7 +247,7 @@ void emscripten_get_canvas_size(int *width, int *height, int *isFullscreen);
* absolute time, and is only meaningful in comparison to
* other calls to this function. The unit is ms.
*/
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
double emscripten_get_now();
#else
#include <time.h>
diff --git a/system/include/jansson.h b/system/include/jansson.h
index 04c345e9..53715fcc 100644
--- a/system/include/jansson.h
+++ b/system/include/jansson.h
@@ -82,7 +82,7 @@ typedef long long json_int_t;
typedef long json_int_t;
#endif /* JSON_INTEGER_IS_LONG_LONG */
-#ifdef EMSCRIPTEN
+#ifdef __EMSCRIPTEN__
extern "C" bool json_typeof(const void *object);
extern "C" bool json_is_object(const void *object);
extern "C" bool json_is_array(const void *object);
diff --git a/system/lib/compiler-rt/int_endianness.h b/system/lib/compiler-rt/int_endianness.h
index 17905355..fa294c49 100644
--- a/system/lib/compiler-rt/int_endianness.h
+++ b/system/lib/compiler-rt/int_endianness.h
@@ -100,7 +100,7 @@
#endif /* Windows */
-#if defined(EMSCRIPTEN)
+#if defined(__EMSCRIPTEN__)
#define _YUGA_LITTLE_ENDIAN 1
#define _YUGA_BIG_ENDIAN 0
diff --git a/system/lib/dlmalloc.c b/system/lib/dlmalloc.c
index ce2c25f1..04e9e47b 100644
--- a/system/lib/dlmalloc.c
+++ b/system/lib/dlmalloc.c
@@ -1,6 +1,6 @@
/* XXX Emscripten XXX */
-#if EMSCRIPTEN
+#if __EMSCRIPTEN__
#define DLMALLOC_EXPORT __attribute__((__weak__, __visibility__("default")))
/* mmap uses malloc, so malloc can't use mmap */
#define HAVE_MMAP 0
diff --git a/tests/asmjs-unknown-emscripten.c b/tests/asmjs-unknown-emscripten.c
new file mode 100644
index 00000000..36071964
--- /dev/null
+++ b/tests/asmjs-unknown-emscripten.c
@@ -0,0 +1,98 @@
+#ifndef __EMSCRIPTEN__
+#error __EMSCRIPTEN__ is not defined
+#endif
+#ifndef __asmjs__
+#error __asmjs__ is not defined
+#endif
+#ifdef __cplusplus
+#ifndef _GNU_SOURCE
+#error _GNU_SOURCE is not defined in C++
+#endif
+#endif
+#ifndef __unix__
+#error __unix__ is not defined
+#endif
+#ifndef __LITTLE_ENDIAN__
+#error __LITTLE_ENDIAN__ is not defined
+#endif
+
+#ifdef __clang__
+#if __has_feature(pnacl)
+#error has feature pnacl
+#endif
+#endif
+
+#ifdef __native_client__
+#error __native_client__ is defined
+#endif
+#ifdef __pnacl__
+#error __pnacl__ is defined
+#endif
+#ifdef __ELF__
+#error __ELF__ is defined
+#endif
+#ifdef __i386__
+#error __i386__ is defined
+#endif
+#ifdef __i386
+#error __i386 is defined
+#endif
+#ifdef i386
+#error i386 is defined
+#endif
+#ifdef __SSE__
+#error __SSE__ is defined
+#endif
+#ifdef __SSE2__
+#error __SSE2__ is defined
+#endif
+#ifdef __SSE_MATH__
+#error __SSE_MATH__ is defined
+#endif
+#ifdef __SSE2_MATH__
+#error __SSE2_MATH__ is defined
+#endif
+#ifdef __MMX__
+#error __MMX__ is defined
+#endif
+#ifdef __APPLE__
+#error __APPLE__ is defined
+#endif
+#ifdef __linux__
+#error __linux__ is defined
+#endif
+#ifdef __BIG_ENDIAN__
+#error __BIG_ENDIAN__ is defined
+#endif
+#ifdef __LP64__
+#error __LP64__ is defined
+#endif
+
+// We prefer to use __EMSCRIPTEN__, but for compatibility, we define
+// EMSCRIPTEN too.
+#ifndef EMSCRIPTEN
+#error EMSCRIPTEN is not defined
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+#define STRINGIZE_HELPER(x) #x
+#define STRINGIZE(x) STRINGIZE_HELPER(x)
+
+int main() {
+ assert(sizeof(void*) == 4);
+ assert(sizeof(long) == 4);
+ assert(sizeof(intmax_t) == 8);
+ assert(__alignof(double) == 8);
+ assert(sizeof(long double) == 8);
+ assert(__alignof(long double) == 8);
+ assert(sizeof(intptr_t) == 4);
+ assert(sizeof(size_t) == 4);
+ assert(sizeof(ptrdiff_t) == 4);
+ assert(__FLT_EVAL_METHOD__ == 0);
+ assert(strcmp(STRINGIZE(__USER_LABEL_PREFIX__), "") == 0);
+ return 0;
+}
diff --git a/tests/test_core.py b/tests/test_core.py
index 789ea776..7d6199ff 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -504,6 +504,11 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run(open(path_from_root('tests', 'sha1.c')).read(), 'SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6')
+ def test_asmjs_unknown_emscripten(self):
+ if self.emcc_args == None: return self.skip('needs emcc')
+ if not self.is_emscripten_abi(): return self.skip('asmjs-unknown-emscripten needed for asmjs-unknown-emscripten target test')
+ self.do_run(open(path_from_root('tests', 'asmjs-unknown-emscripten.c')).read(), '')
+
def test_cube2md5(self):
if self.emcc_args == None: return self.skip('needs emcc')
if not self.is_emscripten_abi(): return self.skip('asmjs-unknown-emscripten needed for accurate math')
diff --git a/tools/shared.py b/tools/shared.py
index a9a3fa4e..e6be09d0 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -626,20 +626,29 @@ try:
COMPILER_OPTS # Can be set in EM_CONFIG, optionally
except:
COMPILER_OPTS = []
-COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-DEMSCRIPTEN', '-D__EMSCRIPTEN__',
- '-fno-math-errno',
- #'-fno-threadsafe-statics', # disabled due to issue 1289
+COMPILER_OPTS = COMPILER_OPTS + [#'-fno-threadsafe-statics', # disabled due to issue 1289
'-target', LLVM_TARGET]
-# For temporary compatibility, treat 'le32-unknown-nacl' as 'asmjs-unknown-emscripten'.
-if LLVM_TARGET == 'asmjs-unknown-emscripten' or LLVM_TARGET == 'le32-unknown-nacl':
- COMPILER_OPTS = filter(lambda opt: opt != '-m32', COMPILER_OPTS) # asmjs-unknown-emscripten target is 32-bit anyhow, no need for -m32
- COMPILER_OPTS += ['-U__native_client__', '-U__pnacl__', '-U__ELF__'] # The nacl target is originally used for Google Native Client. Emscripten is not NaCl, so remove the platform #define, when using their triple.
-
-# Remove various platform specific defines, and set little endian
-COMPILER_STANDARDIZATION_OPTS = ['-U__i386__', '-U__i386', '-Ui386', '-U__STRICT_ANSI__', '-D__IEEE_LITTLE_ENDIAN',
- '-U__SSE__', '-U__SSE_MATH__', '-U__SSE2__', '-U__SSE2_MATH__', '-U__MMX__',
- '-U__APPLE__', '-U__linux__']
+# COMPILER_STANDARDIZATION_OPTS: Options to correct various predefined macro options.
+COMPILER_STANDARDIZATION_OPTS = []
+
+# When we're not using an appropriate target triple, use -m32 to get i386, which we
+# can mostly make work.
+if LLVM_TARGET != 'asmjs-unknown-emscripten' and LLVM_TARGET != 'le32-unknown-nacl':
+ COMPILER_OPTS += ['-m32']
+ COMPILER_STANDARDIZATION_OPTS += ['-U__i386__', '-U__i386', '-Ui386',
+ '-U__SSE__', '-U__SSE_MATH__', '-U__SSE2__', '-U__SSE2_MATH__', '-U__MMX__',
+ '-U__APPLE__', '-U__linux__']
+
+# With the asmjs-unknown-emscripten target triple, clang sets up language modes
+# and predefined macros properly. When using the other targets, we have to set things
+# up manually.
+if LLVM_TARGET != 'asmjs-unknown-emscripten':
+ COMPILER_OPTS += ['-fno-math-errno']
+ COMPILER_STANDARDIZATION_OPTS += ['-D__IEEE_LITTLE_ENDIAN']
+if LLVM_TARGET == 'le32-unknown-nacl':
+ COMPILER_OPTS += ['-DEMSCRIPTEN', '-D__EMSCRIPTEN__', '-fno-math-errno',
+ '-U__native_client__', '-U__pnacl__', '-U__ELF__']
USE_EMSDK = not os.environ.get('EMMAKEN_NO_SDK')