msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.31k stars 1.23k forks source link

Does LFORTRAN package work? #20009

Open angelog0 opened 9 months ago

angelog0 commented 9 months ago
$ pacman -S --needed mingw-w64-ucrt-x86_64-lfortran
risoluzione delle dipendenze in corso...
ricerca dei pacchetti in conflitto in corso...

Pacchetti (1) mingw-w64-ucrt-x86_64-lfortran-0.31.0-1

Dimensione totale dei pacchetti da scaricare:   16,71 MiB
Dimensione totale dei pacchetti da installare:  57,85 MiB

:: Vuoi procedere con l'installazione? [S/n]
:: Download dei pacchetti in corso...
 mingw-w64-ucrt-x86_64-lfortran-0.31.0-...    16,7 MiB  2,30 MiB/s 00:07 [#######################################] 100%
(1/1) verifica delle chiavi presenti nel portachiavi                     [#######################################] 100%
(1/1) verifica dell'integrità dei pacchetti                              [#######################################] 100%
(1/1) caricamento dei file dei pacchetti                                 [#######################################] 100%
(1/1) controllo dei conflitti in corso                                   [#######################################] 100%
(1/1) controllo dello spazio disponibile sul disco                       [#######################################] 100%
:: Elaborazione delle modifiche al pacchetto...
(1/1) installazione in corso di mingw-w64-ucrt-x86_64-lfortran           [#######################################] 100%

From helloworld.f90

cat helloworld.f90
program hello_world
    implicit none
    write (*, *) 'Hello World!'
end program hello_world

then

user@PC UCRT64: ~
$ lfortran helloworld.f90
"clang" non è riconosciuto come comando interno o esterno,
 un programma eseguibile o un file batch.
The command 'clang -o helloworld.out helloworld.out.tmp.o  -L"C:\msys64\ucrt64\bin/../lib" -Wl,-rpath,"C:\msys64\ucrt64\bin/../lib" -llfortran_runtime -lm' failed.

The same running lfortran -o hw helloworld.f90. If it needs clang, why is this package not installed as dependency?

With other real example it produces Segment fault. But this could be matter of another bug report..

Windows Version

MINGW64_NT-10.0-19045

MINGW environments affected

lazka commented 9 months ago

@zoziha ^

MehdiChinoune commented 9 months ago

Installing clang doesn't fix the issue. I still get this error:

$ lfortran.exe main.f90
'.' is not recognized as an internal or external command,
operable program or batch file.
zoziha commented 9 months ago

The same running lfortran -o hw helloworld.f90. If it needs clang, why is this package not installed as dependency?

Sorry, I didn't verify this, lfortran does rely on clang to generate binaries and should make clang a dependency of lfortran.

Installing clang doesn't fix the issue.

This may have something to do with the current design of lfortran, @certik. I was able to successfully generate and run the binary using the following command:

$ lfortran main.f90 -o ./a
$ ./a
Hello World!
certik commented 9 months ago

LFortran currently requires either Clang or GCC to do the linking. We'll eventually remove this dependency, but right now that's what's needed.

lfortran.exe main.f90

Should work, it compiles it to a binary and runs it. Something goes wrong, so it needs to be debugged. Can you please report it into our issue tracker and give as many details so that we can reproduce it?

angelog0 commented 9 months ago

@zoziha wrote:

I was able to successfully generate and run the binary using the following command:

$ lfortran main.f90 -o ./a $ ./a Hello World!

instead here it produces:

$ lfortran.exe helloworld.f90 -o ./a
"clang" non è riconosciuto come comando interno o esterno,
 un programma eseguibile o un file batch.
The command 'clang -o ./a ./a.tmp.o  -L"C:\msys64\ucrt64\bin/../lib" -Wl,-rpath,"C:\msys64\ucrt64\bin/../lib" -llfortran_runtime -lm' failed.

Are you going to fix this? Otherwise I do not see reasons to continue to have this package installed on my systems...

certik commented 9 months ago

@angelog0 can you install clang using msys2 and see if it fixes the problem?

zoziha commented 9 months ago

@certik mingw64-lfortran runs under bash, powershell, and other Windows OS shell environments:

$ lfortran main.f90 -v
clang -o main.out main.out.tmp.o  -L"C:\msys64\mingw64\bin/../lib" -Wl,-rpath,"C:\msys64\mingw64\bin/../lib" -llfortran_runtime -lm
'.' is not recognized as an internal or external command,
operable program or batch file.

$ lfortran main.f90 -v && ./main.out
clang -o main.out main.out.tmp.o  -L"C:\msys64\mingw64\bin/../lib" -Wl,-rpath,"C:\msys64\mingw64\bin/../lib" -llfortran_runtime -lm
'.' is not recognized as an internal or external command,
operable program or batch file.

$ lfortran main.f90 -o main.out -v
clang -o main.out main.out.tmp.o  -L"C:\msys64\mingw64\bin/../lib" -Wl,-rpath,"C:\msys64\mingw64\bin/../lib" -llfortran_runtime -lm

$ lfortran main.f90 -o main.out -v && ./main.out
clang -o main.out main.out.tmp.o  -L"C:\msys64\mingw64\bin/../lib" -Wl,-rpath,"C:\msys64\mingw64\bin/../lib" -llfortran_runtime -lm
Hello World!

It seems that the lfortran main.f90 command needs to be traced to a specific execution logic, possibly where lfortran runs a command-line statement with the "." character.

angelog0 commented 9 months ago

@certik

can you install clang using msys2 and see if it fixes the problem?

As @MehdiChinoune wrote it does not fix the issue and I would a clean installation of lfortran on MSYS2/UCRT64 so that it works OB.

Let's see how it works the merge of @zoziha (At the moment the package is not yet upgraded on the MSYS2 repos).

certik commented 9 months ago

I think the problem is right here: https://github.com/lfortran/lfortran/blob/6960d71567fded9ae071f7691bd1db2fe67b943c/src/bin/lfortran.cpp#L1739

You can see the logic:

    std::string run_cmd = "";
    if (backend == Backend::wasm) {
        // for node version less than 16, we need to also provide flag --experimental-wasm-bigint
        run_cmd = "node --experimental-wasi-unstable-preview1 " + outfile + ".js";
    } else if (t == "x86_64-pc-windows-msvc") {
        run_cmd = outfile;
    } else {
        run_cmd = "./" + outfile;
    }
    int err = system(run_cmd.c_str());

It uses just the name of the executable on Windows if the target is x86_64-pc-windows-msvc, otherwise it uses ./ and name.

And I think when ./ is used on your system it fails.

@angelog0 or @zoziha can you please show the output of lfortran --version on this system? For example for me I get:

$ lfortran --version
LFortran version: 0.33.1-302-ga1ce97de6
Platform: macOS ARM
Default target: arm64-apple-darwin21.3.0

This will print the target, and I bet it is not x86_64-pc-windows-msvc. That will explain it, and then we just need to add your target name into the if statement above. I reported this at https://github.com/lfortran/lfortran/issues/3424.

MehdiChinoune commented 9 months ago

@certik

$ lfortran --version
LFortran version: 0.33.1
Platform: Windows
Default target: x86_64-w64-windows-gnu
certik commented 9 months ago

On Windows, when do you call a program using a.out and when using ./a.out? Does that depend on the shell? We use the std::system command to launch it.

I wonder if instead of checking for the "target", we should just always not use ./ when platform == Windows. That might be a better default.

angelog0 commented 9 months ago

@certik ,

On Windows, when do you call a program using a.out and when using ./a.out?

we should remember that we are speaking about MSYS2/UCRT64 shell and MSYS2 is a fork from Cygwin which is a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows.

So, we have to start a.out as ./a.out. If you are thinking about CMD, a.out does not work if the PATH does not contains the paths to the needed libs..., and usually this is not the case unless the user setups the correct Windows PATH (mixing Windows and MSYS2 paths could have indesiderate side effects).

angelog0 commented 9 months ago

Also remember that, for example, gfortran helloworld.f90 produces an a.exe executable not an a.out.. You should run gfortran helloworld.f90 -o a.out for that

angelog0 commented 9 months ago

Ok, now I have seen another upgrade for lfortran

mingw-w64-ucrt-x86_64-lfortran 0.33.1-2

It produces the following results:

$ lfortran --version
LFortran version: 0.33.1
Platform: Windows
Default target: x86_64-w64-windows-gnu

$ lfortran.exe helloworld.f90
"." non è riconosciuto come comando interno o esterno,
 un programma eseguibile o un file batch.

the last command produces these files

helloworld.out.tmp.o 
helloworld.out       

and then

$ ./helloworld.out
Hello World!

instead

$ lfortran.exe helloworld.f90  -o helloworld  ## no errors/warnings

$ ls helloworld.*
helloworld.exe  helloworld.f90  helloworld.tmp.o

$ ./helloworld.exe
Hello World!
angelog0 commented 9 months ago

I tried some more complicated example but it systematically segments fault. For example:

$ cat pi_greco_mc.0.f90

program pi_greco
  implicit none

  integer, parameter :: DP = selected_real_kind(15,307)

  integer :: i, n, n1, n2
  real(DP) :: u(3), pig1, pig2

  write(*,'(a)',advance='no') 'Number of points to be generated: '
  read(*,*) n

  n1 = 0
  n2 = 0
  do i = 1, n
     call random_number(u)
     if ((u(1)*u(1)+u(2)*u(2)) <= 1) n1 = n1+1
     if ((u(1)*u(1)+u(2)*u(2)+u(3)*u(3)) <= 1) n2 = n2+1
  end do

  pig1 = (4.0_DP*n1)/n
  pig2 = (6.0_DP*n2)/n

  write(*,*) 'PIG1 = ', pig1
  write(*,*) 'PIG2 = ', pig2

end program pi_greco

$ lfortran pi_greco_mc.f90 -o pi_greco_mc.out
Segmentation fault
certik commented 9 months ago

@angelog0 you discovered two bugs:

Remember that LFortran is in alpha, so it is expected that things will break when you try it and you will find bugs. However usually it's quite easy to workaround the bugs, in this case:

program pi_greco
  implicit none

  !integer, parameter :: DP = selected_real_kind(15,307)
  integer, parameter :: DP = kind(0.d0)

  integer :: i, n, n1, n2
  real(DP) :: u(3), pig1, pig2

  !write(*,'(a)',advance='no') 'Number of points to be generated: '
  !read(*,*) n
  n = 10000

  n1 = 0
  n2 = 0
  do i = 1, n
     call random_number(u)
     if ((u(1)*u(1)+u(2)*u(2)) <= 1) n1 = n1+1
     if ((u(1)*u(1)+u(2)*u(2)+u(3)*u(3)) <= 1) n2 = n2+1
  end do

  pig1 = (4.0_DP*n1)/n
  pig2 = (6.0_DP*n2)/n

  write(*,*) 'PIG1 = ', pig1
  write(*,*) 'PIG2 = ', pig2

end program pi_greco

This gives:

$ lfortran a.f90 
PIG1 =  3.15799999999999992e+00
PIG2 =  3.14279999999999982e+00
angelog0 commented 9 months ago

@certik

Remember that LFortran is in alpha, so it is expected that things will break when you try it and you will find bugs

Yes, I know...

However usually it's quite easy to workaround the bugs, in this case:

that was just the simplest between my old programs which produced the Segment fault