Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fill in LFortran options into the compilers table #544

Closed
wants to merge 1 commit into from

Conversation

certik
Copy link
Member

@certik certik commented Aug 22, 2021

I put in options that I'll implement in LFortran or that are already implemented.

@certik
Copy link
Member Author

certik commented Aug 22, 2021

@awvwgk would you have time to then update fpm to use lfortran correctly using these options? I looked how fpm uses gfortran to compile an example project and created an analogous script using lfortran, attached below. It seems to just work.

#!/bin/bash

set -ex

#FC=gfortran
FC=lfortran

mkdir -p build/dependencies
mkdir -p build/gfortran_2A42023B310FA28D/default_new_project
$FC -c test/check.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project  -o build/gfortran_2A42023B310FA28D/default_new_project/test_check.f90.o
$FC -c ././src/default_new_project.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project  -o build/gfortran_2A42023B310FA28D/default_new_project/src_default_new_project.f90.o
ar -rs build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a build/gfortran_2A42023B310FA28D/default_new_project/src_default_new_project.f90.o
$FC -c app/main.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project  -o build/gfortran_2A42023B310FA28D/default_new_project/app_main.f90.o
mkdir -p build/gfortran_2A42023B310FA28D/app/
$FC -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project  build/gfortran_2A42023B310FA28D/default_new_project/app_main.f90.o build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a -o build/gfortran_2A42023B310FA28D/app/default_new_project
mkdir -p build/gfortran_2A42023B310FA28D/test/
$FC -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project  build/gfortran_2A42023B310FA28D/default_new_project/test_check.f90.o build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a -o build/gfortran_2A42023B310FA28D/test/check

Here is the output for me:

$ ./a.sh 
+ FC=lfortran
+ mkdir -p build/dependencies
+ mkdir -p build/gfortran_2A42023B310FA28D/default_new_project
+ lfortran -c test/check.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project -o build/gfortran_2A42023B310FA28D/default_new_project/test_check.f90.o
+ lfortran -c ././src/default_new_project.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project -o build/gfortran_2A42023B310FA28D/default_new_project/src_default_new_project.f90.o
+ ar -rs build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a build/gfortran_2A42023B310FA28D/default_new_project/src_default_new_project.f90.o
ar: creating archive build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a
/Library/Developer/CommandLineTools/usr/bin/ranlib: file: build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a(src_default_new_project.f90.o) has no symbols
warning: /Library/Developer/CommandLineTools/usr/bin/ranlib: archive library: build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a the table of contents is empty (no object file members in the library define global symbols)
+ lfortran -c app/main.f90 -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project -o build/gfortran_2A42023B310FA28D/default_new_project/app_main.f90.o
+ mkdir -p build/gfortran_2A42023B310FA28D/app/
+ lfortran -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project build/gfortran_2A42023B310FA28D/default_new_project/app_main.f90.o build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a -o build/gfortran_2A42023B310FA28D/app/default_new_project
+ mkdir -p build/gfortran_2A42023B310FA28D/test/
+ lfortran -J build/gfortran_2A42023B310FA28D/default_new_project -I build/gfortran_2A42023B310FA28D/default_new_project build/gfortran_2A42023B310FA28D/default_new_project/test_check.f90.o build/gfortran_2A42023B310FA28D/default_new_project/libdefault_new_project.a -o build/gfortran_2A42023B310FA28D/test/check

The two executables work

$ build/gfortran_2A42023B310FA28D/app/default_new_project 
Hello, default_new_project!
$ build/gfortran_2A42023B310FA28D/test/check             
Put some tests in here!

The warning about the object files comes from the fact that LFortran currently creates empty object files and stores the code in mod files and only when the final executable is compiled it actually compiles everything. We'll eventually add a mode to compile file by file also. From fpm's perspective this is minor. Also the -J and -I options currently are a no-op in LFortran, so it puts the .mod file in the current directory (and also finds them there), see lfortran!1265. That will also get fixed.

@awvwgk
Copy link
Member

awvwgk commented Aug 23, 2021

Done in #527, just checked with 0.12.0 but this doesn't work yet. Guess I have to compile from source, i.e. downgrade my LLVM installation first.

@certik
Copy link
Member Author

certik commented Aug 23, 2021

Thanks! I can test fpm or your PR myself to see if it works. I didn't see any change of options for lfortran in #537. The main one is the -module option that LFortran does not support.

@certik
Copy link
Member Author

certik commented Aug 23, 2021

I see the change in 937b87e, but it doesn't seem to be part of any PR.

Btw, what compatibility does there have to be between a C compiler and a Fortran compiler? LFortran seems to work with any C compiler. I know on Windows one has to generate object files that are compatible with the MSVC linker, which I think GFortran does not. Apart from that, is there any other issue?

@awvwgk
Copy link
Member

awvwgk commented Aug 23, 2021

The commit is part of #527.

Actually, I don't think we need any compatibility between C and Fortran, except for the guarantee of a compatible C ABI between the C and the Fortran compiler in case of iso_c_binding usage. Therefore, for all Fortran compilers any C compiler should do. Linking is a different story, we rely on the Fortran compiler to correctly wrap the platform linker.

@certik
Copy link
Member Author

certik commented Aug 23, 2021

I struggled with C ABI for complex numbers, but got it working on Linux and macOS: https://gitlab.com/lfortran/lfortran/-/issues/528. I still didn't get it working on Windows. Linking the MSVC compiled C and LFortran compiled Fortran works for everything except the complex types passed by value. I am aware of https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention and LLVM code generation automatically implements it, but it does not specify how C structs {float,float} and {double,double} are passed by value --- I had to work to get it working on Linux/macOS, and I still need to know what LLVM code to emit to make it work on Windows. If anybody knows that, please let me know.

Second question: I suspect the C ABI is different between MSVC and GCC on Windows?

@certik
Copy link
Member Author

certik commented Aug 25, 2021

and I still need to know what LLVM code to emit to make it work on Windows. If anybody knows that, please let me know.

I figured it out and as of now, LFortran master works well with complex numbers on Windows to and from C. I documented the details in: https://gitlab.com/lfortran/lfortran/-/wikis/Platform-Calling-Conventions-and-ABI

Second question: I suspect the C ABI is different between MSVC and GCC on Windows?

It seems the calling convention might be different. And the object file format is also different. So users would simply choose on a command line which target to generate for: https://gitlab.com/lfortran/lfortran/-/issues/545

@certik
Copy link
Member Author

certik commented Aug 25, 2021

This PR now continues as part of #527.

@certik certik closed this Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants