From 8876bc7f5039cf898fa0944bf963f6eadca07d20 Mon Sep 17 00:00:00 2001 From: Fred Hornsey Date: Thu, 13 Oct 2022 01:50:39 -0500 Subject: [PATCH 1/2] Experimental WebAssembly Support Using emscripten --- .gitignore | 3 ++ ACE/ace/Notification_Queue.h | 2 + ACE/ace/Timer_Queue_T.inl | 3 ++ ACE/ace/config-emscripten.h | 51 +++++++++++++++++++ ACE/ace/os_include/sys/os_types.h | 3 +- .../makeinclude/platform_emscripten.GNU | 23 +++++++++ 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 ACE/ace/config-emscripten.h create mode 100644 ACE/include/makeinclude/platform_emscripten.GNU diff --git a/.gitignore b/.gitignore index 8d1ca1d523e79..c2bc162482f59 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ ipch/ *.*codeanalysis* read.lock fileList.bin + +*.js +*.wasm diff --git a/ACE/ace/Notification_Queue.h b/ACE/ace/Notification_Queue.h index 914904ac296fc..18749e4f2a221 100644 --- a/ACE/ace/Notification_Queue.h +++ b/ACE/ace/Notification_Queue.h @@ -13,6 +13,8 @@ #include "ace/Intrusive_List.h" #include "ace/Intrusive_List_Node.h" #include "ace/Unbounded_Queue.h" +#include "ace/Synch_Traits.h" +#include "ace/Thread_Mutex.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL diff --git a/ACE/ace/Timer_Queue_T.inl b/ACE/ace/Timer_Queue_T.inl index 15c0e8ef99d5f..72dc9e71e7067 100644 --- a/ACE/ace/Timer_Queue_T.inl +++ b/ACE/ace/Timer_Queue_T.inl @@ -1,4 +1,7 @@ // -*- C++ -*- + +#include "ace/Guard_T.h" + ACE_BEGIN_VERSIONED_NAMESPACE_DECL template ACE_INLINE FUNCTOR & diff --git a/ACE/ace/config-emscripten.h b/ACE/ace/config-emscripten.h new file mode 100644 index 0000000000000..f43c16b3a52f6 --- /dev/null +++ b/ACE/ace/config-emscripten.h @@ -0,0 +1,51 @@ +#ifndef ACE_CONFIG_EMSCRIPTEN_H +#define ACE_CONFIG_EMSCRIPTEN_H + +#define ACE_EMSCRIPTEN + +#define ACE_HAS_CPP11 + +// Threading +#define ACE_MT_SAFE 1 +#define ACE_HAS_THREADS 1 +#define ACE_HAS_PTHREADS +#define ACE_HAS_PTHREADS_UNIX98_EXT +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Basic Types +#define ACE_HAS_SSIZE_T +#define ACE_HAS_WCHAR + +// Time +#define ACE_HAS_POSIX_TIME +#define ACE_LACKS_TIMESPEC_T +#define ACE_HAS_NONCONST_SELECT_TIMEVAL +#define ACE_HAS_VOIDPTR_GETTIMEOFDAY + +// Everything else +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_MSG +#define ACE_HAS_CPU_SET_T +#define ACE_LACKS_ISCTYPE +#define ACE_HAS_STRBUF_T +#define ACE_HAS_SOCKLEN_T +#define ACE_LACKS_AUTO_PTR +#define ACE_HAS_SIGINFO_T +#define ACE_LACKS_SIGINFO_H +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_3_PARAM_WCSTOK +#define ACE_LACKS_ITOW +#define ACE_LACKS_WCSICMP +#define ACE_LACKS_WCSNICMP +#define ACE_HAS_DIRENT +#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG + +#include "config-posix.h" +#include "config-g++-common.h" + +// Not supported? https://github.com/emscripten-core/emscripten/issues/18050 +#ifdef ACE_HAS_AIO_CALLS +# undef ACE_HAS_AIO_CALLS +#endif + +#endif diff --git a/ACE/ace/os_include/sys/os_types.h b/ACE/ace/os_include/sys/os_types.h index b179c7051ad73..9d5fe106549a2 100644 --- a/ACE/ace/os_include/sys/os_types.h +++ b/ACE/ace/os_include/sys/os_types.h @@ -53,7 +53,8 @@ typedef double ACE_timer_t; #if defined (ACE_SIZEOF_LONG) && ACE_SIZEOF_LONG == 8 typedef off_t ACE_LOFF_T; -#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__APPLE__) +#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__APPLE__) || \ + defined (ACE_EMSCRIPTEN) typedef off_t ACE_LOFF_T; #elif defined (__QNX__) typedef off64_t ACE_LOFF_T; diff --git a/ACE/include/makeinclude/platform_emscripten.GNU b/ACE/include/makeinclude/platform_emscripten.GNU new file mode 100644 index 0000000000000..af6fa2bc14544 --- /dev/null +++ b/ACE/include/makeinclude/platform_emscripten.GNU @@ -0,0 +1,23 @@ +ACE_PLATFORM_CONFIG ?= config-emscripten.h +EXEEXT = .js + +debug ?= 1 +optimize ?= 1 +threads ?= 1 +inline ?= 1 +static_libs_only = 1 + +CROSS_COMPILE := THIS_VALUE_SHOULD_NOT_BE_USED +override_cross_compile = 1 +CC = emcc +CXX = em++ +AR = emar +LD = emcc + +ifeq ($(threads),1) + FLAGS_C_CC += -pthread + SOFLAGS += -pthread + LIBS += -lrt +endif + +include $(ACE_ROOT)/include/makeinclude/platform_clang_common.GNU From 83f8682c00b9b7e6dfce3cb6cc7f69c0eaf9d530 Mon Sep 17 00:00:00 2001 From: Fred Hornsey Date: Tue, 18 Apr 2023 22:13:42 -0500 Subject: [PATCH 2/2] Can Run ACE/tests/run_test.pl, Got OS_Test Passing Almost all other ACE tests are failing pretty spectacularly though. Also fixed some build warnings and added instructions to ACE-INSTALL. --- ACE/ACE-INSTALL.html | 40 ++++++++++++++++++- ACE/ace/config-emscripten.h | 5 ++- ACE/bin/PerlACE/ProcessNodeJS.pm | 21 ++++++++++ ACE/bin/PerlACE/Run_Test.pm | 5 +++ ACE/bin/PerlACE/TestTarget.pm | 28 ++++++++----- .../makeinclude/platform_clang_common.GNU | 8 ++-- .../makeinclude/platform_emscripten.GNU | 12 +++++- ACE/tests/OS_Test.cpp | 2 +- 8 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 ACE/bin/PerlACE/ProcessNodeJS.pm diff --git a/ACE/ACE-INSTALL.html b/ACE/ACE-INSTALL.html index 185fe6d9d5235..e87072b692e23 100644 --- a/ACE/ACE-INSTALL.html +++ b/ACE/ACE-INSTALL.html @@ -284,6 +284,7 @@

Building and Installing ACE

  • Windows (including MinGW and Cygwin)
  • VxWorks
  • Android
  • +
  • Emscripten WebAssembly
  • General Rules

    @@ -1823,7 +1824,7 @@

    OpenSSL

    OpenSSL. On Android, OpenSSL isn't part of the NDK Library and Android preloads the system SSL library (either OpenSSL or BoringSSL) for the Java Android API. This means OpenSSL MUST be statically linked to avoid - conflicts with the almost certianly incompatible system SSL library. + conflicts with the almost certainly incompatible system SSL library. To build OpenSSL for Android, please read NOTES.ANDROID that comes with OpenSSL's source code. The static libraries will used if the shared @@ -1833,6 +1834,43 @@

    OpenSSL

    building OpenSSL.

    +
    + +

    Building ACE for Emscripten WebAssembly

    + +

    NOTE: This has only been tested on Linux with NodeJS 16.18.

    + +Emscripten +is a LLVM toolchain that allows compiling C++ to +WebAssembly +that can be ran on a web browser or NodeJS. + +

    Building

    + +
      +
    1. Download and setup emscripten.
    2. +
    3. Run source emsdk_env.sh in emsdk.
    4. +
    5. Make sure MPC is available and MPC_ROOT is set.
    6. +
    7. Configure ACE: +
        +
      1. $ACE_ROOT/bin/MakeProjectCreator/config/default.features + should contain no_cxx11=0
      2. +
      3. $ACE_ROOT/include/makeinclude/platform_macros.GNU should contain + include $(ACE_ROOT)/include/makeinclude/platform_emscripten.GNU
      4. +
      5. $ACE_ROOT/ace/config.h should contain + #include "config-emscripten.h"
      6. +
      7. cd $ACE_ROOT/ace && mwc.pl -type gnuace .
      8. +
      +
    8. +
    9. Build ACE: cd $ACE_ROOT/ace && make -j4
    10. +
    + +

    Running Tests

    + +
    +DOC_TEST_1=NODEJS NODEJS_OS=local ./run_test.pl -Config STATIC -Config NODEJS
    +
    +

    Building and Installing ACE Network Services

    diff --git a/ACE/ace/config-emscripten.h b/ACE/ace/config-emscripten.h index f43c16b3a52f6..7ec287328aaae 100644 --- a/ACE/ace/config-emscripten.h +++ b/ACE/ace/config-emscripten.h @@ -40,10 +40,13 @@ #define ACE_HAS_DIRENT #define ACE_HAS_4_4BSD_SENDMSG_RECVMSG +// These exist, but don't seem to work correctly +#define ACE_LACKS_PWD_FUNCTIONS + #include "config-posix.h" #include "config-g++-common.h" -// Not supported? https://github.com/emscripten-core/emscripten/issues/18050 +// Not supported: https://github.com/emscripten-core/emscripten/issues/18050 #ifdef ACE_HAS_AIO_CALLS # undef ACE_HAS_AIO_CALLS #endif diff --git a/ACE/bin/PerlACE/ProcessNodeJS.pm b/ACE/bin/PerlACE/ProcessNodeJS.pm new file mode 100644 index 0000000000000..92be88dfe1188 --- /dev/null +++ b/ACE/bin/PerlACE/ProcessNodeJS.pm @@ -0,0 +1,21 @@ +package PerlACE::ProcessNodeJS; + +use strict; + +use PerlACE::Process; +our @ISA = qw(PerlACE::Process); + +sub new { + my $class = shift(); + my $name = shift(); + my $args = shift(); + my $node_args = shift() // ''; + + my $self = $class->SUPER::new("$name.js", $node_args); + bless($self, $class); + $self->IgnoreExeSubDir(1); + $self->{VALGRIND_CMD} = "node $node_args"; + return $self; +} + +1; diff --git a/ACE/bin/PerlACE/Run_Test.pm b/ACE/bin/PerlACE/Run_Test.pm index fe0bfb74aff49..ed9ddea0b2418 100644 --- a/ACE/bin/PerlACE/Run_Test.pm +++ b/ACE/bin/PerlACE/Run_Test.pm @@ -48,6 +48,11 @@ if ($PerlACE::Android_Test) { require PerlACE::ProcessAndroid; } +$PerlACE::NodeJS_Test = $config->check_config("NODEJS"); +if ($PerlACE::NodeJS_Test) { + require PerlACE::ProcessNodeJS; +} + # Figure out the svc.conf extension $svcconf_ext = $ENV{'ACE_RUNTEST_SVCCONF_EXT'}; if (!defined $svcconf_ext) { diff --git a/ACE/bin/PerlACE/TestTarget.pm b/ACE/bin/PerlACE/TestTarget.pm index 83d1d8f91c470..7e2b2b5be4226 100644 --- a/ACE/bin/PerlACE/TestTarget.pm +++ b/ACE/bin/PerlACE/TestTarget.pm @@ -82,9 +82,10 @@ sub new { my $proto = shift; my $class = ref ($proto) || $proto; - my $self = {}; - my $config_name = shift; + + my $self = {config_name => $config_name}; + bless ($self, $class); $self->GetConfigSettings($config_name); @@ -505,7 +506,7 @@ sub DeleteFile ($) print STDERR "Deleting remote $file from path $newfile using $cmd\n"; } if (system ($cmd) != 0) { - print STDERR "ERROR executing [".$cmd."]\n"; + print STDERR "ERROR executing [".$cmd."]\n"; } } else { unlink ($newfile); @@ -523,9 +524,9 @@ sub GetFile ($) $remote_file = $self->LocalFile($local_file); } if (defined $self->{GET_CMD}) { - if (system ($self->{GET_CMD}.' '.$remote_file.' '.$local_file) != 0) { - print STDERR "ERROR executing [".$self->{GET_CMD}." $remote_file $local_file]\n"; - } + if (system ($self->{GET_CMD}.' '.$remote_file.' '.$local_file) != 0) { + print STDERR "ERROR executing [".$self->{GET_CMD}." $remote_file $local_file]\n"; + } } elsif (($remote_file ne $local_file) && (File::Spec->rel2abs($remote_file) ne File::Spec->rel2abs($local_file))) { @@ -541,9 +542,9 @@ sub PutFile ($) my $src = shift; my $dest = $self->LocalFile ($src); if (defined $self->{PUT_CMD}) { - if (system ($self->{PUT_CMD}.' '.$src.' '.$dest) != 0) { - print STDERR "ERROR executing [".$self->{PUT_CMD}." $src $dest]\n"; - } + if (system ($self->{PUT_CMD}.' '.$src.' '.$dest) != 0) { + print STDERR "ERROR executing [".$self->{PUT_CMD}." $src $dest]\n"; + } } elsif (($src ne $dest) && (File::Spec->rel2abs($src) ne File::Spec->rel2abs($dest))) { @@ -594,7 +595,14 @@ sub WaitForFileTimed ($) sub CreateProcess ($) { my $self = shift; - my $process = new PerlACE::Process (@_); + + my $process; + if ($self->{config_name} eq 'NODEJS') { + $process = new PerlACE::ProcessNodeJS(@_); + } else { + $process = new PerlACE::Process (@_); + } + $process->Target($self); return $process; } diff --git a/ACE/include/makeinclude/platform_clang_common.GNU b/ACE/include/makeinclude/platform_clang_common.GNU index 667d394e1da0e..61992f911b3f5 100644 --- a/ACE/include/makeinclude/platform_clang_common.GNU +++ b/ACE/include/makeinclude/platform_clang_common.GNU @@ -9,9 +9,11 @@ ifneq ($(CROSS_COMPILE),) CXX = ${CROSS_COMPILE}clang++${CROSS_COMPILE_SUFFIX} AR = ${CROSS_COMPILE}ar${CROSS_COMPILE_SUFFIX} endif - # Cross-linker requires this for linked in shared libs that depend - # themselves on other shared libs (not directly linked in) - LDFLAGS += -Wl,-rpath-link,$(ACE_ROOT)/lib + ifneq ($(static_libs_only), 1) + # Cross-linker requires this for linked in shared libs that depend + # themselves on other shared libs (not directly linked in) + LDFLAGS += -Wl,-rpath-link,$(ACE_ROOT)/lib + endif ifneq (,$(HOST_ROOT)) TAO_IDLFLAGS += -g $(HOST_ROOT)/bin/ace_gperf TAO_IDL = $(HOST_ROOT)/bin/tao_idl diff --git a/ACE/include/makeinclude/platform_emscripten.GNU b/ACE/include/makeinclude/platform_emscripten.GNU index af6fa2bc14544..d00b9c4ce5595 100644 --- a/ACE/include/makeinclude/platform_emscripten.GNU +++ b/ACE/include/makeinclude/platform_emscripten.GNU @@ -2,7 +2,7 @@ ACE_PLATFORM_CONFIG ?= config-emscripten.h EXEEXT = .js debug ?= 1 -optimize ?= 1 +optimize ?= 0 threads ?= 1 inline ?= 1 static_libs_only = 1 @@ -16,8 +16,16 @@ LD = emcc ifeq ($(threads),1) FLAGS_C_CC += -pthread - SOFLAGS += -pthread + LDFLAGS += -pthread LIBS += -lrt endif +ifeq ($(debug),1) + LDFLAGS += -sASSERTIONS=2 +endif + +# TODO: Require choosing Filesystem model: +# https://emscripten.org/docs/api_reference/Filesystem-API.html +LDFLAGS += -sNODERAWFS=1 + include $(ACE_ROOT)/include/makeinclude/platform_clang_common.GNU diff --git a/ACE/tests/OS_Test.cpp b/ACE/tests/OS_Test.cpp index b9fad77374903..b40832466fc93 100644 --- a/ACE/tests/OS_Test.cpp +++ b/ACE/tests/OS_Test.cpp @@ -1208,7 +1208,7 @@ ace_ctype_test () ++retval; } - return 0; + return retval; } int