cmake_minimum_required(VERSION 3.20) project(cnc_sim_wasm_core LANGUAGES C CXX) option(CNC_SIM_ENABLE_LINUXCNC_BRIDGE "Build the experimental LinuxCNC canon bridge" OFF) option(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND "Build the native LinuxCNC librs274 backend" OFF) option(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE "Compile the browser-safe subset of LinuxCNC rs274 sources" OFF) option(CNC_SIM_ENABLE_SMOKE_BACKEND "Build the legacy explicit smoke G-code backend test harness" OFF) if(CNC_SIM_ENABLE_SMOKE_BACKEND AND CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) message(FATAL_ERROR "CNC_SIM_ENABLE_SMOKE_BACKEND cannot be combined with CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE") endif() set(CNC_SIM_LINUXCNC_ROOT "" CACHE PATH "LinuxCNC source root for the experimental bridge") set(CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/../linuxcnc-rs274-wasm-source-files.txt" CACHE FILEPATH "Manifest that partitions LinuxCNC rs274 sources into wasm-safe core and blocked groups" ) set(cnc_sim_core_sources src/canon_event_sink.cpp src/cnc_sim_api.cpp src/gcode_backend.cpp src/linuxcnc_5axiskins_adapter.c src/linuxcnc_5axiskins_adapter.cpp src/linuxcnc_corexykins_adapter.c src/linuxcnc_corexykins_adapter.cpp src/linuxcnc_cubic_adapter.c src/linuxcnc_cubic_adapter.cpp src/linuxcnc_genserfuncs_adapter.c src/linuxcnc_genserfuncs_adapter.cpp src/linuxcnc_genhexkins_adapter.c src/linuxcnc_genhexkins_adapter.cpp src/linuxcnc_kins_util_adapter.c src/linuxcnc_kins_util_adapter.cpp src/linuxcnc_lineardeltakins_adapter.c src/linuxcnc_lineardeltakins_adapter.cpp src/linuxcnc_maxkins_adapter.c src/linuxcnc_maxkins_adapter.cpp src/linuxcnc_pentakins_adapter.c src/linuxcnc_pentakins_adapter.cpp src/linuxcnc_pumakins_adapter.c src/linuxcnc_pumakins_adapter.cpp src/linuxcnc_rotatekins_adapter.c src/linuxcnc_rotatekins_adapter.cpp src/linuxcnc_rosekins_adapter.c src/linuxcnc_rosekins_adapter.cpp src/linuxcnc_rotarydeltakins_adapter.c src/linuxcnc_rotarydeltakins_adapter.cpp src/linuxcnc_scarakins_adapter.c src/linuxcnc_scarakins_adapter.cpp src/linuxcnc_scorbot_kins_adapter.c src/linuxcnc_scorbot_kins_adapter.cpp src/linuxcnc_tripodkins_adapter.c src/linuxcnc_tripodkins_adapter.cpp src/linuxcnc_trtfuncs_adapter.c src/linuxcnc_trtfuncs_adapter.cpp src/linuxcnc_userkfuncs_adapter.c src/linuxcnc_userkfuncs_adapter.cpp src/linuxcnc_xyzab_tdr_kins_adapter.c src/linuxcnc_xyzab_tdr_kins_adapter.cpp src/rtcp_kinematics.cpp src/simulator_gcode_controls.cpp ) set(cnc_sim_smoke_backend_sources src/smoke_gcode_parser.cpp ) set(cnc_sim_linuxcnc_rs274_backend_sources src/linuxcnc_canon_bridge.cpp src/linuxcnc_rs274_backend.cpp src/linuxcnc_tooldata_fixture.cpp ) if(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND) if(CNC_SIM_ENABLE_SMOKE_BACKEND) message(FATAL_ERROR "CNC_SIM_ENABLE_SMOKE_BACKEND cannot be combined with CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND") endif() if(EMSCRIPTEN) message(FATAL_ERROR "CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND is native-only; it links LinuxCNC librs274") endif() if(NOT CNC_SIM_LINUXCNC_ROOT) message(FATAL_ERROR "Set CNC_SIM_LINUXCNC_ROOT to the LinuxCNC source root") endif() list(APPEND cnc_sim_core_sources ${cnc_sim_linuxcnc_rs274_backend_sources}) elseif(CNC_SIM_ENABLE_SMOKE_BACKEND) list(APPEND cnc_sim_core_sources ${cnc_sim_smoke_backend_sources}) endif() if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) if(NOT CNC_SIM_LINUXCNC_ROOT) message(FATAL_ERROR "Set CNC_SIM_LINUXCNC_ROOT to the LinuxCNC source root") endif() get_filename_component(CNC_SIM_LINUXCNC_ROOT_ABS "${CNC_SIM_LINUXCNC_ROOT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ) if(NOT IS_DIRECTORY "${CNC_SIM_LINUXCNC_ROOT_ABS}") message(FATAL_ERROR "LinuxCNC source root does not exist: ${CNC_SIM_LINUXCNC_ROOT_ABS}") endif() if(NOT EXISTS "${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}") message(FATAL_ERROR "Missing LinuxCNC wasm source manifest: ${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}") endif() if(IS_DIRECTORY "${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}") message(FATAL_ERROR "LinuxCNC wasm source manifest is not a file: ${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}") endif() set(linuxcnc_wasm_safe_probe_sources) set(linuxcnc_wasm_blocked_sources) file(STRINGS "${CNC_SIM_LINUXCNC_WASM_SOURCE_MANIFEST}" linuxcnc_wasm_manifest_lines) foreach(manifest_line IN LISTS linuxcnc_wasm_manifest_lines) string(STRIP "${manifest_line}" manifest_line) if(manifest_line STREQUAL "" OR manifest_line MATCHES "^#") continue() endif() if(NOT manifest_line MATCHES "^([^:]+):([^:]+):(.*)$") message(FATAL_ERROR "Bad LinuxCNC wasm source manifest line: ${manifest_line}") endif() set(manifest_group "${CMAKE_MATCH_1}") set(manifest_path "${CMAKE_MATCH_2}") if(NOT manifest_group STREQUAL "core" AND NOT manifest_group STREQUAL "blocked" AND NOT manifest_group STREQUAL "header" AND NOT manifest_group STREQUAL "metadata" AND NOT manifest_group STREQUAL "blocked-header") message(FATAL_ERROR "Unknown LinuxCNC wasm source manifest group: ${manifest_group}") endif() set(manifest_source "${CNC_SIM_LINUXCNC_ROOT_ABS}/${manifest_path}") if(NOT EXISTS "${manifest_source}") message(FATAL_ERROR "LinuxCNC wasm manifest source does not exist: ${manifest_source}") endif() if(IS_DIRECTORY "${manifest_source}") message(FATAL_ERROR "LinuxCNC wasm manifest source is not a file: ${manifest_source}") endif() if(manifest_group STREQUAL "core") list(APPEND linuxcnc_wasm_safe_probe_sources "${manifest_source}") elseif(manifest_group STREQUAL "blocked") list(APPEND linuxcnc_wasm_blocked_sources "${manifest_source}") endif() endforeach() list(LENGTH linuxcnc_wasm_safe_probe_sources linuxcnc_wasm_safe_probe_source_count) list(LENGTH linuxcnc_wasm_blocked_sources linuxcnc_wasm_blocked_source_count) if(linuxcnc_wasm_safe_probe_source_count EQUAL 0) message(FATAL_ERROR "LinuxCNC wasm source manifest has no core entries") endif() if(linuxcnc_wasm_blocked_source_count EQUAL 0) message(FATAL_ERROR "LinuxCNC wasm source manifest has no blocked entries") endif() message(STATUS "LinuxCNC wasm-safe core sources: ${linuxcnc_wasm_safe_probe_source_count}") message(STATUS "LinuxCNC wasm blocked sources: ${linuxcnc_wasm_blocked_source_count}") set(cnc_sim_wasm_safe_preinclude_options "SHELL:-include wctype.h") set(cnc_sim_wasm_safe_section_options -ffunction-sections -fdata-sections) set(cnc_sim_wasm_safe_link_options "-Wl,--gc-sections") if(EMSCRIPTEN) list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-include libgen.h") find_path(CNC_SIM_FMT_INCLUDE_DIR fmt/format.h PATHS /usr/include /usr/local/include NO_CMAKE_FIND_ROOT_PATH REQUIRED ) list(APPEND cnc_sim_wasm_safe_preinclude_options "SHELL:-idirafter ${CNC_SIM_FMT_INCLUDE_DIR}") endif() set(linuxcnc_wasm_safe_probe_shims ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/dlfcn.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/emc_status_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/gettext_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/linuxcnc_runtime_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/nml_status_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/python_c_api_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rcs_print_shim.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rtapi_compat.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/tooldata/tooldata_mmap_backend.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/tooldata/tooldata_runtime_stubs.cc ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/pythonplugin/python_plugin.cc ) add_library(linuxcnc_rs274_wasm_safe_probe_objects OBJECT ${linuxcnc_wasm_safe_probe_shims} ${linuxcnc_wasm_safe_probe_sources} ) target_compile_features(linuxcnc_rs274_wasm_safe_probe_objects PUBLIC cxx_std_20) target_compile_definitions(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ULAPI) target_compile_options(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options} ${cnc_sim_wasm_safe_section_options} ) target_include_directories(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims ${CNC_SIM_LINUXCNC_ROOT_ABS}/src ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT_ABS}/include ) if(EMSCRIPTEN) target_compile_definitions(linuxcnc_rs274_wasm_safe_probe_objects PRIVATE FMT_HEADER_ONLY=1) endif() set(cnc_sim_wasm_runtime_probe_main ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc ) if(linuxcnc_wasm_blocked_sources) add_custom_target(linuxcnc_rs274_wasm_blocked_sources SOURCES ${linuxcnc_wasm_blocked_sources} ) endif() endif() if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) list(APPEND cnc_sim_core_sources ${cnc_sim_linuxcnc_rs274_backend_sources}) endif() add_library(cnc_sim_objects OBJECT ${cnc_sim_core_sources} ) target_include_directories(cnc_sim_objects PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/../../linuxcnc/include ) target_compile_features(cnc_sim_objects PUBLIC cxx_std_17) set(cnc_sim_linuxcnc_kinematics_c_sources src/linuxcnc_5axiskins_adapter.c src/linuxcnc_corexykins_adapter.c src/linuxcnc_cubic_adapter.c src/linuxcnc_genserfuncs_adapter.c src/linuxcnc_genhexkins_adapter.c src/linuxcnc_kins_util_adapter.c src/linuxcnc_lineardeltakins_adapter.c src/linuxcnc_maxkins_adapter.c src/linuxcnc_pentakins_adapter.c src/linuxcnc_pumakins_adapter.c src/linuxcnc_rotatekins_adapter.c src/linuxcnc_rosekins_adapter.c src/linuxcnc_rotarydeltakins_adapter.c src/linuxcnc_scarakins_adapter.c src/linuxcnc_scorbot_kins_adapter.c src/linuxcnc_tripodkins_adapter.c src/linuxcnc_trtfuncs_adapter.c src/linuxcnc_userkfuncs_adapter.c src/linuxcnc_xyzab_tdr_kins_adapter.c ) set_source_files_properties( ${cnc_sim_linuxcnc_kinematics_c_sources} PROPERTIES COMPILE_OPTIONS "$<$:-fpermissive>" ) if(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND) find_package(Python3 REQUIRED COMPONENTS Development) target_compile_definitions(cnc_sim_objects PRIVATE CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND ) target_include_directories(cnc_sim_objects PRIVATE ${Python3_INCLUDE_DIRS} ${CNC_SIM_LINUXCNC_ROOT}/src ${CNC_SIM_LINUXCNC_ROOT}/src/emc ${CNC_SIM_LINUXCNC_ROOT}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT}/include ) endif() if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) target_compile_definitions(cnc_sim_objects PRIVATE CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE ULAPI ) target_compile_options(cnc_sim_objects PRIVATE ${cnc_sim_wasm_safe_preinclude_options}) target_include_directories(cnc_sim_objects PRIVATE ${CNC_SIM_LINUXCNC_ROOT_ABS}/src ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT_ABS}/include ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims ) if(EMSCRIPTEN) target_compile_definitions(cnc_sim_objects PRIVATE FMT_HEADER_ONLY=1) endif() endif() if(CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) add_executable(linuxcnc_rs274_wasm_safe_probe EXCLUDE_FROM_ALL $ $ ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims/rs274ngc_pre_probe_main.cc ) target_compile_features(linuxcnc_rs274_wasm_safe_probe PRIVATE cxx_std_20) target_compile_definitions(linuxcnc_rs274_wasm_safe_probe PRIVATE CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE ULAPI ) target_compile_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options}) target_link_options(linuxcnc_rs274_wasm_safe_probe PRIVATE ${cnc_sim_wasm_safe_link_options}) target_include_directories(linuxcnc_rs274_wasm_safe_probe PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims ${CNC_SIM_LINUXCNC_ROOT_ABS}/src ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT_ABS}/include ) if(EMSCRIPTEN) target_compile_definitions(linuxcnc_rs274_wasm_safe_probe PRIVATE FMT_HEADER_ONLY=1) else() target_link_libraries(linuxcnc_rs274_wasm_safe_probe PRIVATE fmt) endif() add_executable(cnc_sim_wasm_runtime_probe EXCLUDE_FROM_ALL $ $ ${cnc_sim_wasm_runtime_probe_main} ) target_compile_features(cnc_sim_wasm_runtime_probe PRIVATE cxx_std_20) target_compile_definitions(cnc_sim_wasm_runtime_probe PRIVATE ULAPI) target_compile_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_preinclude_options}) target_link_options(cnc_sim_wasm_runtime_probe PRIVATE ${cnc_sim_wasm_safe_link_options}) target_include_directories(cnc_sim_wasm_runtime_probe PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims ${CNC_SIM_LINUXCNC_ROOT_ABS}/src ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT_ABS}/include ) if(EMSCRIPTEN) target_compile_definitions(cnc_sim_wasm_runtime_probe PRIVATE FMT_HEADER_ONLY=1) else() target_link_libraries(cnc_sim_wasm_runtime_probe PRIVATE fmt) endif() endif() if(CNC_SIM_ENABLE_SMOKE_BACKEND) target_compile_definitions(cnc_sim_objects PRIVATE CNC_SIM_ENABLE_SMOKE_BACKEND ) endif() add_library(cnc_sim_core STATIC $ ) target_include_directories(cnc_sim_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) if(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND) target_link_directories(cnc_sim_core PUBLIC ${CNC_SIM_LINUXCNC_ROOT}/lib ) target_link_libraries(cnc_sim_core PUBLIC rs274 tooldata Python3::Python ) target_link_options(cnc_sim_core PUBLIC "-Wl,-rpath,${CNC_SIM_LINUXCNC_ROOT}/lib" ) endif() if(NOT EMSCRIPTEN) if(CNC_SIM_ENABLE_SMOKE_BACKEND) add_executable(cnc_sim_api_smoke tests/cnc_sim_api_smoke.cpp ) target_link_libraries(cnc_sim_api_smoke PRIVATE cnc_sim_core) target_include_directories(cnc_sim_api_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) endif() add_executable(canon_event_sink_smoke tests/canon_event_sink_smoke.cpp ) target_link_libraries(canon_event_sink_smoke PRIVATE cnc_sim_core) target_include_directories(canon_event_sink_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) add_executable(rtcp_kinematics_smoke tests/rtcp_kinematics_smoke.cpp ) target_link_libraries(rtcp_kinematics_smoke PRIVATE cnc_sim_core) target_include_directories(rtcp_kinematics_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) add_executable(linuxcnc_gees_table_smoke tests/linuxcnc_gees_table_smoke.cpp ) target_include_directories(linuxcnc_gees_table_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) add_executable(simulator_gcode_controls_smoke tests/simulator_gcode_controls_smoke.cpp ) target_link_libraries(simulator_gcode_controls_smoke PRIVATE cnc_sim_core) target_include_directories(simulator_gcode_controls_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) if(CNC_SIM_ENABLE_SMOKE_BACKEND) add_executable(cnc_sim_dump tools/cnc_sim_dump.cpp ) target_link_libraries(cnc_sim_dump PRIVATE cnc_sim_core) target_include_directories(cnc_sim_dump PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) endif() if(CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND) add_executable(cnc_sim_api_linuxcnc_rs274_smoke tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp ) target_link_libraries(cnc_sim_api_linuxcnc_rs274_smoke PRIVATE cnc_sim_core) target_include_directories(cnc_sim_api_linuxcnc_rs274_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) endif() endif() if(CNC_SIM_ENABLE_LINUXCNC_BRIDGE) if(NOT CNC_SIM_LINUXCNC_ROOT) message(FATAL_ERROR "Set CNC_SIM_LINUXCNC_ROOT to the LinuxCNC source root") endif() add_library(cnc_sim_linuxcnc_canon_bridge STATIC src/linuxcnc_canon_bridge.cpp ) target_include_directories(cnc_sim_linuxcnc_canon_bridge PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CNC_SIM_LINUXCNC_ROOT}/src/emc ${CNC_SIM_LINUXCNC_ROOT}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT}/src ${CNC_SIM_LINUXCNC_ROOT}/include ) target_link_directories(cnc_sim_linuxcnc_canon_bridge PRIVATE ${CNC_SIM_LINUXCNC_ROOT}/lib ) target_link_libraries(cnc_sim_linuxcnc_canon_bridge PRIVATE cnc_sim_core tooldata) target_link_options(cnc_sim_linuxcnc_canon_bridge PRIVATE "-Wl,-rpath,${CNC_SIM_LINUXCNC_ROOT}/lib" ) endif() if(EMSCRIPTEN) if(NOT CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE) message(FATAL_ERROR "WASM builds must enable CNC_SIM_ENABLE_LINUXCNC_WASM_SAFE_PROBE so LinuxCNC rs274 sources are linked") endif() add_executable(cnc_sim_wasm $ $ ) target_include_directories(cnc_sim_wasm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/wasm_shims ${CNC_SIM_LINUXCNC_ROOT_ABS}/src ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/nml_intf ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/rs274ngc ${CNC_SIM_LINUXCNC_ROOT_ABS}/src/emc/motion ${CNC_SIM_LINUXCNC_ROOT_ABS}/include ) target_compile_definitions(cnc_sim_wasm PRIVATE FMT_HEADER_ONLY=1) set_target_properties(cnc_sim_wasm PROPERTIES OUTPUT_NAME "cnc_sim" SUFFIX ".js" ) target_link_options(cnc_sim_wasm PRIVATE ${cnc_sim_wasm_safe_link_options} "--no-entry" "-sMODULARIZE=1" "-sEXPORT_NAME=createCncSimModule" "-sALLOW_MEMORY_GROWTH=1" "-sALLOW_TABLE_GROWTH=1" "-sFORCE_FILESYSTEM=1" "-sEXPORTED_FUNCTIONS=['_malloc','_free','_cnc_sim_create','_cnc_sim_destroy','_cnc_sim_reset','_cnc_sim_set_dialect','_cnc_sim_set_event_callback','_cnc_sim_load_config_json','_cnc_sim_parse_program','_cnc_sim_last_error']" "-sEXPORTED_RUNTIME_METHODS=['FS','ccall','cwrap','UTF8ToString','stringToUTF8','lengthBytesUTF8','addFunction','removeFunction']" ) endif()