How to translate bash to .bat

I have a bash script to create a Julia system image. (KiteSimulators.jl/create_sys_image at main · aenarete/KiteSimulators.jl · GitHub)
Now I want to convert it to a .bat file for windows users. How could I translate these lines:

julia_version=$(julia --version | awk '{print($3)}')
julia_major=${julia_version:0:3} 
if test -f "kps-image-${julia_major}.so"; then
    mv bin/kps-image-${julia_major}.so kps-image-${julia_major}.so.bak
fi

Maybe translating to powershell could be easier. I can’t help with either but I’ve heard nice things about it.

A problem here. julia --version on Windows opens the Julia REPL itself instead of printing the version info.

It definitely does not.

then maybe it’s a 1.8beta bug (the one I happen to have in my path)

Works for me (WezTerm running cmd.exe):

C:\Users\ngudat>julia --version

julia version 1.7.2

C:\Users\ngudat>juliabeta --version

julia version 1.8.0-beta3

OK, found out why. I’m calling Julia through a batch file. If I call the exe directly then yes, it prints the version number.

C:\Users\joaqu>C:\programs\julia-1.8\bin\julia.exe --version
julia version 1.8.0-beta3

Already found out how to extract the version number from the version string: How to extract part of a string in Windows batch file? - Super User

I’m calling Julia through a batch file as well (that’s what a .bat is, right?)

Yes.

Yes. I have two scripts, one that creates the system image, and one the starts Julia with the correct parameter to make use of the system image.

But because the system image works only with a specific Julia version I include the version number in the image name. In this way I can switch between different Julia versions and it always loads the correct system image.

I even found a way to test my .bat file on Linux:

wine cmd

Very happy :slight_smile:

Is it possible to install Julia in wine?

Is it the content of the bat file then? Mine is:

@echo off
echo.
C:\Users\ngudat\AppData\Local\Programs\Julia-1.7.2\bin\julia.exe %*

(I have no idea how any of this works, just copy pasted from somewhere on the internet - I believe the %* at the end might be responsible for passing along arguments?)

Yes, likely a lot works, but not all (just keep in mind even, if with superficial testing works, always a possibility not all implemented/tested):

https://github.com/JuliaLang/julia/issues/43566

Note, Julialang has a Wine label, so they want it to work, but as you can see it’s a problem with (upstream) wine, not Julia. It would always be a problem with wine, as it’s responsible for the conversion from Windows API.

Conversely, Linux Julia builds work in WSL [2], and again there might be bugs in Windows WSL, but I find it more likely to work, since they’re not trying to support a huge kernel API, that is a moving target, or rather it is, but they have the Linux kernel so not reimplementing from scratch. I understand Julia under WSL can sometimes be faster tan the native Windows Julia build (but that’s a problem with the Windows API not Julia).

I’ve been copying mine version-after-version and some (all?) of it is no longer necessary but it was at a certain time. This oi what I have

@ echo off

call C:\programs\WPy64-31020\env2.bat

set pato=C:\programs\ImageMagick;C:\MinGW64\msys64\usr\bin;C:\MinGW64\mingw64\bin;
set path=%pato%;%path%

C:\programs\julia-1.8\bin\julia.exe --sysimage-native-code=yes

Indeed. Adding that %* to mine also prints the version number.

1 Like

Finished my translation (fully tested, but only works if your package is registered):

@echo off
REM This script creates a julia system image with a name that
REM contains the Julia version, e.g. kps-image-1.7.dll
REM It should be placed in the bin folder of the project.
REM It assumes that the following files exist:
REM test/update_packages.jl
REM test/create_sys_image.jl

REM determine basename of current directory
for /F "delims=" %%i in ("%cd%") do set basename=%%~ni

if %basename%==bin cd ..
for /f "delims=" %%i in ('julia --version') do set version_string=%%i
for /f "tokens=3 delims= " %%a in ("%version_string%") do set version=%%a

set julia_major=%version:~0,3%
set image=kps-image-%julia_major%.dll

IF EXIST "bin/%image%" (
  move bin/kps-image-%julia_major%.dll bin/kps-image-%julia_major%.so.bak
)

echo Updating packages...
if EXIST "Manifest.toml" (
    move Manifest.toml Manifest.toml.bak
)

julia --project -e "include(\"./test/update_packages.jl\");"
julia --project -e "using Pkg; Pkg.precompile()"
julia --project -e "include(\"./test/create_sys_image.jl\");"
move kps-image_tmp.so bin/kps-image-%julia_major%.dll
julia --project -e "using Pkg; Pkg.precompile()"
1 Like

Why not write the script in Julia? Then it can be portable to Windows, and you don’t need a second (or third) language.

I thought about it, but I also need a script to launch Julia in the first place, so I also need to rewrite this bash script:

#!/bin/bash
if [[ $(basename $(pwd)) == "bin" ]]; then
    cd ..
fi

julia_version=$(julia --version | awk '{print($3)}')
julia_major=${julia_version:0:3}

export EDITOR="gedit"

if test -f "bin/kps-image-${julia_major}.so"; then
    echo "Found system image!"
    julia -J  bin/kps-image-${julia_major}.so -t 1 --project
else
    julia --project
fi

And if I would replace this script with a Julia script, I guess latency and memory consumption would be significantly higher.

Finally, you cannot fully replace bash or bat or whatever scripts to start Julia itself because if you want to start Julia with parameters you need a script. This would become unnecessary only if Julia

  • would allow to use a config file to configure the launch options
  • and Julia would be able to load a version specific system image automatically

Here the translation of the run_julia script to .bat for Windows users:

@echo off
REM This script launches julia and loads a version specific
REM system image from the folder bin if it exists.
REM The name of the system image must be similar to
REM kps-image-1.7.dll
REM It launches julia with one thread.

REM determine basename of current directory
for /F "delims=" %%i in ("%cd%") do set basename=%%~ni

if %basename%==bin cd ..
for /f "delims=" %%i in ('julia --version') do set version_string=%%i
for /f "tokens=3 delims= " %%a in ("%version_string%") do set version=%%a

set julia_major=%version:~0,3%
set image=kps-image-%julia_major%.dll

set EDITOR="code"

IF EXIST "bin/%image%" (
    echo Found system image!
    julia -J  bin/kps-image-%julia_major%.so -t 1 --project
) else julia --project

tested! :slight_smile:

Why is that easier than just running a Julia script (which can launch additional Julia processes as needed, see below)?

Surely any differences here are negligible compared to the cost of creating a system image.

Sure you can:

julia> run(`$(joinpath(Sys.BINDIR, Sys.iswindows() ? "julia.exe" : "julia")) --version`)
julia version 1.7.1
Process(`/Applications/Julia-1.7.app/Contents/Resources/julia/bin/julia --version`, ProcessExited(0))

You can literally do everything in Julia that you would do in a shell script (except more easily and portably), including launching additional julia processes, with the added advantage that Julia knows its own path.