wasmer-napi 0.702.0

NAPI library for Wasmer WebAssembly runtime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
set(NAPI_V8_PREBUILT_VERSION "11.9.2")
set(NAPI_V8_PREBUILT_BASE_URL
  "https://github.com/wasmerio/v8-custom-builds/releases/download/${NAPI_V8_PREBUILT_VERSION}")

function(_napi_v8_warn_deprecated old_name new_name)
  message(WARNING
    "${old_name} is deprecated; use ${new_name} instead.")
endfunction()

function(_napi_v8_read_value out_var canonical_name)
  set(_resolved "")

  if(DEFINED ${canonical_name} AND NOT "${${canonical_name}}" STREQUAL "")
    set(_resolved "${${canonical_name}}")
    set(${out_var} "${_resolved}" PARENT_SCOPE)
    return()
  endif()

  if(DEFINED ENV{${canonical_name}} AND NOT "$ENV{${canonical_name}}" STREQUAL "")
    set(_resolved "$ENV{${canonical_name}}")
    set(${out_var} "${_resolved}" PARENT_SCOPE)
    return()
  endif()

  foreach(_old_name IN LISTS ARGN)
    if(DEFINED ${_old_name} AND NOT "${${_old_name}}" STREQUAL "")
      _napi_v8_warn_deprecated("${_old_name}" "${canonical_name}")
      set(_resolved "${${_old_name}}")
      set(${out_var} "${_resolved}" PARENT_SCOPE)
      return()
    endif()
    if(DEFINED ENV{${_old_name}} AND NOT "$ENV{${_old_name}}" STREQUAL "")
      _napi_v8_warn_deprecated("${_old_name}" "${canonical_name}")
      set(_resolved "$ENV{${_old_name}}")
      set(${out_var} "${_resolved}" PARENT_SCOPE)
      return()
    endif()
  endforeach()

  set(${out_var} "" PARENT_SCOPE)
endfunction()

function(_napi_v8_local_strategy out_ok out_include out_library out_extra out_defines out_reason
    include_override library_override extra_override defines_override)
  set(_include "${include_override}")
  set(_library "${library_override}")
  set(_extra "${extra_override}")
  set(_defines "${defines_override}")
  set(_reason "")

  if(APPLE)
    foreach(_hb_prefix "/opt/homebrew/Cellar/v8/14.5.201.9" "/opt/homebrew/opt/v8")
      if(NOT _include AND EXISTS "${_hb_prefix}/include")
        set(_include "${_hb_prefix}/include")
      endif()
      if(NOT _library AND EXISTS "${_hb_prefix}/lib/libv8.dylib")
        set(_library "${_hb_prefix}/lib/libv8.dylib")
      endif()
      if(_library STREQUAL "${_hb_prefix}/lib/libv8.dylib")
        if(_extra STREQUAL "")
          set(_extra "${_hb_prefix}/lib/libv8_libplatform.dylib;${_hb_prefix}/lib/libv8_libbase.dylib")
        endif()
        if(_defines STREQUAL "")
          set(_defines "")
        endif()
        break()
      endif()
    endforeach()
  endif()

  if(_include STREQUAL "")
    set(_reason "V8 include directory is not set. Set NAPI_V8_INCLUDE_DIR.")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason} "${_reason}" PARENT_SCOPE)
    return()
  endif()
  if(NOT EXISTS "${_include}")
    set(_reason "V8 include directory does not exist: ${_include}")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason} "${_reason}" PARENT_SCOPE)
    return()
  endif()

  if(_library STREQUAL "")
    set(_reason "V8 library path is not set. Set NAPI_V8_LIBRARY.")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason} "${_reason}" PARENT_SCOPE)
    return()
  endif()
  if(NOT EXISTS "${_library}")
    set(_reason "V8 library does not exist: ${_library}")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason} "${_reason}" PARENT_SCOPE)
    return()
  endif()

  set(${out_ok} TRUE PARENT_SCOPE)
  set(${out_include} "${_include}" PARENT_SCOPE)
  set(${out_library} "${_library}" PARENT_SCOPE)
  set(${out_extra} "${_extra}" PARENT_SCOPE)
  set(${out_defines} "${_defines}" PARENT_SCOPE)
  set(${out_reason} "" PARENT_SCOPE)
endfunction()

