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-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/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..7ec287328aaae --- /dev/null +++ b/ACE/ace/config-emscripten.h @@ -0,0 +1,54 @@ +#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 + +// 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 +#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/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 new file mode 100644 index 0000000000000..d00b9c4ce5595 --- /dev/null +++ b/ACE/include/makeinclude/platform_emscripten.GNU @@ -0,0 +1,31 @@ +ACE_PLATFORM_CONFIG ?= config-emscripten.h +EXEEXT = .js + +debug ?= 1 +optimize ?= 0 +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 + 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