diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 849157c..4adae23 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: Test on: push: - branches: [ master ] + branches: [ master, msvc-detect ] pull_request_target: branches: [ master ] @@ -39,7 +39,7 @@ jobs: name: Build and test on Windows strategy: matrix: - os: [ windows-2022 ] + os: [ windows-2022, windows-2019 ] janet-version: [ 1.36.0 ] runs-on: ${{ matrix.os }} steps: @@ -55,7 +55,7 @@ jobs: - name: Build Spork shell: cmd run: | - refreshenv & "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 & cd spork & janet -l ./bundle -e "(do (setdyn :verbose true) (build))" + refreshenv & cd spork & janet -l ./bundle -e "(do (setdyn :verbose true) (build))" - name: Test Install shell: cmd run: | diff --git a/bundle/init.janet b/bundle/init.janet index e70d66f..cc63405 100644 --- a/bundle/init.janet +++ b/bundle/init.janet @@ -51,6 +51,8 @@ cc/compile-and-make-archive)) (when (= :windows (os/which)) + (cc/msvc-find) + (assert (cc/msvc-setup?)) (setdyn cc/*msvc-libs* @[(cc/msvc-janet-import-lib)])) (defn make1 diff --git a/spork/cc.janet b/spork/cc.janet index ff25c94..2b600b2 100644 --- a/spork/cc.janet +++ b/spork/cc.janet @@ -305,6 +305,50 @@ ### - more testing ### - libraries +(def- tag "AAABBBAAABBBCCCAAABBBAAACCC") +(def- vcvars-grammar + (peg/compile + ~{:main (* (thru ,tag) (any :line)) + :line (group (* :key "=" :value :s*)) + :key '(to "=") + :value '(to "\n")})) + +(defn msvc-setup? + "Check if MSVC environment is already setup." + [] + (and + (os/getenv "INCLUDE") + (os/getenv "LIB") + (os/getenv "LIBPATH"))) + +(defn msvc-find + "Find vcvarsall.bat and run it to setup the current environment for building. + Optionally pass in `year` and `edition` to help look for vcvars. + Only supports VS 2017, 2019, and 2022. + Will set environment variables such that invocations of cl.exe, link.exe, etc. + will work as expected." + [] + (when (msvc-setup?) (break)) + (def arch (string (os/arch))) + (defn loc [y e] + (string `C:\Program Files\Microsoft Visual Studio\` y `\` e `\VC\Auxiliary\Build\vcvarsall.bat`)) + (var found-path nil) + (loop [y :in [2022 2019 2017] + e :in ["Enterprise" "Professional" "Community" "BuildTools"]] + (def path (loc y e)) + (when (os/stat path :mode) + (set found-path path) + (break))) + (unless found-path (error "Could not find vcvarsall.bat")) + (def arg (string `"` found-path `" ` arch ` && echo ` tag ` && set`)) + (def output (sh/exec-slurp "cmd" "/s" "/c" arg)) + (def parsed-block (last (string/split tag output))) + (def kvpairs (peg/match vcvars-grammar parsed-block)) + (assert kvpairs) + (each [k v] kvpairs + (os/setenv (string/trim k) (string/trim v))) + nil) + (defn- msvc-opt [] (case (build-type)