function(_napi_v8_prebuilt_strategy out_ok out_include out_library out_extra out_defines out_reason
    extra_override defines_override)
  set(_platform "")
  set(_asset "")
  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
     (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64"))
    set(_platform "darwin-arm64")
    set(_asset "v8-darwin-arm64.tar.xz")
  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
         (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64"))
    set(_platform "linux-amd64")
    set(_asset "v8-linux-amd64.tar.xz")
  else()
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason}
      "Prebuilt V8 is not available for ${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}"
      PARENT_SCOPE)
    return()
  endif()

  set(_cache_dir "${CMAKE_BINARY_DIR}/_v8_cache/${NAPI_V8_PREBUILT_VERSION}/${_platform}")
  set(_archive_path "${_cache_dir}/${_asset}")
  set(_include "${_cache_dir}/include")
  set(_library "${_cache_dir}/lib/libv8.a")

  file(MAKE_DIRECTORY "${_cache_dir}")

  if(EXISTS "${_archive_path}")
    file(SIZE "${_archive_path}" _archive_size)
    if(_archive_size EQUAL 0)
      file(REMOVE "${_archive_path}")
    endif()
  endif()

  if(NOT EXISTS "${_archive_path}")
    set(_url "${NAPI_V8_PREBUILT_BASE_URL}/${_asset}")
    message(STATUS "Downloading prebuilt V8 ${NAPI_V8_PREBUILT_VERSION} from ${_url}")
    file(DOWNLOAD
      "${_url}"
      "${_archive_path}"
      STATUS _download_status
      SHOW_PROGRESS
      TLS_VERIFY ON
    )
    list(GET _download_status 0 _download_code)
    list(GET _download_status 1 _download_message)
    if(NOT _download_code EQUAL 0)
      set(${out_ok} FALSE PARENT_SCOPE)
      set(${out_reason}
        "Failed to download ${_url}: ${_download_message}"
        PARENT_SCOPE)
      return()
    endif()
  endif()

  if(NOT EXISTS "${_include}" OR NOT EXISTS "${_library}")
    execute_process(
      COMMAND "${CMAKE_COMMAND}" -E tar xJf "${_archive_path}"
      WORKING_DIRECTORY "${_cache_dir}"
      RESULT_VARIABLE _extract_result
      ERROR_VARIABLE _extract_error
    )
    if(NOT _extract_result EQUAL 0)
      set(${out_ok} FALSE PARENT_SCOPE)
      set(${out_reason}
        "Failed to extract ${_archive_path}: ${_extract_error}"
        PARENT_SCOPE)
      return()
    endif()
  endif()

  if(NOT EXISTS "${_include}" OR NOT EXISTS "${_library}")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason}
      "Prebuilt V8 archive did not produce expected layout under ${_cache_dir}"
      PARENT_SCOPE)
    return()
  endif()

  if(defines_override STREQUAL "")
    set(_defines "V8_COMPRESS_POINTERS")
  else()
    set(_defines "${defines_override}")
  endif()

  if(extra_override STREQUAL "" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(_extra "/System/Library/Frameworks/CoreFoundation.framework")
  else()
    set(_extra "${extra_override}")
  endif()

  set(${out_ok} TRUE PARENT_SCOPE)
  set(${out_include} "${_include}" PARENT_SCOPE)
  set(${out_library} "${_library}" PARENT_SCOPE)
  set(${out_extra} "${_extra}" PARENT_SCOPE)
  set(${out_defines} "${_defines}" PARENT_SCOPE)
  set(${out_reason} "" PARENT_SCOPE)
endfunction()

function(_napi_v8_source_strategy out_ok out_include out_library out_extra out_defines out_reason
    extra_override defines_override)
  set(_v8_source_root "${PROJECT_ROOT}/deps/v8")
  if(NOT EXISTS "${_v8_source_root}/BUILD.gn")
    set(${out_ok} FALSE PARENT_SCOPE)
    set(${out_reason} "Could not find V8 source tree at ${_v8_source_root}" PARENT_SCOPE)
    return()
  endif()

  find_program(_python3 python3)
  find_program(_gn gn)
  find_program(_autoninja autoninja)
  find_program(_ninja ninja)
  if(NOT _python3)
    message(FATAL_ERROR "NAPI_V8_BUILD_METHOD=source requires python3 in PATH.")
  endif()
  if(NOT _gn)
    message(FATAL_ERROR "NAPI_V8_BUILD_METHOD=source requires gn in PATH.")
  endif()
  if(NOT _autoninja AND NOT _ninja)
    message(FATAL_ERROR "NAPI_V8_BUILD_METHOD=source requires ninja or autoninja in PATH.")
  endif()

  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(_target_os "mac")
  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    set(_target_os "linux")
  else()
    message(FATAL_ERROR "NAPI_V8_BUILD_METHOD=source is unsupported for ${CMAKE_SYSTEM_NAME}.")
  endif()

  if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
    set(_target_cpu "arm64")
  elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
    set(_target_cpu "x64")
  else()
    message(FATAL_ERROR
      "NAPI_V8_BUILD_METHOD=source unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
  endif()

  set(_platform "${_target_os}-${_target_cpu}")
  set(_build_dir "${CMAKE_BINARY_DIR}/_v8_source_build/${_platform}")
  file(MAKE_DIRECTORY "${_build_dir}")

  set(_gn_args
    "is_debug=false "
    "is_component_build=false "
    "v8_monolithic=true "
    "v8_use_external_startup_data=false "
    "v8_enable_i18n_support=true "
    "icu_use_data_file=false "
    "v8_enable_pointer_compression=true "
    "v8_enable_sandbox=false "
    "target_os=\"${_target_os}\" "
    "target_cpu=\"${_target_cpu}\" "
    "treat_warnings_as_errors=false")

  message(STATUS "Generating V8 build files in ${_build_dir}")
  execute_process(
    COMMAND "${_gn}" gen "${_build_dir}" "--args=${_gn_args}"
    WORKING_DIRECTORY "${_v8_source_root}"
    RESULT_VARIABLE _gn_result
    ERROR_VARIABLE _gn_error
  )
  if(NOT _gn_result EQUAL 0)
    message(FATAL_ERROR "gn gen failed: ${_gn_error}")
  endif()

  if(_autoninja)
    set(_ninja_cmd "${_autoninja}")
  else()
    set(_ninja_cmd "${_ninja}")
  endif()
  message(STATUS "Building V8 monolith in ${_build_dir}")
  execute_process(
    COMMAND "${_ninja_cmd}" -C "${_build_dir}" v8_monolith
    WORKING_DIRECTORY "${_v8_source_root}"
    RESULT_VARIABLE _ninja_result
    ERROR_VARIABLE _ninja_error
  )
  if(NOT _ninja_result EQUAL 0)
    message(FATAL_ERROR "V8 source build failed: ${_ninja_error}")
  endif()

  set(_library_candidates
    "${_build_dir}/obj/libv8_monolith.a"
    "${_build_dir}/obj/libv8_monolith/libv8_monolith.a")
  set(_library "")
  foreach(_candidate IN LISTS _library_candidates)
    if(EXISTS "${_candidate}")
      set(_library "${_candidate}")
      break()
    endif()
  endforeach()
  if(_library STREQUAL "")
    message(FATAL_ERROR
      "V8 source build succeeded but libv8_monolith.a was not found in ${_build_dir}/obj.")
  endif()

  set(_include "${_v8_source_root}/include")
  if(NOT EXISTS "${_include}")
    message(FATAL_ERROR "V8 include directory missing after source build: ${_include}")
  endif()

  if(defines_override STREQUAL "")
    set(_defines "V8_COMPRESS_POINTERS")
  else()
    set(_defines "${defines_override}")
  endif()

  if(extra_override STREQUAL "" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(_extra "/System/Library/Frameworks/CoreFoundation.framework")
  else()
    set(_extra "${extra_override}")
  endif()

  set(${out_ok} TRUE PARENT_SCOPE)
  set(${out_include} "${_include}" PARENT_SCOPE)
  set(${out_library} "${_library}" PARENT_SCOPE)
  set(${out_extra} "${_extra}" PARENT_SCOPE)
  set(${out_defines} "${_defines}" PARENT_SCOPE)
  set(${out_reason} "" PARENT_SCOPE)
endfunction()

function(napi_v8_resolve_configuration)
  set(_requested_method "prebuilt")
  if(DEFINED NAPI_V8_BUILD_METHOD AND NOT "${NAPI_V8_BUILD_METHOD}" STREQUAL "")
    set(_requested_method "${NAPI_V8_BUILD_METHOD}")
  elseif(DEFINED ENV{NAPI_V8_BUILD_METHOD} AND NOT "$ENV{NAPI_V8_BUILD_METHOD}" STREQUAL "")
    set(_requested_method "$ENV{NAPI_V8_BUILD_METHOD}")
  endif()
  string(TOLOWER "${_requested_method}" _requested_method)

  if(DEFINED ENV{NAPI_V8_FORCE_LOCAL_BUILD} AND
     NOT "$ENV{NAPI_V8_FORCE_LOCAL_BUILD}" STREQUAL "" AND
     NOT "$ENV{NAPI_V8_FORCE_LOCAL_BUILD}" STREQUAL "0")
    set(_requested_method "local")
  endif()

  if(NOT _requested_method MATCHES "^(prebuilt|source|local)$")
    message(FATAL_ERROR
      "Invalid NAPI_V8_BUILD_METHOD='${_requested_method}'. "
      "Valid values: prebuilt, source, local.")
  endif()

  _napi_v8_read_value(_include_override "NAPI_V8_INCLUDE_DIR" "NAPI_V8_V8_INCLUDE_DIR")
  _napi_v8_read_value(_library_override "NAPI_V8_LIBRARY" "NAPI_V8_V8_LIBRARY" "NAPI_V8_V8_MONOLITH_LIB")
  _napi_v8_read_value(_extra_override "NAPI_V8_EXTRA_LIBS" "NAPI_V8_V8_EXTRA_LIBS")
  _napi_v8_read_value(_defines_override "NAPI_V8_DEFINES" "NAPI_V8_V8_DEFINES")

  set(_resolved_ok FALSE)
  set(_resolved_include "")
  set(_resolved_library "")
  set(_resolved_extra "")
  set(_resolved_defines "")
  set(_resolved_reason "")
  set(_effective_method "${_requested_method}")

  if(NOT "${_include_override}" STREQUAL "" OR NOT "${_library_override}" STREQUAL "")
    _napi_v8_local_strategy(
      _resolved_ok _resolved_include _resolved_library _resolved_extra _resolved_defines _resolved_reason
      "${_include_override}" "${_library_override}" "${_extra_override}" "${_defines_override}")
    set(_effective_method "local")
    if(NOT _resolved_ok)
      message(FATAL_ERROR "${_resolved_reason}")
    endif()
  elseif(_requested_method STREQUAL "prebuilt")
    _napi_v8_prebuilt_strategy(
      _resolved_ok _resolved_include _resolved_library _resolved_extra _resolved_defines _resolved_reason
      "${_extra_override}" "${_defines_override}")
    if(NOT _resolved_ok)
      message(WARNING
        "Prebuilt V8 unavailable: ${_resolved_reason}. Falling back to local mode.")
      _napi_v8_local_strategy(
        _resolved_ok _resolved_include _resolved_library _resolved_extra _resolved_defines _resolved_reason
        "${_include_override}" "${_library_override}" "${_extra_override}" "${_defines_override}")
      set(_effective_method "local")
      if(NOT _resolved_ok)
        message(FATAL_ERROR "${_resolved_reason}")
      endif()
    endif()
  elseif(_requested_method STREQUAL "source")
    _napi_v8_source_strategy(
      _resolved_ok _resolved_include _resolved_library _resolved_extra _resolved_defines _resolved_reason
      "${_extra_override}" "${_defines_override}")
  elseif(_requested_method STREQUAL "local")
    _napi_v8_local_strategy(
      _resolved_ok _resolved_include _resolved_library _resolved_extra _resolved_defines _resolved_reason
      "${_include_override}" "${_library_override}" "${_extra_override}" "${_defines_override}")
    if(NOT _resolved_ok)
      message(FATAL_ERROR "${_resolved_reason}")
    endif()
  endif()

  set(NAPI_V8_BUILD_METHOD "${_requested_method}" CACHE STRING
    "V8 resolution method: prebuilt|source|local" FORCE)
  set_property(CACHE NAPI_V8_BUILD_METHOD PROPERTY STRINGS prebuilt source local)

  set(NAPI_V8_EFFECTIVE_BUILD_METHOD "${_effective_method}" CACHE STRING
    "Effective resolved V8 method" FORCE)
  set(NAPI_V8_INCLUDE_DIR "${_resolved_include}" CACHE PATH "Path to V8 headers" FORCE)
  set(NAPI_V8_LIBRARY "${_resolved_library}" CACHE FILEPATH
    "Path to V8 runtime library (monolith/static/dynamic)" FORCE)
  set(NAPI_V8_EXTRA_LIBS "${_resolved_extra}" CACHE STRING
    "Semicolon-separated extra V8 libraries (e.g. libplatform/libbase)" FORCE)
  set(NAPI_V8_DEFINES "${_resolved_defines}" CACHE STRING
    "Semicolon-separated V8 embedder compile definitions" FORCE)

  # Compatibility aliases for existing callers.
  set(NAPI_V8_V8_INCLUDE_DIR "${NAPI_V8_INCLUDE_DIR}" CACHE PATH "Deprecated alias for NAPI_V8_INCLUDE_DIR" FORCE)
  set(NAPI_V8_V8_LIBRARY "${NAPI_V8_LIBRARY}" CACHE FILEPATH "Deprecated alias for NAPI_V8_LIBRARY" FORCE)
  set(NAPI_V8_V8_MONOLITH_LIB "${NAPI_V8_LIBRARY}" CACHE FILEPATH "Deprecated alias for NAPI_V8_LIBRARY" FORCE)
  set(NAPI_V8_V8_EXTRA_LIBS "${NAPI_V8_EXTRA_LIBS}" CACHE STRING "Deprecated alias for NAPI_V8_EXTRA_LIBS" FORCE)
  set(NAPI_V8_V8_DEFINES "${NAPI_V8_DEFINES}" CACHE STRING "Deprecated alias for NAPI_V8_DEFINES" FORCE)

  message(STATUS "Resolved V8 method: ${NAPI_V8_EFFECTIVE_BUILD_METHOD}")
  message(STATUS "Resolved V8 include dir: ${NAPI_V8_INCLUDE_DIR}")
  message(STATUS "Resolved V8 library: ${NAPI_V8_LIBRARY}")
endfunction()