portable icon indicating copy to clipboard operation
portable copied to clipboard

Autoconf builds do not support emscripten

Open CodingMarkus opened this issue 1 year ago • 5 comments

According to README, Emscripten is a supported platform but it's not possible to build with Emscripten.

# emconfigure ./configure --enable-static --disable-shared --host=wasm32-unknown-emscripten

fails with

checking whether to build static libraries... yes
checking size of time_t... 8
configure: error: unsupported platform: emscripten
emconfigure: error: './configure --enable-static --disable-shared --host=wasm32-unknown-emscripten' failed (returned 1)

configure.log says

configure:13339: error: unsupported platform: emscripten

configure without --host=wasm32-unknown-emscripten will work but then make will fail as platform is then set to my native build platform, which is macOS (aarch64-apple-darwin23.6.0) and that will not produce a correct wasm/asmjs build.

The build process will fail

  CC       compat/getentropy_osx.lo
compat/getentropy_osx.c:23:10: fatal error: 'TargetConditionals.h' file not found
   23 | #include <TargetConditionals.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Building getentropy_osx is wrong to begin with when doing an Emscripten build.

CodingMarkus avatar Sep 03 '24 13:09 CodingMarkus

The readme file tells you to use cmake:

https://github.com/libressl/portable?tab=readme-ov-file#emscripten

That works in CI on linux.

botovq avatar Sep 03 '24 14:09 botovq

Is there any specific reason for not supporting configure/make with Emcripten?

With an older version of LibreSSL, I was able to make that work with just few tiny adoptions, see https://github.com/libressl/portable/commit/210a30f510f3bf4b4bd82c33081a07db32b7ac98

This commit is no longer compatible to the current source code state which now has added official Emscripten to various files but it was working fine when I forked the project 2024-05-26 (0dfa4f3b764521f4ee23850b705973c4b55b23b7).

I'm pretty sure that making Emscripten work with configure/make would not require a lot more work than it used to in a few months ago.

CodingMarkus avatar Sep 03 '24 16:09 CodingMarkus

The only reason is that nobody put in the effort to add it.

Thanks for sharing that commit.

We'd be perfectly happy to review and land an updated version of that if you care to submit it as a PR, otherwise someone might draw inspiration for it. However, before we can land something like it, we will need to have some way to test it in CI.

botovq avatar Sep 03 '24 16:09 botovq

Okay, here's an updated commit that should add emscripten support via autoconf: https://github.com/libressl/portable/commit/d3fe9139fb70290a28e98964437dc56d5188139f

Since there is no support for wasm32/asmjs in OpenBSD (e.g. missing from openbsd/src/lib/libcrypto/arch), the i386 files are used instead wherever arch-dependent files are expected. I found out that this is the same thing that CMake does, well, actually it is what Emscript does:

.../libexec/emscripten/cmake/Modules/Platform/Emscripten.cmake

contains these lines

if (NOT DEFINED EMSCRIPTEN_SYSTEM_PROCESSOR)
  set(EMSCRIPTEN_SYSTEM_PROCESSOR x86)
endif()
set(CMAKE_SYSTEM_PROCESSOR ${EMSCRIPTEN_SYSTEM_PROCESSOR})

and that way CMake thinks it is building for i386 when it is building for Emscripten.

This is a bit suboptimal, as both targets are not really i386, and optimizations for i386 might not work as well on Emscripten.

Also, i386 assembly code cannot be used anyway, but I still prepared the build for supporting assembly (does something like wasm-assembly even exist? If not, maybe it will one day), just like in the case of mips, which also disables assembly, but would be prepared to use some one day.

Ideally, there would be separate platform files for Emscripten, but then I would have to create them from scratch somewhere, so for now I just modified update.sh to copy the i386 files to the wasm32 and asmjs arch directories. With custom files, some of the changes wouldn't even be necessary (e.g. no crypto_cpu_caps.c would be needed).

The build works for me using either

./autogen.sh \
&& emconfigure ./configure --host=wasm32-unknown-emscripten \
&& emmake make

or

./autogen.sh \
&& emconfigure ./configure --host=asmjs-unknown-emscripten \
&& emmake make

because of course you have to cross compile, otherwise autoconf would build for the current build platform instead.

Theoretically, this could be changed by detecting Emscripten in the configure script and then automatically assuming wasm32-unknown-emscripten, in which case only asmjs builds would have to be cross-compiled and emconfigure ./configure would automatically do a wasm32 build, but I'm not the autoconf expert, so I kept it simple.

Let me know what you think. Suggestions? Improvements? Criticism?

CodingMarkus avatar Oct 28 '24 16:10 CodingMarkus

I made another small fix to ensure that .wasm and .js files are also cleaned on make clean.

https://github.com/libressl/portable/commit/fb8c8b5290cda3b770d0ac419cefafaf151508c7

I'm still waiting for feedback, so I know if it's worth to make a pull request.

CodingMarkus avatar Nov 05 '24 13:11 CodingMarkus