-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add partial support for WASI #75
base: gfm
Are you sure you want to change the base?
Conversation
This change allows building the `cmark-gfm` target for both `wasm32-unknown-wasi` and `wasm32-unknown-wasip1-threads`. The other targets are not tested. The differences between two target triples: - `wasm32-unknown-wasi` - C - can import `unistd.h` - has `__wasi__` - does not have `__unix__` - **does not have `_REENTRANT`** - **does not have `_POSIX_THREADS`** - **does not support pthreads API at all** - Swift - can use `#if os(WASI)` - SwiftPM - `BuildSettingsCondition`'s `Platform` is `.wasi` - `wasm32-unknown-wasip1-threads` - C - can import `unistd.h` - has `__wasi__` - does not have `__unix__` - **has `_REENTRANT` (defined in wasi-libc)** - **has `_POSIX_THREADS` (defined in wasi-libc)** - **supports a subset of pthreads API** - Swift - can use `#if os(WASI)` - SwiftPM - `BuildSettingsCondition`'s `Platform` is `.wasi`
I feel like it would be nice to still have the ability to definitively disable the threading support, since upstream diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23eca3c5..4f741228 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR YES)
option(CMARK_FUZZ_QUADRATIC "Build quadratic fuzzing harness" OFF)
option(CMARK_LIB_FUZZER "Build libFuzzer fuzzing harness" OFF)
-option(CMARK_THREADING "Add locks around static accesses" OFF)
+option(CMARK_THREADING "Add locks around static accesses; will autodetect based on platform if not set" OFF)
+option(CMARK_NO_THREADING "Disable thread-support auto-detection" OFF)
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "Do not build in-source.\nPlease remove CMakeCache.txt and the CMakeFiles/ directory.\nThen: mkdir build ; cd build ; cmake .. ; make")
@@ -44,6 +45,9 @@ if(CMARK_THREADING)
include(FindThreads)
add_compile_definitions(CMARK_THREADING)
endif()
+if(CMARK_NO_THREADING)
+ add_compile_definitions(CMARK_NO_THREADING)
+endif()
include(GNUInstallDirs)
if(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) And then you'd guard the autodetect you added with a |
Thank you for your suggestion. That sounds great, but I feel the naming is a little confusing. Users could specify both options at the same time like Instead, what do you think about undoing the behavior of diff --git a/api_test/harness.c b/api_test/harness.c
index f561aeac..a00ae9ef 100644
--- a/api_test/harness.c
+++ b/api_test/harness.c
@@ -54,7 +54,7 @@ void INT_EQ(test_batch_runner *runner, int got, int expected, const char *msg,
}
}
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
#include <unistd.h>
static char *write_tmp(char const *header, char const *data) {
@@ -79,7 +79,7 @@ void STR_EQ(test_batch_runner *runner, const char *got, const char *expected,
va_end(ap);
if (!cond) {
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
char *got_fn = write_tmp("actual\n", got);
char *expected_fn = write_tmp("expected\n", expected);
char buf[1024];
diff --git a/src/include/mutex.h b/src/include/mutex.h
index 59427f34..d9f12554 100644
--- a/src/include/mutex.h
+++ b/src/include/mutex.h
@@ -3,9 +3,13 @@
#include <stdbool.h>
+#if defined(CMARK_THREADING) && defined(__wasi__) && !defined(_REENTRANT)
+#undef CMARK_THREADING
+#endif
+
#ifdef CMARK_THREADING
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__wasi__)
#include <unistd.h>
#endif |
I would like to hear @kateinoigakukun's opinion too, if possible. |
@kkebo I'm personally not a big fan of undefining a definition as I feel "including a header results in disappearing a definition" is a bit confusing. How about interpreting |
Thanks for the advice. It seems to be possible to express the three cases (on, off, auto) in that way.
I felt that this method seemed to be the best at the moment. new diff from gfm branchdiff --git a/CMakeLists.txt b/CMakeLists.txt
index 23eca3c5..02596d5d 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,7 +42,9 @@ include(FindAsan)
if(CMARK_THREADING)
set(THREADS_PREFER_PTHREAD_FLAG YES)
include(FindThreads)
- add_compile_definitions(CMARK_THREADING)
+ add_compile_definitions(CMARK_THREADING=1)
+else()
+ add_compile_definitions(CMARK_THREADING=0)
endif()
include(GNUInstallDirs)
diff --git a/Package.swift b/Package.swift
index f1acc5f3..618c280a 100644
--- a/Package.swift
+++ b/Package.swift
@@ -11,12 +11,9 @@ import PackageDescription
// link time.
let cSettings: [CSetting] = [
.define("CMARK_GFM_STATIC_DEFINE", .when(platforms: [.windows])),
- .define("CMARK_THREADING"),
]
#else
- let cSettings: [CSetting] = [
- .define("CMARK_THREADING"),
- ]
+ let cSettings: [CSetting] = []
#endif
let package = Package(
diff --git a/api_test/harness.c b/api_test/harness.c
index f561aeac..a00ae9ef 100644
--- a/api_test/harness.c
+++ b/api_test/harness.c
@@ -54,7 +54,7 @@ void INT_EQ(test_batch_runner *runner, int got, int expected, const char *msg,
}
}
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
#include <unistd.h>
static char *write_tmp(char const *header, char const *data) {
@@ -79,7 +79,7 @@ void STR_EQ(test_batch_runner *runner, const char *got, const char *expected,
va_end(ap);
if (!cond) {
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__wasi__)
char *got_fn = write_tmp("actual\n", got);
char *expected_fn = write_tmp("expected\n", expected);
char buf[1024];
diff --git a/src/include/mutex.h b/src/include/mutex.h
index 59427f34..25630622 100644
--- a/src/include/mutex.h
+++ b/src/include/mutex.h
@@ -3,9 +3,17 @@
#include <stdbool.h>
-#ifdef CMARK_THREADING
+#ifndef CMARK_THREADING
+#if defined(__wasi__) && !defined(_REENTRANT)
+#define CMARK_THREADING 0
+#else
+#define CMARK_THREADING 1
+#endif
+#endif
+
+#if CMARK_THREADING
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__wasi__)
#include <unistd.h>
#endif In addition to successful builds for CMake logs$ cmake -S . -B build -DCMARK_THREADING=OFF
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kebo/swift-cmark/build
$ grep CMARK_THREADING build
build/extensions/CMakeFiles/libcmark-gfm-extensions.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=0
build/CMakeCache.txt
285:CMARK_THREADING:BOOL=OFF
build/api_test/CMakeFiles/api_test.dir/flags.make
6:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=0
12:CXX_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=0
build/src/CMakeFiles/libcmark-gfm.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=0
build/src/CMakeFiles/cmark-gfm.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=0
$ cmake -S . -B build -DCMARK_THREADING=ON
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kebo/swift-cmark/build
$ grep CMARK_THREADING build
build/extensions/CMakeFiles/libcmark-gfm-extensions.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=1
build/CMakeCache.txt
285:CMARK_THREADING:BOOL=ON
build/api_test/CMakeFiles/api_test.dir/flags.make
6:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=1
12:CXX_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=1
build/src/CMakeFiles/libcmark-gfm.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=1
build/src/CMakeFiles/cmark-gfm.dir/flags.make
5:C_DEFINES = -DCMARK_GFM_STATIC_DEFINE -DCMARK_THREADING=1 |
@QuietMisdreavus If this change addresses your concerns, I would change the PR to this. |
This would mean that the library built with the C compiler could have threading enabled, but then when imported into swift would not have threading enabled. This feels like it would cause issues. Perhaps we need to consider having a |
@compnerd Thank you for your comment. It would certainly be better to use I referred to swift-cmark's previous commits and https://github.com/github/cmark-gfm. In addition, as it seemed more appropriate to place the code for when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems reasonable to me. Please get @QuietMisdreavus to sign off on this.
Description
This change allows building the
cmark-gfm
target for bothwasm32-unknown-wasi
andwasm32-unknown-wasip1-threads
. The other targets are not tested.The current problem
The differences between two target triples are as follows:
wasm32-unknown-wasi
unistd.h
__wasi__
__unix__
_REENTRANT
_POSIX_THREADS
#if os(WASI)
BuildSettingsCondition
'sPlatform
is.wasi
wasm32-unknown-wasip1-threads
unistd.h
__wasi__
__unix__
_REENTRANT
(defined in wasi-libc)_POSIX_THREADS
(defined in wasi-libc)#if os(WASI)
BuildSettingsCondition
'sPlatform
is.wasi
Therefore,
CMARK_THREADING
must not be defined when building forwasm32-unknown-wasi
, but must be defined when building forwasm32-unknown-wasip1-threads
.However, when building with CMake, it is controllable, but when building with SwiftPM,
CMARK_THREADING
is always defined.Proposed solution
-DCMARK_THREADING=OFF
(default),CMARK_THREADING
will not be defined in the C compiler.-DCMARK_THREADING=ON
,CMARK_THREADING
will be defined in the C compiler.-DCMARK_THREADING=OFF
(default),CMARK_THREADING
will be defined inconfig.h
and be0
.-DCMARK_THREADING=ON
,CMARK_THREADING
will be defined inconfig.h
and be1
..define("CMARK_THREADING")
will be added inPackage.swift
..define("CMARK_THREADING")
will not be added inPackage.swift
. (reverting aef4761)CMARK_THREADING
will automatically be defined as one of the following values insrc/include/cmark-gfm_config.h
.0
if building for targets that do not support threading (e.g.wasm32-unknown-wasi
)1
if building for the other targets includingwasm32-unknown-wasip1-threads
I reverted 6f64876 because I needed
src/config.h.in
andsrc/include/cmark-gfm_config.h
.Checks
I've tested this PR (149b31f) by the following ways on Linux.
Building with SwiftPM
swift-DEVELOPMENT-SNAPSHOT-2024-09-25-a:
swiftly install main-snapshot-2024-09-25
swiftly use main-snapshot-2024-09-25
swift sdk install https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-09-26-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-09-26-a-wasm32-unknown-wasi.artifactbundle.zip --checksum 34c53bac6f41502f26056fd14bbf4757eca2cb93fdab089dd25449bc17cbc3c8
(instructions)swift build --swift-sdk wasm32-unknown-wasi --target cmark-gfm
swift sdk install https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-09-26-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-09-26-a-wasm32-unknown-wasip1-threads.artifactbundle.zip --checksum 588749ed32af29c8fdd64c37ee61531c62574197f058c11c43848d74e6683a41
(instructions)swift build --swift-sdk wasm32-unknown-wasip1-threads --target cmark-gfm
swift build
Building with CMake and Make
-DCMARK_THREADING=ON
-DCMARK_THREADING=OFF
Building as an external dependency with SwiftPM
This CI workflow builds swift-format's executable and test executable for
wasm32-unknown-wasi
. swift-format depends on swift-cmark, and the following one is using this PR's branch. The test executable runs on a WebAssembly runtime (wasmtime). As you can see, all tests cases have passed.https://github.com/kkebo/swift-format/actions/runs/11669491583