diff --git a/.github/workflows/MainDistributionPipeline.yml b/.github/workflows/MainDistributionPipeline.yml index 9a43ae090..26418698c 100644 --- a/.github/workflows/MainDistributionPipeline.yml +++ b/.github/workflows/MainDistributionPipeline.yml @@ -14,23 +14,23 @@ concurrency: jobs: duckdb-stable-build: name: Build extension binaries - uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.4.2 + uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.4.3 with: extension_name: iceberg - duckdb_version: v1.4.2 - ci_tools_version: v1.4.2 - exclude_archs: 'windows_amd64_mingw;wasm_mvp;wasm_eh;wasm_threads' + duckdb_version: v1.4.3 + ci_tools_version: v1.4.3 + exclude_archs: 'windows_amd64_mingw' extra_toolchains: 'python3' duckdb-stable-deploy: name: Deploy extension binaries needs: duckdb-stable-build - uses: duckdb/extension-ci-tools/.github/workflows/_extension_deploy.yml@v1.4.2 + uses: duckdb/extension-ci-tools/.github/workflows/_extension_deploy.yml@v1.4.3 secrets: inherit with: extension_name: iceberg - duckdb_version: v1.4.2 - ci_tools_version: v1.4.2 - exclude_archs: 'windows_amd64_mingw;wasm_mvp;wasm_eh;wasm_threads' + duckdb_version: v1.4.3 + ci_tools_version: v1.4.3 + exclude_archs: 'windows_amd64_mingw' deploy_latest: ${{ startsWith(github.ref, 'refs/heads/v') || github.ref == 'refs/heads/main' }} deploy_versioned: ${{ startsWith(github.ref, 'refs/heads/v') || github.ref == 'refs/heads/main' }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 4105da77f..b85cf5829 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,12 @@ add_subdirectory(src/rest_catalog/objects) add_library(${EXTENSION_NAME} STATIC ${EXTENSION_SOURCES} ${ALL_OBJECT_FILES}) set(PARAMETERS "-warnings") + +if(EMSCRIPTEN) + set (DUCKDB_EXTENSION_ICEBERG_LINKED_LIBS "../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-mqtt.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-kinesis.a;../../vcpkg_installed/wasm32-emscripten/lib/liblzma.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-auth.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-s3.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-s3.a;../../vcpkg_installed/wasm32-emscripten/lib/libroaring.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-cal.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-sdkutils.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-sso.a;../../vcpkg_installed/wasm32-emscripten/lib/libs2n.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-common.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-checksums.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-sts.a;../../vcpkg_installed/wasm32-emscripten/lib/libsnappy.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-compression.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-cognito-identity.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-crt-cpp.a;../../vcpkg_installed/wasm32-emscripten/lib/libssl.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-event-stream.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-core.a;../../vcpkg_installed/wasm32-emscripten/lib/libcrypto.a;../../vcpkg_installed/wasm32-emscripten/lib/libz.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-http.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-dynamodb.a;../../vcpkg_installed/wasm32-emscripten/lib/libcurl.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-c-io.a;../../vcpkg_installed/wasm32-emscripten/lib/libaws-cpp-sdk-identity-management.a;../../vcpkg_installed/wasm32-emscripten/lib/libjansson.a;../../third_party/mbedtls/libduckdb_mbedtls.a") +endif() + + build_loadable_extension(${TARGET_NAME} ${PARAMETERS} ${EXTENSION_SOURCES} ${ALL_OBJECT_FILES}) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten") diff --git a/Makefile b/Makefile index beed9bfb9..de17e39ef 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,3 @@ data_large: data data_clean data_clean: rm -rf data/generated - -wasm_pre_build_step: - jq 'del(.overrides,.dependencies[5])' vcpkg.json | unexpand -t2 > vcpkg.json.tmp && mv vcpkg.json.tmp vcpkg.json diff --git a/duckdb b/duckdb index 68d7555f6..d1dc88f95 160000 --- a/duckdb +++ b/duckdb @@ -1 +1 @@ -Subproject commit 68d7555f68bd25c1a251ccca2e6338949c33986a +Subproject commit d1dc88f950d456d72493df452dabdcd13aa413dd diff --git a/extension-ci-tools b/extension-ci-tools index 86306f451..35caa192a 160000 --- a/extension-ci-tools +++ b/extension-ci-tools @@ -1 +1 @@ -Subproject commit 86306f45100210a75d1633521d83ebd1f640e960 +Subproject commit 35caa192a33706de4308a9ad4078042ed4a762d7 diff --git a/src/aws.cpp b/src/aws.cpp index cee94ca25..41d6993d1 100644 --- a/src/aws.cpp +++ b/src/aws.cpp @@ -132,6 +132,7 @@ static string GetPayloadHash(const char *buffer, idx_t buffer_len) { std::shared_ptr AWSInput::CreateSignedRequest(Aws::Http::HttpMethod method, const Aws::Http::URI &uri, HTTPHeaders &headers, const string &body) { +#ifndef EMSCRIPTEN auto request = Aws::Http::CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); request->SetUserAgent(user_agent); @@ -153,10 +154,14 @@ std::shared_ptr AWSInput::CreateSignedRequest(Aws::Http: } return request; +#else + return nullptr; +#endif } unique_ptr AWSInput::ExecuteRequestLegacy(ClientContext &context, Aws::Http::HttpMethod method, HTTPHeaders &headers, const string &body) { +#ifndef EMSCRIPTEN InitAWSAPI(); auto clientConfig = BuildClientConfig(); auto uri = BuildURI(); @@ -191,6 +196,9 @@ unique_ptr AWSInput::ExecuteRequestLegacy(ClientContext &context, throw HTTPException(*result, result->reason); } return result; +#else + throw NotImplementedException("ExecuteRequestLegacy is not implemented in duckdb-wasm"); +#endif } unique_ptr AWSInput::ExecuteRequest(ClientContext &context, Aws::Http::HttpMethod method, diff --git a/src/include/rest_catalog/objects/assert_ref_snapshot_id.hpp b/src/include/rest_catalog/objects/assert_ref_snapshot_id.hpp index e2258bb98..418c6fd02 100644 --- a/src/include/rest_catalog/objects/assert_ref_snapshot_id.hpp +++ b/src/include/rest_catalog/objects/assert_ref_snapshot_id.hpp @@ -30,6 +30,7 @@ class AssertRefSnapshotId { TableRequirementType type; string ref; int64_t snapshot_id; + bool has_snapshot_id = false; }; } // namespace rest_api_objects diff --git a/src/metadata/iceberg_table_metadata.cpp b/src/metadata/iceberg_table_metadata.cpp index b93ede5b9..d68d8fd6a 100644 --- a/src/metadata/iceberg_table_metadata.cpp +++ b/src/metadata/iceberg_table_metadata.cpp @@ -334,11 +334,11 @@ string IcebergTableMetadata::GetDataPath() const { string IcebergTableMetadata::GetMetadataPath() const { // If write.metadata.path property is set, use it; otherwise use default location + "/metadata" auto metadata_path = table_properties.find("write.metadata.path"); - // If write.data.path property is set, use it; otherwise use default location + "/data" + // If write.data.path property is set, use it; otherwise use default location + "/metadata" if (metadata_path != table_properties.end()) { return metadata_path->second; } - return location + "/data"; + return location + "/metadata"; } string IcebergTableMetadata::GetTableProperty(string property_string) const { diff --git a/src/rest_catalog/objects/assert_ref_snapshot_id.cpp b/src/rest_catalog/objects/assert_ref_snapshot_id.cpp index 9a44c60d9..e5ab372cf 100644 --- a/src/rest_catalog/objects/assert_ref_snapshot_id.cpp +++ b/src/rest_catalog/objects/assert_ref_snapshot_id.cpp @@ -50,10 +50,14 @@ string AssertRefSnapshotId::TryFromJSON(yyjson_val *obj) { if (!snapshot_id_val) { return "AssertRefSnapshotId required property 'snapshot-id' is missing"; } else { - if (yyjson_is_sint(snapshot_id_val)) { + if (yyjson_is_null(snapshot_id_val)) { + has_snapshot_id = false; + } else if (yyjson_is_sint(snapshot_id_val)) { snapshot_id = yyjson_get_sint(snapshot_id_val); + has_snapshot_id = true; } else if (yyjson_is_uint(snapshot_id_val)) { snapshot_id = yyjson_get_uint(snapshot_id_val); + has_snapshot_id = true; } else { return StringUtil::Format( "AssertRefSnapshotId property 'snapshot_id' is not of type 'integer', found '%s' instead", diff --git a/src/storage/irc_catalog.cpp b/src/storage/irc_catalog.cpp index f69f9895e..f2f19d061 100644 --- a/src/storage/irc_catalog.cpp +++ b/src/storage/irc_catalog.cpp @@ -240,7 +240,7 @@ void IRCatalog::AddDefaultSupportedEndpoints() { // Rename a table from one identifier to another. supported_urls.insert("POST /v1/{prefix}/tables/rename"); // commit updates to multiple tables in an atomic transaction - supported_urls.insert("POST /v1/{prefix}/transactions/commit)"); + supported_urls.insert("POST /v1/{prefix}/transactions/commit"); } void IRCatalog::AddS3TablesEndpoints() { @@ -268,7 +268,7 @@ void IRCatalog::AddS3TablesEndpoints() { // Rename a table from one identifier to another. supported_urls.insert("POST /v1/{prefix}/tables/rename"); // commit updates to multiple tables in an atomic transaction - supported_urls.insert("POST /v1/{prefix}/transactions/commit)"); + supported_urls.insert("POST /v1/{prefix}/transactions/commit"); } void IRCatalog::GetConfig(ClientContext &context, IcebergEndpointType &endpoint_type) { diff --git a/src/storage/irc_transaction.cpp b/src/storage/irc_transaction.cpp index 288539048..7f753253c 100644 --- a/src/storage/irc_transaction.cpp +++ b/src/storage/irc_transaction.cpp @@ -47,7 +47,11 @@ void CommitTableToJSON(yyjson_mut_doc *doc, yyjson_mut_val *root_object, auto requirement_json = yyjson_mut_arr_add_obj(doc, requirements_array); yyjson_mut_obj_add_strcpy(doc, requirement_json, "type", assert_ref_snapshot_id.type.value.c_str()); yyjson_mut_obj_add_strcpy(doc, requirement_json, "ref", assert_ref_snapshot_id.ref.c_str()); - yyjson_mut_obj_add_uint(doc, requirement_json, "snapshot-id", assert_ref_snapshot_id.snapshot_id); + if (assert_ref_snapshot_id.has_snapshot_id) { + yyjson_mut_obj_add_uint(doc, requirement_json, "snapshot-id", assert_ref_snapshot_id.snapshot_id); + } else { + yyjson_mut_obj_add_null(doc, requirement_json, "snapshot-id"); + } } else if (requirement.has_assert_create) { auto &assert_create = requirement.assert_create; auto requirement_json = yyjson_mut_arr_add_obj(doc, requirements_array); @@ -230,6 +234,18 @@ static rest_api_objects::TableRequirement CreateAssertRefSnapshotIdRequirement(I auto &res = req.assert_ref_snapshot_id; res.ref = "main"; res.snapshot_id = old_snapshot.snapshot_id; + res.has_snapshot_id = true; + res.type.value = "assert-ref-snapshot-id"; + return req; +} + +static rest_api_objects::TableRequirement CreateAssertNoSnapshotRequirement() { + rest_api_objects::TableRequirement req; + req.has_assert_ref_snapshot_id = true; + + auto &res = req.assert_ref_snapshot_id; + res.ref = "main"; + res.has_snapshot_id = false; res.type.value = "assert-ref-snapshot-id"; return req; } @@ -307,6 +323,10 @@ TableTransactionInfo IRCTransaction::GetTransactionRequest(ClientContext &contex //! If any changes were made to the state of the table, we should assert that our parent snapshot has //! not changed. We don't want to change the table location if someone has added a snapshot commit_state.table_change.requirements.push_back(CreateAssertRefSnapshotIdRequirement(*current_snapshot)); + } else if (!info.has_assert_create) { + //! If the table had no snapshots and isn't created by this transaction, we should assert that no snapshot + //! has been added in the meantime + commit_state.table_change.requirements.push_back(CreateAssertNoSnapshotRequirement()); } transaction.table_changes.push_back(std::move(table_change)); diff --git a/test/sql/local/irc/insert/test_concurrent_insert_new_table.test b/test/sql/local/irc/insert/test_concurrent_insert_new_table.test new file mode 100644 index 000000000..9076cf1aa --- /dev/null +++ b/test/sql/local/irc/insert/test_concurrent_insert_new_table.test @@ -0,0 +1,73 @@ +# name: test/sql/local/irc/insert/test_concurrent_insert_new_table.test +# description: Test concurrent inserts to a newly created table with no snapshots +# group: [insert] + +require-env ICEBERG_SERVER_AVAILABLE + +require avro + +require parquet + +require iceberg + +require httpfs + +# Do not ignore 'HTTP' error messages! +set ignore_error_messages + +statement ok +CREATE SECRET ( + TYPE S3, + KEY_ID 'admin', + SECRET 'password', + ENDPOINT '127.0.0.1:9000', + URL_STYLE 'path', + USE_SSL 0 +); + +statement ok +ATTACH '' AS my_datalake ( + TYPE ICEBERG, + CLIENT_ID 'admin', + CLIENT_SECRET 'password', + ENDPOINT 'http://127.0.0.1:8181' +); + +statement ok +DROP TABLE IF EXISTS my_datalake.default.concurrent_new_table_test; + +statement ok +CREATE TABLE my_datalake.default.concurrent_new_table_test (id INTEGER, name VARCHAR); + +# con1 starts a transaction and inserts +statement ok con1 +begin + +statement ok con1 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (1, 'con1'); + +# con2 starts a transaction and inserts +statement ok con2 +begin + +statement ok con2 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (2, 'con2'); + +# con2 commits first +statement ok con2 +commit + +# con1 should fail because con2 already added a snapshot +statement error con1 +commit +---- +:.*Requirement failed: branch main was created concurrently.* + +# only con2's data is in the table +query II +SELECT * FROM my_datalake.default.concurrent_new_table_test ORDER BY id; +---- +2 con2 + +statement ok +DROP TABLE my_datalake.default.concurrent_new_table_test; diff --git a/test/sql/local/irc/reads/test_read_nulls.test b/test/sql/local/irc/reads/test_read_nulls.test index 1078ec81f..7ab572103 100644 --- a/test/sql/local/irc/reads/test_read_nulls.test +++ b/test/sql/local/irc/reads/test_read_nulls.test @@ -74,7 +74,7 @@ select * from my_datalake.default.test_null_filtering where a is distinct from n 10 no nulls query II -select * from my_datalake.default.test_null_filtering where a is not distinct from null order by a NULLS FIRST; +select * from my_datalake.default.test_null_filtering where a is not distinct from null order by all NULLS FIRST; ---- NULL NULL NULL duck diff --git a/test/sql/local/irc/test_polaris_concurrent_insert.test b/test/sql/local/irc/test_polaris_concurrent_insert.test new file mode 100644 index 000000000..9d2a963c4 --- /dev/null +++ b/test/sql/local/irc/test_polaris_concurrent_insert.test @@ -0,0 +1,126 @@ +# name: test/sql/local/irc/test_polaris_concurrent_insert.test +# description: Test concurrent inserts to a newly created table with no snapshots +# group: [irc] + +require-env POLARIS_CLIENT_ID + +require-env POLARIS_CLIENT_SECRET + +require-env POLARIS_SERVER_AVAILABLE + +require avro + +require parquet + +require httpfs + +require iceberg + +require aws + +# Do not ignore 'HTTP' error messages! +set ignore_error_messages + +statement ok +create secret polaris_secret ( + TYPE ICEBERG, + CLIENT_ID '${POLARIS_CLIENT_ID}', + CLIENT_SECRET '${POLARIS_CLIENT_SECRET}', + ENDPOINT 'http://0.0.0.0:8181/api/catalog' +); + +statement ok +attach 'quickstart_catalog' as my_datalake ( + type ICEBERG, + ENDPOINT 'http://0.0.0.0:8181/api/catalog' +); + +statement ok +DROP TABLE IF EXISTS my_datalake.default.concurrent_new_table_test; + +statement ok +CREATE TABLE my_datalake.default.concurrent_new_table_test (id INTEGER, name VARCHAR); + +# con1 starts a transaction and inserts +statement ok con1 +begin + +statement ok con1 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (1, 'con1'); + +# con2 starts a transaction and inserts +statement ok con2 +begin + +statement ok con2 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (2, 'con2'); + +# con2 commits first +statement ok con2 +commit + +# con1 should fail because con2 already added a snapshot +statement error con1 +commit +---- +:.*Requirement failed: branch main was created concurrently.* + +# only con2's data is in the table +query II +SELECT * FROM my_datalake.default.concurrent_new_table_test ORDER BY id; +---- +2 con2 + +statement ok +DROP TABLE my_datalake.default.concurrent_new_table_test; + + +# attach with support stage create as false +# polaris is currently file backed in tests, so folders are not automatically +# created when creating a table with stage_create=true +statement ok +attach or replace 'quickstart_catalog' as my_datalake ( + type ICEBERG, + ENDPOINT 'http://0.0.0.0:8181/api/catalog', + SUPPORT_NESTED_NAMESPACES true, + support_stage_create false +); + +statement ok +DROP TABLE IF EXISTS my_datalake.default.concurrent_new_table_test; + +statement ok +CREATE TABLE my_datalake.default.concurrent_new_table_test (id INTEGER, name VARCHAR); + +# con1 starts a transaction and inserts +statement ok con1 +begin + +statement ok con1 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (1, 'con1'); + +# con2 starts a transaction and inserts +statement ok con2 +begin + +statement ok con2 +INSERT INTO my_datalake.default.concurrent_new_table_test VALUES (2, 'con2'); + +# con2 commits first +statement ok con2 +commit + +# con1 should fail because con2 already added a snapshot +statement error con1 +commit +---- +:.*Requirement failed: branch main was created concurrently.* + +# only con2's data is in the table +query II +SELECT * FROM my_datalake.default.concurrent_new_table_test ORDER BY id; +---- +2 con2 + +statement ok +DROP TABLE my_datalake.default.concurrent_new_table_test; diff --git a/test/sql/local/partitioning/foldable_expression_filter.test b/test/sql/local/partitioning/foldable_expression_filter.test index 2f7c4eef7..06fc8bcbd 100644 --- a/test/sql/local/partitioning/foldable_expression_filter.test +++ b/test/sql/local/partitioning/foldable_expression_filter.test @@ -15,6 +15,10 @@ set enable_logging=true statement ok set logging_level='debug' +#FIXME: logging types are not registered to extensions +statement ok +LOAD iceberg; + statement ok CALL enable_logging('Iceberg'); diff --git a/test/sql/local/partitioning/in_filter.test b/test/sql/local/partitioning/in_filter.test index 8b492a267..9b4be1fb2 100644 --- a/test/sql/local/partitioning/in_filter.test +++ b/test/sql/local/partitioning/in_filter.test @@ -15,6 +15,10 @@ set enable_logging=true statement ok set logging_level='debug' +#FIXME: logging types are not registered to extensions +statement ok +LOAD iceberg; + statement ok CALL enable_logging('Iceberg'); diff --git a/vcpkg.json b/vcpkg.json index 2cc4714cb..bb3c821fe 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -15,6 +15,9 @@ } ], "vcpkg-configuration": { + "overlay-ports": [ + "./vcpkg_ports" + ], "registries": [ { "kind": "git", diff --git a/vcpkg_ports/aws-c-io/no_op_implementation.patch b/vcpkg_ports/aws-c-io/no_op_implementation.patch new file mode 100644 index 000000000..0dfacca01 --- /dev/null +++ b/vcpkg_ports/aws-c-io/no_op_implementation.patch @@ -0,0 +1,137 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 671fb2c..048fb63 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -176,10 +176,12 @@ aws_add_sanitizers(${PROJECT_NAME}) + + # We are not ABI stable yet + set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0) +- ++if (NOT EMSCRIPTEN) + if (NOT EVENT_LOOP_DEFINES) + message(FATAL_ERROR "Event Loop is not setup on the platform.") + endif() ++endif() ++ + foreach(EVENT_LOOP_DEFINE IN LISTS EVENT_LOOP_DEFINES) + target_compile_definitions(${PROJECT_NAME} PUBLIC "-DAWS_ENABLE_${EVENT_LOOP_DEFINE}") + endforeach() +diff --git a/source/event_loop.c b/source/event_loop.c +index 8d9321d..98f485a 100644 +--- a/source/event_loop.c ++++ b/source/event_loop.c +@@ -21,6 +21,17 @@ static enum aws_event_loop_type s_default_event_loop_type_override = AWS_EVENT_L + static enum aws_event_loop_type s_default_event_loop_type_override = AWS_EVENT_LOOP_PLATFORM_DEFAULT; + #endif + ++#ifdef EMSCRIPTEN ++int aws_default_dns_resolve( ++ struct aws_allocator *allocator, ++ const struct aws_string *host_name, ++ struct aws_array_list *output_addresses, ++ void *user_data) { ++ printf("aws_default_dns_resolve\n"); ++ return 1; ++} ++#endif ++ + struct aws_event_loop *aws_event_loop_new_default(struct aws_allocator *alloc, aws_io_clock_fn *clock) { + struct aws_event_loop_options options = { + .thread_options = NULL, +@@ -75,6 +86,9 @@ struct aws_event_loop *aws_event_loop_new_with_epoll( + * If `aws_event_loop_override_default_type` has been called, return the override default type. + */ + static enum aws_event_loop_type aws_event_loop_get_default_type(void) { ++#ifdef EMSCRIPTEN ++ return s_default_event_loop_type_override; ++#else + if (s_default_event_loop_type_override != AWS_EVENT_LOOP_PLATFORM_DEFAULT) { + return s_default_event_loop_type_override; + } +@@ -94,6 +108,7 @@ static enum aws_event_loop_type aws_event_loop_get_default_type(void) { + # error \ + "Default event loop type required. Failed to get default event loop type. The library is not built correctly on the platform. " + #endif ++#endif + } + + static int aws_event_loop_type_validate_platform(enum aws_event_loop_type type); +diff --git a/source/io.c b/source/io.c +index 380ece1..60418b5 100644 +--- a/source/io.c ++++ b/source/io.c +@@ -351,8 +351,13 @@ static struct aws_log_subject_info_list s_io_log_subject_list = { + + static bool s_io_library_initialized = false; + ++#ifdef EMSCRIPTEN ++void aws_tls_init_static_state(struct aws_allocator *alloc) {} ++void aws_tls_clean_up_static_state(void) {} ++#else + void aws_tls_init_static_state(struct aws_allocator *alloc); + void aws_tls_clean_up_static_state(void); ++#endif + + void aws_io_library_init(struct aws_allocator *allocator) { + if (!s_io_library_initialized) { +diff --git a/source/posix/socket.c b/source/posix/socket.c +index 266ad2d..d0830d4 100644 +--- a/source/posix/socket.c ++++ b/source/posix/socket.c +@@ -330,6 +330,9 @@ static void s_socket_clean_up(struct aws_socket *socket) { + + /* Update socket->local_endpoint based on the results of getsockname() */ + static int s_update_local_endpoint(struct aws_socket *socket) { ++#ifdef EMSCRIPTEN ++ return 0; ++#else + struct aws_socket_endpoint tmp_endpoint; + AWS_ZERO_STRUCT(tmp_endpoint); + +@@ -411,6 +414,7 @@ static int s_update_local_endpoint(struct aws_socket *socket) { + + socket->local_endpoint = tmp_endpoint; + return AWS_OP_SUCCESS; ++#endif + } + + static void s_on_connection_error(struct aws_socket *socket, int error); +@@ -991,7 +995,9 @@ static void s_socket_accept_event( + struct aws_io_handle *handle, + int events, + void *user_data) { +- ++#ifdef EMSCRIPTEN ++ return; ++#else + (void)event_loop; + + struct aws_socket *socket = user_data; +@@ -1115,6 +1121,7 @@ static void s_socket_accept_event( + "waiting on event-loop notification", + (void *)socket, + socket->io_handle.data.fd); ++#endif + } + + static int s_socket_start_accept( +diff --git a/source/tls_channel_handler.c b/source/tls_channel_handler.c +index 5c64268..2b71242 100644 +--- a/source/tls_channel_handler.c ++++ b/source/tls_channel_handler.c +@@ -17,6 +17,15 @@ + + #include + ++#ifdef EMSCRIPTEN ++struct aws_tls_ctx *aws_tls_client_ctx_new( ++ struct aws_allocator *alloc, ++ const struct aws_tls_ctx_options *options) { ++ printf("aws_tls_client_ctx_new\n"); ++ return 0; ++} ++#endif ++ + void aws_tls_ctx_options_init_default_client(struct aws_tls_ctx_options *options, struct aws_allocator *allocator) { + AWS_ZERO_STRUCT(*options); + options->allocator = allocator; diff --git a/vcpkg_ports/aws-c-io/portfile.cmake b/vcpkg_ports/aws-c-io/portfile.cmake new file mode 100644 index 000000000..48df23583 --- /dev/null +++ b/vcpkg_ports/aws-c-io/portfile.cmake @@ -0,0 +1,33 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO awslabs/aws-c-io + REF "v${VERSION}" + SHA512 853d7603b5fa3a9ff60f9ed742832c68348a92dce276e8e9838770a3cb85f8ecebd767d07359d22ad54bf2269991123fd1e4ed39a106ec132686a34d0239db84 + HEAD_REF master + PATCHES no_op_implementation.patch +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + "-DCMAKE_MODULE_PATH=${CURRENT_INSTALLED_DIR}/share/aws-c-common" # use extra cmake files + -DBUILD_TESTING=FALSE +) + +vcpkg_cmake_install() + +string(REPLACE "dynamic" "shared" subdir "${VCPKG_LIBRARY_LINKAGE}") +vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/${PORT}/${subdir}" DO_NOT_DELETE_PARENT_CONFIG_PATH) +vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/${PORT}") +vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/${PORT}/${PORT}-config.cmake" [[/${type}/]] "/") + +file(REMOVE_RECURSE + "${CURRENT_PACKAGES_DIR}/debug/include" + "${CURRENT_PACKAGES_DIR}/debug/lib/${PORT}" + "${CURRENT_PACKAGES_DIR}/debug/share" + "${CURRENT_PACKAGES_DIR}/lib/${PORT}" +) + +vcpkg_copy_pdbs() + +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE") diff --git a/vcpkg_ports/aws-c-io/vcpkg.json b/vcpkg_ports/aws-c-io/vcpkg.json new file mode 100644 index 000000000..2c8cb87a1 --- /dev/null +++ b/vcpkg_ports/aws-c-io/vcpkg.json @@ -0,0 +1,23 @@ +{ + "name": "aws-c-io", + "version": "0.17.0", + "description": "Handles all IO and TLS work for application protocols.", + "homepage": "https://github.com/awslabs/aws-c-io", + "license": "Apache-2.0", + "dependencies": [ + "aws-c-cal", + "aws-c-common", + { + "name": "s2n", + "platform": "!uwp & !windows" + }, + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +}