* Emscripten build support (#1845)

This commit is contained in:
Rangel Reale 2017-08-14 16:03:07 -03:00 committed by Aleksandar Fabijanic
parent 8cdd129d7e
commit 6cd8f3f73c
12 changed files with 250 additions and 25 deletions

View File

@ -21,7 +21,7 @@
#include "Poco/Foundation.h"
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
#include <semaphore.h>
#endif
@ -41,7 +41,7 @@ private:
std::string getFileName();
std::string _name;
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
sem_t* _sem;
#else
int _semid; // semaphore id

View File

@ -23,7 +23,7 @@
#include "Poco/Foundation.h"
#include <sys/types.h>
#include <sys/stat.h>
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
#include <semaphore.h>
#endif
@ -44,7 +44,7 @@ private:
std::string getFileName();
std::string _name;
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
sem_t* _sem;
#else
int _semid; // semaphore id

View File

@ -40,6 +40,7 @@
#define POCO_OS_VXWORKS 0x000c
#define POCO_OS_CYGWIN 0x000d
#define POCO_OS_NACL 0x000e
#define POCO_OS_EMSCRIPTEN 0x000f
#define POCO_OS_UNKNOWN_UNIX 0x00ff
#define POCO_OS_WINDOWS_NT 0x1001
#define POCO_OS_WINDOWS_CE 0x1011
@ -62,7 +63,10 @@
#elif defined(__NACL__)
#define POCO_OS_FAMILY_UNIX 1
#define POCO_OS POCO_OS_NACL
#elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__TOS_LINUX__) || defined(EMSCRIPTEN)
#elif defined(__EMSCRIPTEN__) || defined(EMSCRIPTEN)
#define POCO_OS_FAMILY_UNIX 1
#define POCO_OS POCO_OS_EMSCRIPTEN
#elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__TOS_LINUX__)
#define POCO_OS_FAMILY_UNIX 1
#define POCO_OS POCO_OS_LINUX
#elif defined(__APPLE__) || defined(__TOS_MACOS__)
@ -135,7 +139,7 @@
#if defined(__ALPHA) || defined(__alpha) || defined(__alpha__) || defined(_M_ALPHA)
#define POCO_ARCH POCO_ARCH_ALPHA
#define POCO_ARCH_LITTLE_ENDIAN 1
#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(EMSCRIPTEN)
#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(EMSCRIPTEN) || defined(__EMSCRIPTEN__)
#define POCO_ARCH POCO_ARCH_IA32
#define POCO_ARCH_LITTLE_ENDIAN 1
#elif defined(_IA64) || defined(__IA64__) || defined(__ia64__) || defined(__ia64) || defined(_M_IA64)

View File

@ -20,7 +20,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
#include <semaphore.h>
#else
#include <unistd.h>
@ -55,7 +55,7 @@ NamedEventImpl::NamedEventImpl(const std::string& name):
_name(name)
{
std::string fileName = getFileName();
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
_sem = sem_open(fileName.c_str(), O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0);
if ((long) _sem == (long) SEM_FAILED)
throw SystemException(Poco::format("cannot create named mutex %s (sem_open() failed, errno=%d)", fileName, errno), _name);
@ -80,13 +80,13 @@ NamedEventImpl::NamedEventImpl(const std::string& name):
_semid = semget(key, 1, 0);
}
else throw SystemException(Poco::format("cannot create named mutex %s (semget() failed, errno=%d)", fileName, errno), _name);
#endif // defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#endif // defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
}
NamedEventImpl::~NamedEventImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
sem_close(_sem);
#endif
}
@ -94,7 +94,7 @@ NamedEventImpl::~NamedEventImpl()
void NamedEventImpl::setImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
if (sem_post(_sem) != 0)
throw SystemException("cannot set named event", _name);
#else
@ -110,7 +110,7 @@ void NamedEventImpl::setImpl()
void NamedEventImpl::waitImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
int err;
do
{

View File

@ -20,7 +20,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(_AIX) || defined(__EMSCRIPTEN__)
#include <semaphore.h>
#else
#include <unistd.h>
@ -55,7 +55,7 @@ NamedMutexImpl::NamedMutexImpl(const std::string& name):
_name(name)
{
std::string fileName = getFileName();
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
_sem = sem_open(fileName.c_str(), O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1);
if ((long) _sem == (long) SEM_FAILED)
throw SystemException(Poco::format("cannot create named mutex %s (sem_open() failed, errno=%d)", fileName, errno), _name);
@ -80,13 +80,13 @@ NamedMutexImpl::NamedMutexImpl(const std::string& name):
_semid = semget(key, 1, 0);
}
else throw SystemException(Poco::format("cannot create named mutex %s (semget() failed, errno=%d)", fileName, errno), _name);
#endif // defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#endif // defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
}
NamedMutexImpl::~NamedMutexImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
sem_close(_sem);
#endif
}
@ -94,7 +94,7 @@ NamedMutexImpl::~NamedMutexImpl()
void NamedMutexImpl::lockImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
int err;
do
{
@ -120,7 +120,7 @@ void NamedMutexImpl::lockImpl()
bool NamedMutexImpl::tryLockImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
return sem_trywait(_sem) == 0;
#else
struct sembuf op;
@ -134,7 +134,7 @@ bool NamedMutexImpl::tryLockImpl()
void NamedMutexImpl::unlockImpl()
{
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX)
#if defined(sun) || defined(__APPLE__) || defined(__osf__) || defined(__QNX__) || defined(_AIX) || defined(__EMSCRIPTEN__)
if (sem_post(_sem) != 0)
throw SystemException("cannot unlock named mutex", _name);
#else

View File

@ -54,7 +54,9 @@ public:
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGPIPE);
#if POCO_OS != POCO_OS_EMSCRIPTEN
pthread_sigmask(SIG_BLOCK, &sset, 0);
#endif
}
~SignalBlocker()
{
@ -451,7 +453,9 @@ void* ThreadImpl::runnableEntry(void* pThread)
sigaddset(&sset, SIGQUIT);
sigaddset(&sset, SIGTERM);
sigaddset(&sset, SIGPIPE);
#if POCO_OS != POCO_OS_EMSCRIPTEN
pthread_sigmask(SIG_BLOCK, &sset, 0);
#endif
#endif
ThreadImpl* pThreadImpl = reinterpret_cast<ThreadImpl*>(pThread);

View File

@ -63,7 +63,7 @@
defined(__SH4__) || defined(__alpha__) || \
defined(_MIPS_ARCH_MIPS32R2) || \
defined(__AARCH64EL__) || \
defined(nios2) || defined(__nios2) || defined(__nios2__)
defined(nios2) || defined(__nios2) || defined(__nios2__) || defined(__EMSCRIPTEN__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
#if defined(_WIN32)

View File

@ -187,7 +187,7 @@ private:
void handlePidFile(const std::string& name, const std::string& value);
bool isDaemon(int argc, char** argv);
void beDaemon();
#if defined(POCO_ANDROID) || defined(__NACL__)
#if defined(POCO_ANDROID) || defined(__NACL__) || defined(__EMSCRIPTEN__)
static Poco::Event _terminate;
#endif
#elif defined(POCO_OS_FAMILY_WINDOWS)

View File

@ -65,7 +65,7 @@ SERVICE_STATUS ServerApplication::_serviceStatus;
SERVICE_STATUS_HANDLE ServerApplication::_serviceStatusHandle = 0;
#endif
#endif
#if defined(POCO_VXWORKS) || defined(POCO_ANDROID) || defined(__NACL__)
#if defined(POCO_VXWORKS) || defined(POCO_ANDROID) || defined(__NACL__) || defined(__EMSCRIPTEN__)
Poco::Event ServerApplication::_terminate;
#endif
@ -103,7 +103,7 @@ void ServerApplication::terminate()
{
#if defined(POCO_OS_FAMILY_WINDOWS)
_terminate.set();
#elif defined(POCO_VXWORKS) || defined(POCO_ANDROID) || defined(__NACL__)
#elif defined(POCO_VXWORKS) || defined(POCO_ANDROID) || defined(__NACL__) || defined(__EMSCRIPTEN__)
_terminate.set();
#else
Poco::Process::requestTermination(Process::id());
@ -593,7 +593,7 @@ void ServerApplication::defineOptions(OptionSet& options)
//
void ServerApplication::waitForTerminationRequest()
{
#if !defined(POCO_ANDROID) && !defined(__NACL__)
#if !defined(POCO_ANDROID) && !defined(__NACL__) && !defined(__EMSCRIPTEN__)
sigset_t sset;
sigemptyset(&sset);
if (!std::getenv("POCO_ENABLE_DEBUGGER"))
@ -605,7 +605,7 @@ void ServerApplication::waitForTerminationRequest()
sigprocmask(SIG_BLOCK, &sset, NULL);
int sig;
sigwait(&sset, &sig);
#else // POCO_ANDROID || __NACL__
#else // POCO_ANDROID || __NACL__ || __EMSCRIPTEN__
_terminate.wait();
#endif
}

77
build/config/emscripten Normal file
View File

@ -0,0 +1,77 @@
#
# $Id: //poco/1.4/build/config/Linux#2 $
#
# Linux
#
# Make settings for emscripten
#
#
#
# General Settings
#
LINKMODE ?= SHARED
POCO_TARGET_OSNAME = emscripten
POCO_TARGET_OSARCH = asmjs
CROSS_COMPILE = em
#
# Define Tools
#
CC = ${CROSS_COMPILE}cc
CXX = ${CROSS_COMPILE}++
LINK = $(CXX)
LIB = ${CROSS_COMPILE}ar rc
RANLIB = ${CROSS_COMPILE}ranlib
SHLIB = $(CXX) -shared -Wl,-soname,$(notdir $@) -o $@
SHLIBLN = $(POCO_BASE)/build/script/shlibln
# em++ strips by default, there is no default strip command
STRIP = /bin/true
DEP = $(POCO_BASE)/build/script/makedepend.gcc
SHELL = sh
RM = rm -rf
CP = cp
MKDIR = mkdir -p
#
# Extension for Shared Libraries
#
SHAREDLIBEXT = .so.$(target_version)
SHAREDLIBLINKEXT = .so
BINEXT = .html
#
# Compiler and Linker Flags
#
CFLAGS = -s USE_PTHREADS=1
CFLAGS32 =
CFLAGS64 =
CXXFLAGS = -Wall -Wno-sign-compare -s USE_PTHREADS=1
CXXFLAGS32 =
CXXFLAGS64 =
LINKFLAGS = -s USE_PTHREADS=1
LINKFLAGS32 =
LINKFLAGS64 =
STATICOPT_CC =
STATICOPT_CXX =
STATICOPT_LINK =
SHAREDOPT_CC = -fPIC
SHAREDOPT_CXX = -fPIC
SHAREDOPT_LINK = -Wl,-rpath,$(LIBPATH)
DEBUGOPT_CC = -g -D_DEBUG
DEBUGOPT_CXX = -g -D_DEBUG
DEBUGOPT_LINK = -g
RELEASEOPT_CC = -O2 -DNDEBUG
RELEASEOPT_CXX = -O2 -DNDEBUG
RELEASEOPT_LINK = -O2
#
# System Specific Flags
#
SYSFLAGS = -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DPOCO_HAVE_FD_EPOLL
#
# System Specific Libraries
#
SYSLIBS = -lpthread -ldl -lrt

View File

@ -0,0 +1,77 @@
#
# $Id: //poco/1.4/build/config/Linux#2 $
#
# Linux
#
# Make settings for emscripten/webassembly
#
#
#
# General Settings
#
LINKMODE ?= SHARED
POCO_TARGET_OSNAME = emscripten
POCO_TARGET_OSARCH = wasm
CROSS_COMPILE = em
#
# Define Tools
#
CC = ${CROSS_COMPILE}cc
CXX = ${CROSS_COMPILE}++
LINK = $(CXX)
LIB = ${CROSS_COMPILE}ar rc
RANLIB = ${CROSS_COMPILE}ranlib
SHLIB = $(CXX) -shared -Wl,-soname,$(notdir $@) -o $@
SHLIBLN = $(POCO_BASE)/build/script/shlibln
# em++ strips by default, there is no default strip command
STRIP = /bin/true
DEP = $(POCO_BASE)/build/script/makedepend.gcc
SHELL = sh
RM = rm -rf
CP = cp
MKDIR = mkdir -p
#
# Extension for Shared Libraries
#
SHAREDLIBEXT = .so.$(target_version)
SHAREDLIBLINKEXT = .so
BINEXT = .html
#
# Compiler and Linker Flags
#
CFLAGS = -s WASM=1
CFLAGS32 =
CFLAGS64 =
CXXFLAGS = -Wall -Wno-sign-compare -s WASM=1
CXXFLAGS32 =
CXXFLAGS64 =
LINKFLAGS = -s WASM=1
LINKFLAGS32 =
LINKFLAGS64 =
STATICOPT_CC =
STATICOPT_CXX =
STATICOPT_LINK =
SHAREDOPT_CC = -fPIC
SHAREDOPT_CXX = -fPIC
SHAREDOPT_LINK = -Wl,-rpath,$(LIBPATH)
DEBUGOPT_CC = -g -D_DEBUG
DEBUGOPT_CXX = -g -D_DEBUG
DEBUGOPT_LINK = -g
RELEASEOPT_CC = -O2 -DNDEBUG
RELEASEOPT_CXX = -O2 -DNDEBUG
RELEASEOPT_LINK = -O2
#
# System Specific Flags
#
SYSFLAGS = -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DPOCO_HAVE_FD_EPOLL
#
# System Specific Libraries
#
SYSLIBS = -lpthread -ldl -lrt

View File

@ -0,0 +1,63 @@
POCO C++ Libraries Emscripten Platform Notes
AAAIntroduction
!!!Introduction
POCO can be compiled to javascript/WebAssembly using the emscripten toolchain.
Currently this is a work in progress.
!!!Requirements
!!Emscripten toolchain
Install the emscripten toolchain following these instructions:
http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
The version 1.37.10 was used for this initial work.
You should then run the emsdk_env.sh script to load the paths and environment variables.
!!Compiling the POCO C++ Libraries
It is best to always compile as shared libraries, there are some incompatibilities with the
".a" static library format. The generated files aren't "true" shared libraries, but
the emscripten toolchain knows how to best handle them.
!!!Restrictions
For the most part, the Linux and Emscripten ports of the POCO C++ Libraries are very similar.
However, there are a few restrictions.
!!Poco::Thread
At the time of this writing, the emscripten thread support is being tested, and it only may
be working on the Firefox Nighly build. It is also not yet available for WebAssembly.
!!!Build Notes
There are 2 configuration files for emscripten:
- emscripten: compile to asm.js (pure javascript)
- emscripten-wasm: compile to WebAssembly
The <*emscripten*> build configuration (located in <*$POCO_BASE/build/config/emscripten*>)
is used to cross-build for Emscripten from a Linux or Mac OS X host.
To build the POCO C++ Libraries on a Linux or Mac OS X host:
./configure --config=emscripten
./make -j4
----
To compile your own application, you must set the same compiler parameters as when you built POCO,
for example, you must set the "-s USE_PTHREADS=1" on all your source files and link flags when
using threads.
!!Samples
The samples executables are generated in .js format (with sibling .html file). To run, use emrun.
emrun executable.html
----