mirror of
https://github.com/sfall-team/sslc.git
synced 2026-07-27 16:52:49 -07:00
Add Linux and Nodejs build targets (#14)
* Add CI build * fix * Update toolset * Use v141_xp * Run on win2019 * Fixes * Link libs statically * Use vcxproj * Experiment: no spaces in configuration * Experiments with build * Commented Fallout1 builds * Comment Win2k builds * Exclude ./out/ from git * Add compat headers * Use one compat file * Fixes for build * Include compat * Add guard for compat.c * Add CMakeLists * Add linux x32 build * Small improvements to build steps * Do not install build-essential * gRevert "Do not install build-essential" This reverts commit434d8e9e98. * Build wasi * Fixing CI pipeline * Fix wasi-sdk download url * Use "" for version * Fix wasm build * Fix wasi build * Disable WASI build due to setjmp/longjmp * Adding emscripten support * Fixes for builds * Include nodefs * Add emscripten build into CI * Build release version from github * Emit mjs file * Add environment node * Use emscripten 4.0.8 * Add comment * Use PATH_MAX * Move all builds into one file * Use bash for linux builds only * Rename artifacts names * Add auto-releases * Add debug ls * Fix artifacts names * Remove folder from tar archive * Fix artifact name * Enable release only on push * Release other builds too * fix names * Fix names * Enable deploy only on push * Remove useless line * Use NODERAWFS & format CMakeLists * Add node-rawfs into emscripten build name * Delete tmp file on non-windows platforms * Rename tmp_file_name * Remove temp file on posix platforms * Revert "Remove temp file on non windows platforms" * Use nodefs instead of noderawfs * Fix ChatGPT code * Add simple tests * Fixes to tests * Fixes for tests run * Small improvements * Rename variable * Small refactor of test runner * Remove warnings which shows folder name * Add minimal package.json * fix package.json main * Fixes for package.json * Fixes for npm packaging * Use bin for all in cmake * Use package subfolder in emscripten ci build * Update CI * Add compiler.mjs as binary * Add test into CI * Bump version * Thinking about running on fallout2 rpu * Add some tests of Fallout RPU * Adding tests for RPU * Debugging * Small improvements * Fixes * Remove comment (there is no problem with asb paths because it runs on the same system) * Experimental: Add RPU test into CI pipeline * CI fixes * Fixes * Use set -e * Add debug for windows build * Add install 7z * Fixes for test runner * Fixes for test runner * Fix symlink creation * Fixing emscripten runner * Add comments * Skip running long test on debug build * Add comment * Use relative symlink for emscripten builds * Show stderr/stdout on wasm crash * Increase stack size to fix emscripten crashes * Add option to skip rpu check by using label * Add additinal label to skip wasm check because they are really really slow * Remove useless line * Add daemon mode for compiler * Use nodejs daemon mode in CI * Add debug for daemon start * Fix daemon start in CI * Add some errors check for daemon mode * Fix daemon cwd * Reduce logging for daemon * use node 22 for emscripten tests runner * Split RPU setup and test run, use cache * Fix order: first try cache * Fix type in CI action * Fix dependencies in CI * Add fail-on-cache-miss * Install wine on test setup * Bump cache version * Add comment * Fix for different caches * Fix bash script * Bump cache version * Check that snapshot file exists * Add "bin" option into package.json * Add comment * Fix checks for RPU * Improve testing logic * Do not install wine if it is already installed * Add some sanity checks * Remove useless check * Check compiler on setup stage * Bump cache version to check setup script on all platforms * Add set -u * Fix env varibales, check wine in bash * Remove unused variable now * Bump cache version * Suppress warning on Windows when checking for apt * Disable asyncify, reduce memory growth * Remove export all * Use O2 for release * Revert exports back because we need FS * Remove emscripted daemon mode from CI * Remove CI daemon mode from emscripten compiler * Adding utils.bash file * Move utils * Move embedded test files * Move gitignore * Use utils for embedded tests too * Remove useless assignment * Fix Windows regular tests * Rename folder name * Add some test files * Add failing .ssl files * Replace paths for embedded tests too * Add expected results for failing compilations * Remove spaces in bash script * Use new line for reports * Remove unused variable in test run * Use new line for test runner too * Use windows-latest * Try windows 2022 * Revert "Try windows 2022" This reverts commit62f6036fae. * Try to use latest but install vs2017 * Do vcvars from vs2017 * Use vs2019 * Change step name * List directories * Use VsDevCmd * Add cmd as shell for dir * use multi-line * Fix multiline * remove duplicate * Use 2017 * Try to install directly * Use cmd as shell * Add sdk to install * Use call * Add VC.Tools.v141; * Add includeRecommended * Add dir command * More components * Use choco * Into one line * Use windows-2025 * Use 2019 * Trying to use vs2019 * Remove choco cache because it does not work properly * Disable ES6 export * Remove wrong commit * Enforce EXPORT_ES6=0 * Revert back to0ef49cbb01* Add separate mjs file with __filename
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
setup_rpu_tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache RPU & modderspack
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: test/gamescripts
|
||||
key: rpu-and-modderpack-gamescripts-v1004
|
||||
|
||||
- name: Download RPU scripts & modderspack
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
shell: bash
|
||||
run: |
|
||||
(cd test && bash test_on_fallout2_rpu_setup.bash)
|
||||
|
||||
build_windows:
|
||||
runs-on: windows-2025
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Visual Studio 2019 Build Tools with v141_xp
|
||||
shell: cmd
|
||||
run: |
|
||||
choco install visualstudio2019buildtools -y --package-parameters="'--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.xp --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.10240 --add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP --add Microsoft.VisualStudio.Component.WinXP'"
|
||||
|
||||
- name: Patch vcxproj to use v141_xp toolset
|
||||
run: sed -i 's|<PlatformToolset>v100</PlatformToolset>|<PlatformToolset>v141_xp</PlatformToolset>|g' sslc.vcxproj
|
||||
|
||||
- name: Patch vcxproj to link debug build statically
|
||||
run: sed -i 's|MultiThreadedDebugDLL|MultiThreadedDebug|g' sslc.vcxproj
|
||||
|
||||
- name: List Visual Studio directories
|
||||
shell: cmd
|
||||
run: |
|
||||
dir "C:\Program Files (x86)\Microsoft Visual Studio" /s /b
|
||||
|
||||
- name: Build Debug
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& msbuild sslc.sln "/t:Clean;Build" /p:Configuration="Debug" /p:Platform="Win32" /m
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
export SSLC=../Debug/sslc.exe
|
||||
(cd test && bash ./tests.bash)
|
||||
|
||||
- name: Upload Debug
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-debug
|
||||
path: |
|
||||
**/Debug/*.exe
|
||||
|
||||
# - name: Build Debug for Fallout1
|
||||
# run: msbuild sslc.vcxproj "/t:Clean;Build" /p:Configuration="Debug (for Fallout1)" /p:Platform="Win32" /m
|
||||
|
||||
# - name: Upload Debug for Fallout1
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: build-Debug-for-Fallout1
|
||||
# path: |
|
||||
# **/Debug*/*.exe
|
||||
|
||||
- name: Mkdir
|
||||
run: mkdir -p Build
|
||||
|
||||
- name: Build Release
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& msbuild sslc.sln "/t:Clean;Build" /p:Configuration="Release" /p:Platform="Win32" /m
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
export SSLC=../Build/compile.exe
|
||||
(cd test && bash ./tests.bash)
|
||||
|
||||
- name: Cache RPU & modderspack (separate cache for Windows)
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: test/gamescripts
|
||||
key: rpu-and-modderpack-gamescripts-v1004
|
||||
- name: Download RPU scripts & modderspack
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
shell: bash
|
||||
run: |
|
||||
(cd test && bash test_on_fallout2_rpu_setup.bash)
|
||||
|
||||
- name: Test on Fallout RPU
|
||||
shell: bash
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
run: |
|
||||
export SSLC=../Build/compile.exe
|
||||
(cd test && bash ./test_on_fallout2_rpu_run.bash)
|
||||
|
||||
- name: Upload Release
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-release
|
||||
path: |
|
||||
**/Build/*.exe
|
||||
|
||||
# - name: Build Release for Fallout1
|
||||
# run: msbuild sslc.sln "/t:Clean;Build" /p:Configuration="Release (for Fallout1)" /p:Platform="Win32" /m
|
||||
|
||||
# - name: Upload Release for Fallout1
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: build-Release-for-Fallout1
|
||||
# path: |
|
||||
# **/Build/*.exe
|
||||
|
||||
- name: Build Release dll
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" ^
|
||||
&& msbuild sslc.sln "/t:Clean;Build" /p:Configuration="Release (dll)" /p:Platform="Win32" /m
|
||||
|
||||
- name: Upload Release dll
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-release-dll
|
||||
path: |
|
||||
**/Build/*.dll
|
||||
|
||||
# - name: Build Win2K
|
||||
# run: msbuild sslc.sln "/t:Clean;Build" /p:Configuration="Win2K" /p:Platform="Win32" /m
|
||||
|
||||
# - name: Upload Win2K
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: build-Win2K
|
||||
# path: |
|
||||
# **/Win2K*/*.exe
|
||||
|
||||
build-wasm:
|
||||
name: WebAssembly (WASI) Build
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [setup_rpu_tests]
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
if: false # Disable this job because WASI do not support setjmp/longjmp
|
||||
env:
|
||||
WASI_VERSION: "25"
|
||||
WASI_VERSION_FULL: "25.0"
|
||||
WASI_SDK_DIR: ${{ github.workspace }}/wasi-sdk
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download wasi-sdk
|
||||
run: |
|
||||
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{env.WASI_VERSION}}/wasi-sdk-${{env.WASI_VERSION_FULL}}-x86_64-linux.tar.gz | tar xz
|
||||
ls -lah
|
||||
mv wasi-sdk-${{env.WASI_VERSION_FULL}}-x86_64-linux wasi-sdk
|
||||
|
||||
- name: Configure project
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{env.WASI_SDK_DIR}}/share/cmake/wasi-sdk.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd build
|
||||
cmake --build .
|
||||
find .
|
||||
|
||||
- name: Upload WebAssembly artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wasm-wasi
|
||||
path: |
|
||||
build/**/*.wasm
|
||||
|
||||
build_emscripten:
|
||||
name: Build webassembly version (Emscripten)
|
||||
runs-on: ubuntu-latest
|
||||
needs: [setup_rpu_tests]
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
# container:
|
||||
# image: emscripten/emsdk:4.0.8
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Build wasm module
|
||||
run: |
|
||||
docker run --rm --user $(id -u):$(id -g) \
|
||||
-v $(pwd):/src emscripten/emsdk:4.0.8 \
|
||||
sh -c 'mkdir -p build && cd build && emcmake cmake -DCMAKE_BUILD_TYPE="Release" ../ && emmake make'
|
||||
|
||||
# mkdir -p build
|
||||
# cd build
|
||||
# emcmake cmake .. -DCMAKE_BUILD_TYPE="Release"
|
||||
# emmake make
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
export SSLC=../build/bin/compiler.mjs
|
||||
(cd test && bash ./tests.bash)
|
||||
|
||||
|
||||
- name: Get cache RPU & modderspack
|
||||
uses: actions/cache@v4
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
with:
|
||||
path: test/gamescripts
|
||||
key: rpu-and-modderpack-gamescripts-v1004
|
||||
fail-on-cache-miss: true
|
||||
- name: Test on Fallout RPU
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
run: |
|
||||
export SSLC=../build/bin/compiler.mjs
|
||||
(cd test && bash ./test_on_fallout2_rpu_run.bash)
|
||||
|
||||
- name: Upload .wasm artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wasm-emscripten-node-nodefs
|
||||
path: build/bin/**
|
||||
|
||||
build_linux:
|
||||
name: Linux build
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [setup_rpu_tests]
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Dependencies (x86)
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential g++-multilib libc6-dev:i386
|
||||
|
||||
- name: Configure & build
|
||||
run: |
|
||||
mkdir out
|
||||
cd out
|
||||
cmake ..
|
||||
make
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
export SSLC=../out/bin/sslc
|
||||
(cd test && bash ./tests.bash)
|
||||
|
||||
- name: Get cache RPU & modderspack
|
||||
uses: actions/cache@v4
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
with:
|
||||
path: test/gamescripts
|
||||
key: rpu-and-modderpack-gamescripts-v1004
|
||||
fail-on-cache-miss: true
|
||||
- name: Test on Fallout RPU
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip-rpu-check')
|
||||
run: |
|
||||
export SSLC=../out/bin/sslc
|
||||
(cd test && bash ./test_on_fallout2_rpu_run.bash)
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux
|
||||
path: out/bin/**
|
||||
retention-days: 7
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [build_windows, build_linux, build_emscripten]
|
||||
permissions: write-all
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: Prepare artifacts
|
||||
run: |
|
||||
ls -laR
|
||||
|
||||
cd artifacts
|
||||
|
||||
mv wasm-emscripten-node-nodefs package
|
||||
tar -czf wasm-emscripten-node-nodefs.tar.gz package
|
||||
rm -rf package
|
||||
|
||||
ls -laR
|
||||
|
||||
mv windows-debug/Debug/sslc.exe sslc-debug.exe
|
||||
rm -rf windows-debug
|
||||
|
||||
mv windows-release/Build/compile.exe compile.exe
|
||||
rm -rf windows-release
|
||||
|
||||
mv windows-release-dll/Build/parser.dll parser.dll
|
||||
rm -rf windows-release-dll
|
||||
|
||||
mv linux/sslc sslc-linux
|
||||
rm -rf linux
|
||||
|
||||
ls -laR
|
||||
|
||||
if find . -mindepth 1 -maxdepth 1 -type d | grep -q .; then
|
||||
echo "Directory contains subfolders."
|
||||
exit 1
|
||||
else
|
||||
echo "No subfolders found."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: Generate timestamp tag
|
||||
id: tag
|
||||
run: echo "TAG_NAME=$(date +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload release
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
with:
|
||||
tag_name: ${{ steps.tag.outputs.TAG_NAME }}
|
||||
name: Build from ${{ steps.tag.outputs.TAG_NAME }}
|
||||
files: artifacts/*
|
||||
draft: false
|
||||
prerelease: true
|
||||
@@ -1,8 +1,10 @@
|
||||
*.vcxproj.user
|
||||
.vs/
|
||||
Build/
|
||||
build/
|
||||
Debug/
|
||||
Release/
|
||||
ReleaseDLL/
|
||||
*.exe
|
||||
*.dll
|
||||
out/
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(EXECUTABLE_NAME sslc)
|
||||
|
||||
project(${EXECUTABLE_NAME})
|
||||
|
||||
# Set 32-bit flag for all targets because it segfaults on 64-bit
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
set(SOURCES
|
||||
compile.c
|
||||
parse.c
|
||||
parselib.c
|
||||
extra.c
|
||||
gencode.c
|
||||
lex.c
|
||||
parseext.c
|
||||
mcpp_main.c
|
||||
mcpp_directive.c
|
||||
mcpp_eval.c
|
||||
mcpp_expand.c
|
||||
mcpp_support.c
|
||||
mcpp_system.c
|
||||
optimize.c
|
||||
compat.c
|
||||
)
|
||||
|
||||
add_executable(${EXECUTABLE_NAME} ${SOURCES})
|
||||
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
|
||||
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".mjs")
|
||||
|
||||
# No need to use asyncify
|
||||
# target_link_options(${EXECUTABLE_NAME} PRIVATE "-sASYNCIFY")
|
||||
# target_link_options(${EXECUTABLE_NAME} PRIVATE "-sASYNCIFY_STACK_SIZE=20480")
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sALLOW_MEMORY_GROWTH")
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-MEMORY_GROWTH_LINEAR_STEP=16mb")
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sNO_DISABLE_EXCEPTION_CATCHING")
|
||||
|
||||
target_link_options( ${EXECUTABLE_NAME} PRIVATE "-lnodefs.js" )
|
||||
# target_link_options(${EXECUTABLE_NAME} PRIVATE "-sNODERAWFS")
|
||||
|
||||
# Disabled because of emscipten bug
|
||||
# target_link_options( ${EXECUTABLE_NAME} PRIVATE "-sCASE_INSENSITIVE_FS" )
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sMODULARIZE=1")
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sEXPORT_ES6=1")
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sENVIRONMENT=node")
|
||||
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sEXPORTED_RUNTIME_METHODS=callMain")
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sEXPORT_ALL")
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sEXIT_RUNTIME")
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "$<$<CONFIG:DEBUG>:-g>")
|
||||
|
||||
target_link_options(${EXECUTABLE_NAME} PRIVATE "-sSTACK_SIZE=2048000")
|
||||
|
||||
# Next commands replaces import.meta.url with __filename in sslc.mjs
|
||||
# This is done to support importing in VScode-BGforge-MLS
|
||||
set(patch_script "${CMAKE_BINARY_DIR}/patch_sslc.cmake")
|
||||
file(WRITE "${patch_script}" "
|
||||
if(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/bin/sslc.mjs\")
|
||||
file(READ \"${CMAKE_CURRENT_BINARY_DIR}/bin/sslc.mjs\" file_content)
|
||||
string(REPLACE \"import.meta.url\" \"__filename\" file_content \"\${file_content}\")
|
||||
file(WRITE \"${CMAKE_CURRENT_BINARY_DIR}/bin/sslc.__filename.mjs\" \"\${file_content}\")
|
||||
message(STATUS \"Patched sslc.mjs\")
|
||||
else()
|
||||
message(FATAL_ERROR \"sslc.mjs does not exist!\")
|
||||
endif()
|
||||
")
|
||||
add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -P "${patch_script}"
|
||||
COMMENT "Applying patch to sslc.mjs"
|
||||
)
|
||||
|
||||
set(PACKAGE_JSON_CONTENT [[
|
||||
{
|
||||
"name": "sslc-emscripten-nodefs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "sslc.mjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
},
|
||||
"bin": "compiler.mjs",
|
||||
"author": "",
|
||||
"license": "UNLICENSED"
|
||||
}
|
||||
|
||||
]])
|
||||
file(WRITE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/package.json "${PACKAGE_JSON_CONTENT}")
|
||||
|
||||
file(COPY "compiler.mjs" DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
#include "compat.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
|
||||
// Functions in this file are written by ChatGPT
|
||||
// Need carefull review
|
||||
|
||||
int strcpy_s(char* dest, size_t destsz, const char* src) {
|
||||
if (!dest || !src || destsz == 0) return EINVAL;
|
||||
size_t len = strlen(src);
|
||||
if (len >= destsz) {
|
||||
dest[0] = '\0';
|
||||
return ERANGE;
|
||||
}
|
||||
strcpy(dest, src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strcat_s(char *dest, size_t destsz, const char *src) {
|
||||
if (!dest || !src || destsz == 0) return EINVAL;
|
||||
|
||||
size_t dest_len = strlen(dest);
|
||||
size_t src_len = strlen(src);
|
||||
|
||||
if (dest_len + src_len + 1 > destsz) {
|
||||
dest[0] = '\0';
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
strcat(dest, src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rand_s(unsigned int *randomValue) {
|
||||
if (!randomValue) return EINVAL;
|
||||
*randomValue = (unsigned int)rand();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) {
|
||||
if (!buffer || sizeOfBuffer == 0 || !format) return EINVAL;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int written = vsnprintf(buffer, sizeOfBuffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (written < 0 || (size_t)written >= sizeOfBuffer) {
|
||||
buffer[0] = '\0'; // mimic Windows behavior
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
intptr_t _findfirst(const char *pattern, struct _finddata_t *data) {
|
||||
_find_handle_t *handle = calloc(1, sizeof(_find_handle_t));
|
||||
if (!handle) return -1;
|
||||
|
||||
// Split pattern into directory path and wildcard
|
||||
const char *slash = strrchr(pattern, '/');
|
||||
if (slash) {
|
||||
size_t len = (size_t)(slash - pattern + 1);
|
||||
if (len >= sizeof(handle->path)) len = sizeof(handle->path) - 1;
|
||||
strncpy(handle->path, pattern, len);
|
||||
handle->path[len] = '\0';
|
||||
strncpy(handle->pattern, slash + 1, sizeof(handle->pattern) - 1);
|
||||
} else {
|
||||
strncpy(handle->path, "./", sizeof(handle->path) - 1);
|
||||
strncpy(handle->pattern, pattern, sizeof(handle->pattern) - 1);
|
||||
}
|
||||
|
||||
handle->dir = opendir(handle->path);
|
||||
if (!handle->dir) {
|
||||
free(handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(handle->dir)) != NULL) {
|
||||
if (fnmatch(handle->pattern, entry->d_name, 0) == 0) {
|
||||
struct stat st;
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, sizeof(fullpath), "%s%s", handle->path, entry->d_name);
|
||||
if (stat(fullpath, &st) == 0) {
|
||||
strncpy(data->name, entry->d_name, sizeof(data->name) - 1);
|
||||
data->name[sizeof(data->name) - 1] = '\0';
|
||||
|
||||
data->time_write = st.st_mtime;
|
||||
data->size = st.st_size;
|
||||
data->attrib = S_ISDIR(st.st_mode) ? _A_SUBDIR : _A_NORMAL;
|
||||
return (intptr_t)handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(handle->dir);
|
||||
free(handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _findnext(intptr_t h, struct _finddata_t *data) {
|
||||
_find_handle_t *handle = (_find_handle_t *)h;
|
||||
struct dirent *entry;
|
||||
|
||||
while ((entry = readdir(handle->dir)) != NULL) {
|
||||
if (fnmatch(handle->pattern, entry->d_name, 0) == 0) {
|
||||
struct stat st;
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, sizeof(fullpath), "%s%s", handle->path, entry->d_name);
|
||||
if (stat(fullpath, &st) == 0) {
|
||||
strncpy(data->name, entry->d_name, sizeof(data->name) - 1);
|
||||
data->name[sizeof(data->name) - 1] = '\0';
|
||||
|
||||
data->time_write = st.st_mtime;
|
||||
data->size = st.st_size;
|
||||
data->attrib = S_ISDIR(st.st_mode) ? _A_SUBDIR : _A_NORMAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _findclose(intptr_t h) {
|
||||
_find_handle_t *handle = (_find_handle_t *)h;
|
||||
if (handle) {
|
||||
if (handle->dir) closedir(handle->dir);
|
||||
free(handle);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef _WIN32
|
||||
|
||||
#ifndef _COMPAT_H_DEFINED
|
||||
#define _COMPAT_H_DEFINED
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <fnmatch.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define _A_NORMAL 0x00
|
||||
#define _A_SUBDIR 0x10
|
||||
|
||||
#define _MSC_VER
|
||||
|
||||
|
||||
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...);
|
||||
int rand_s(unsigned int *randomValue);
|
||||
|
||||
int strcpy_s(char* dest, size_t destsz, const char* src);
|
||||
int strcat_s(char *dest, size_t destsz, const char *src);
|
||||
|
||||
#define _stricmp strcasecmp
|
||||
#define GetCurrentProcessId() ((unsigned int)getpid())
|
||||
#define _mkdir(path) mkdir((path), 0777)
|
||||
#define _chdir chdir
|
||||
#define _getcwd getcwd
|
||||
#define _stat stat
|
||||
|
||||
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
typedef __time_t time_t;
|
||||
#endif
|
||||
|
||||
typedef u_int32_t _fsize_t;
|
||||
|
||||
|
||||
struct _finddata_t {
|
||||
unsigned attrib;
|
||||
time_t time_write;
|
||||
size_t size;
|
||||
char name[PATH_MAX];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
DIR *dir;
|
||||
char pattern[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
} _find_handle_t;
|
||||
|
||||
|
||||
intptr_t _findfirst(const char *pattern, struct _finddata_t *data);
|
||||
int _findnext(intptr_t h, struct _finddata_t *data);
|
||||
int _findclose(intptr_t h);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,11 +1,16 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _CRT_RAND_S
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lex.h"
|
||||
#include "parse.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
@@ -214,20 +219,25 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#ifndef WIN2K
|
||||
char tmp_file_name[260] = {0};
|
||||
if(preprocess) {
|
||||
FILE *newfile;
|
||||
unsigned int letters;
|
||||
char tmpbuf[260];
|
||||
|
||||
rand_s(&letters);
|
||||
if(onlypreprocess) {
|
||||
strcpy_s(tmpbuf, 260, name);
|
||||
newfile=fopen(tmpbuf, "w+");
|
||||
strcpy_s(tmp_file_name, 260, name);
|
||||
newfile=fopen(tmp_file_name, "w+");
|
||||
} else {
|
||||
sprintf(tmpbuf, "%d_%8x.tmp", GetCurrentProcessId(), letters);
|
||||
sprintf(tmp_file_name, "%d_%8x.tmp", GetCurrentProcessId(), letters);
|
||||
//#if _DEBUG
|
||||
// newfile=fopen(tmpbuf, "w+");
|
||||
// newfile=fopen(tmp_file_name, "w+");
|
||||
//#else
|
||||
newfile=fopen(tmpbuf, "w+DT");
|
||||
#ifdef WIN32
|
||||
newfile=fopen(tmp_file_name, "w+DT");
|
||||
#else
|
||||
newfile=fopen(tmp_file_name, "w+");
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
if(mcpp_lib_main(foo.file, newfile, buf.name, buf.name, defMacro, includeDir)) {
|
||||
@@ -244,6 +254,11 @@ int main(int argc, char **argv)
|
||||
freeCurrentProgram();
|
||||
}
|
||||
fclose(foo.file);
|
||||
#ifndef WIN32
|
||||
if (strlen(tmp_file_name) > 0) {
|
||||
remove(tmp_file_name);
|
||||
}
|
||||
#endif
|
||||
FreeFileNames();
|
||||
} while (!FINDNEXT(handle, &buf));
|
||||
|
||||
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
//
|
||||
// This is a Node.js wrapper for the SSL Compiler (sslc).
|
||||
// It allows to compile SSL files using the Node.js environment.
|
||||
//
|
||||
// Use it the same way as you would use the `sslc` command-line tool.
|
||||
//
|
||||
|
||||
import path from "path";
|
||||
import Module from "./sslc.mjs";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string[]} sslcArgs Command-line arguments to sslc
|
||||
* @param {Uint8Array} [wasmBinary] A compiled binary, if bundler fails to bundle .wasm file
|
||||
* @param {string} [cwd] Current working directory to compile in.
|
||||
* @returns {{stdout: string, stderr: string, returnCode: number}}
|
||||
*/
|
||||
async function compile(sslcArgs, wasmBinary, cwd) {
|
||||
const stdout = [];
|
||||
const stderr = [];
|
||||
|
||||
try {
|
||||
const instance = await Module({
|
||||
print: (text) => stdout.push(text),
|
||||
printErr: (text) => stderr.push(text),
|
||||
noInitialRun: true,
|
||||
...(wasmBinary
|
||||
? {
|
||||
wasmBinary,
|
||||
locateFile: (p) => p,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
instance.FS.mkdir("/host");
|
||||
|
||||
const cwdPath = path.parse(cwd || process.cwd());
|
||||
|
||||
// console.info("DEBUG cwd", cwd);
|
||||
|
||||
instance.FS.mount(
|
||||
// Using NODEFS instead of NODERAWFS because
|
||||
// NODERAWFS caused errors when the same module
|
||||
// runs the second time
|
||||
instance.NODEFS,
|
||||
{
|
||||
root: cwdPath.root,
|
||||
},
|
||||
"/host"
|
||||
);
|
||||
|
||||
// console.info("DEBUG after mount");
|
||||
|
||||
instance.FS.chdir(path.join("host", cwdPath.dir, cwdPath.name));
|
||||
|
||||
// console.info("DEBUG after chdir");
|
||||
|
||||
const returnCode = instance.callMain(sslcArgs);
|
||||
|
||||
// console.info("DEBUG after call");
|
||||
|
||||
instance.FS.chdir("/");
|
||||
instance.FS.unmount("/host");
|
||||
|
||||
return {
|
||||
returnCode,
|
||||
stdout: stdout.join("\n"),
|
||||
stderr: stderr.join("\n"),
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
returnCode: 1,
|
||||
stdout: stdout.join("\n"),
|
||||
stderr: stderr.join("\n") + `\nERROR: ${e.name} ${e.message} ${e.stack}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const { stdout, stderr, returnCode } = await compile(process.argv.slice(2));
|
||||
console.log(stdout);
|
||||
if (stderr) {
|
||||
console.error(stderr);
|
||||
}
|
||||
process.exit(returnCode);
|
||||
@@ -348,6 +348,9 @@ There are several changes in this version of sslc which may result in problems f
|
||||
|
||||
### Changelog
|
||||
|
||||
**sfall 4.4.5:**
|
||||
- added Linux & WebAssembly builds
|
||||
|
||||
**sfall 4.4.4:**
|
||||
- fixed stringified procedure names shifting when the same name is called more than once
|
||||
- syntax improvements:
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
#include "gencode.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
extern int shortCircuit;
|
||||
|
||||
static Program *currentProgram;
|
||||
@@ -867,7 +871,7 @@ static int writeStatement(NodeList *n, int i, FILE *f) {
|
||||
return i+1;
|
||||
}
|
||||
|
||||
static int writeBlock(NodeList *n, int i, FILE *f) {
|
||||
extern int writeBlock(NodeList *n, int i, FILE *f) {
|
||||
if (n->nodes[i].token != T_BEGIN)
|
||||
parseError("begin expected");
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include "parselib.h"
|
||||
#include "extra.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
LexData lexData;
|
||||
static char *tokens[256+T_END_TOKEN];
|
||||
static struct {
|
||||
|
||||
@@ -14,7 +14,6 @@ typedef struct {
|
||||
} LexData;
|
||||
|
||||
extern LexData lexData;
|
||||
extern char *tokens[];
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@
|
||||
* are placed here.
|
||||
*/
|
||||
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
|
||||
static int do_if( int hash, const char * directive_name);
|
||||
/* #if, #elif, #ifdef, #ifndef */
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@
|
||||
* Some routines are used also to evaluate the value of numerical tokens.
|
||||
*/
|
||||
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef struct optab {
|
||||
char op; /* Operator */
|
||||
|
||||
+2
-2
@@ -37,8 +37,8 @@
|
||||
#if PREPROCESSED
|
||||
#include "mcpp.H"
|
||||
#else
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
#endif
|
||||
|
||||
#define ARG_ERROR (-255)
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@
|
||||
* The post-preprocessing routines are also placed here.
|
||||
*/
|
||||
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* Function pointer to expand_macro() functions. */
|
||||
char * (*expand_macro)( DEFBUF * defp, char * out, char * out_end
|
||||
|
||||
+2
-2
@@ -70,8 +70,8 @@
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
|
||||
static void scan_id( int c);
|
||||
/* Scan an identifier */
|
||||
|
||||
+13
-3
@@ -36,10 +36,15 @@
|
||||
* 1. specify the constants in "configed.H" or "noconfig.H",
|
||||
* 2. append the system-dependent routines in this file.
|
||||
*/
|
||||
#include "system.H"
|
||||
#include "internal.H"
|
||||
#include "system.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
#include "direct.h"
|
||||
#define getcwd( buf, size) _getcwd( buf, size)
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h" /* For stat() */
|
||||
@@ -47,8 +52,13 @@
|
||||
#define S_ISREG( mode) (mode & S_IFREG)
|
||||
#define S_ISDIR( mode) (mode & S_IFDIR)
|
||||
#endif
|
||||
#if ! defined (S_IFREG)
|
||||
#define S_IFREG _S_IFREG
|
||||
#endif
|
||||
#if ! defined (S_IFDIR)
|
||||
#define S_IFDIR _S_IFDIR
|
||||
#endif
|
||||
|
||||
#define stat( path, stbuf) _stat( path, stbuf)
|
||||
|
||||
/* Function to compare path-list */
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define Protect(a) if (_stricmp(c, a) == 0) return 1;
|
||||
|
||||
#define F_OP(token,op) case token: out->floatData = fd1 op fd2; break;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "lex.h"
|
||||
#include "parseext.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "compat.h"
|
||||
#endif
|
||||
|
||||
int compilerErrorTotal;
|
||||
char compilerSyntaxError;
|
||||
|
||||
@@ -58,7 +62,8 @@ int expressionNesting = 0;
|
||||
static void freeVariableList(VariableList *v);
|
||||
static void freeVariable(Variable *v);
|
||||
static void parseWhile(Procedure *p, NodeList *n);
|
||||
static int writeBlock(NodeList *n, int i, FILE *f);
|
||||
static int variable(VariableList *v, char **names, int type, char allowArrays, int allowMulti);
|
||||
extern int writeBlock(NodeList *n, int i, FILE *f);
|
||||
|
||||
extern FILE* parseroutput;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parse.h"
|
||||
#include "parselib.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user