pmodels / mpich

Official MPICH Repository
http://www.mpich.org
Other
565 stars 279 forks source link

How to generate cross-file #3753

Closed jounathaen closed 2 years ago

jounathaen commented 5 years ago

Hi,

I wan't to port MPICH to a exotic system. Unfortunately the configure script does not detect all SIZEOF define values correctly.

The script gives me the following output:

configure: error: Configure was unable to determine the size of short ; if cross compiling,
use the environment variables CROSS_SIZEOF_typename, e.g., CROSS_SIZEOF_SHORT,
or use the --with-cross=file configure option to specify a file containing
Bourne (sh) shell assignments to CROSS_SIZEOF_typename for all datatype
types.  The program maint/getcross.c can be compiled and run on the target
system; this program outputs an appropriate file for the --with-cross option

Using the maint/getcross.c program sounds fantastic, but I can't find the source!

So: Where can I find the source of maint/getcross.c? Or: How does a crossfile look like? What are possible candidates for CROSS_SIZEOF_typename?

Best Regards Jonathan

pavanbalaji commented 5 years ago

Can you send the config.log that you are seeing? Let's first get the C version working (let's --disable-fortran for now). For the C version, you don't need any cross file and configure should be able to detect everything, unless there's a bug in our configure.ac.

jounathaen commented 5 years ago

Hi, Thanks for your quick reply. Here is the log file. config.log However, I managed to write some kind of cross file and get through the configure part, but when I call make afterwards, not all sizes are set. Therefore, It would be most helpful to know how the cross-file should look like.

Besides this, if the getcross.c file is not existing in the repository anymore, maybe the error message should be adapted.

pavanbalaji commented 5 years ago

Please let's work on C first. That's easier and doesn't need a cross file. It'll make it easier for us to debug the problem. Pass --disable-fortran to your configure, so we only have to deal with C for now.

Does your compiler not support _Complex? Is it not a C99 compiler?

jounathaen commented 5 years ago

Well, It is basically a GCC 6.3 and it does support _Complex as well as --std=c99

pavanbalaji commented 5 years ago

config.log says that the compiler couldn’t find long double _Complex. Can you try that out?

jounathaen commented 5 years ago

Oh, and I already specified --disable-fortran for the config.log I attached previously

jounathaen commented 5 years ago

Something like

volatile long double _Complex mycdouble = 12.3;
mycdouble++;
printf("test %d\n", mycdouble);

Compiles and runs without any problems. It has to be added, that you can't just run the output files on the compiling machine. They need to be run inside a VM for example.

pavanbalaji commented 5 years ago

I understand. AC_CHECK_SIZEOF is not supposed to run anything, at least with newer autoconfs. We went through this change a few years ago because AC_CHECK_SIZEOF became smart enough to do a weird trick by compiling arrays with sizes based on sizeof, which is a compile-time check to find the actual size. But I see in the config.log that it still is running ./conftest, which is very weird.

I'll dig a bit deeper into this and get back to you.

pavanbalaji commented 5 years ago

It looks like AC_CHECK_SIZEOF does a compile-only check only when cross-compilation is enabled. Otherwise it does a runtime check. I'd have preferred that it always do a compile-only check, but that's what autoconf gives.

Anyway, in your case, it looks like configure is not able to detect that it's a cross compilation. Can you try setting --host and --build instead of --target?

jounathaen commented 5 years ago

First: Thanks for your help and time 👍 ❤️

./configure --disable-fortran --host=x86_64-hermit --enable-static=true --with-pm="none"  --prefix=/XXX
[...]
checking for long double _Complex... yes
configure: error: Configure was unable to determine the size of short ; if cross compiling,
use the environment variables CROSS_SIZEOF_typename, e.g., CROSS_SIZEOF_SHORT,
[...]

Did not find the correct build. However, specifying both variables resulted in a successful configure run. ./configure --disable-fortran --host=x86_64-hermit --build=x86_64-linux-gnu --enable-static=true --with-pm=none --prefix=/XXX

Thank you very much!

I'd still suggest to add some documentation on this topic and maybe update the configure messages regarding the cross-file, but my problem is fixed.

You can close this issue if there is nothing more to add from your side.

pavanbalaji commented 5 years ago

Right. The generated configure script seems to compare host and build before enabling cross compilation. So you need both.

Would you be able to help us debug the Fortran side? That is, not pass --disable-fortran and see if that works fine?

jounathaen commented 5 years ago

Oh, I forgot to click on Comment. Sorry for the long delay.

Ok, without --disable-fortran I get the following error:

configure: error: Unable to configure with Fortran support because configure could notdetermine the size of a Fortran INTEGER. Consider setting CROSS_F77_SIZEOF_INTEGER tothe length in bytes of a Fortran INTEGER

But I cannot really tell you anything about the Fortran support of that compiler...

pavanbalaji commented 5 years ago

Thanks. We do have a script to generate the Fortran cross file, but it's unnecessarily complex. See maint/fcrosscompile. Perhaps we could simplify it. We should also update the README to add these instructions.

I think the only person in the group who knows Fortran to any reasonable level is @hzhou. Hui, can you help?

hzhou commented 5 years ago

@pavanbalaji I'll take a look.

hzhou commented 5 years ago

Documenting my understanding:

hzhou commented 5 years ago

The current way of MPICH configureing datatype sizes are less than ideal. I have following ideas:

pavanbalaji commented 5 years ago

@hzhou I think you might have misunderstood what I was asking you to look at. Let me clarify that here.

  1. The compilation for the C/C++ pieces works fine today in MPICH. The compiler autodetects the sizes of the variables and fills them in. This probably needs some documentation in the README to say that --host and --build are needed, but I don't think we need any code changes.

  2. The Fortran piece doesn't work correctly today. I'm not a Fortran expert, but I believe such compile-time detection of sizes, similar to what we do in C, is not possible in Fortran. Configure needs a cross file to get this. However, we do not have an easy way for the user to generate the cross file. What I was hoping was that you could create a simple Fortran program, which calculates the sizes that we need and prints them. Then we can ask the user to compile this simple Fortran program with the cross compiler, run it on the target machine and copy the output into the cross file. Once that's done, configure can use this cross file and build correctly.

Thoughts?

hzhou commented 5 years ago

That can be done too. We could use the same mechanism as in aclocal_f77: link the Fortran code with C, and have C output that file. But either way, we will need ask user manually compile and manually run and then manually re run configure -- just to set 3 environment variables. It may appear simpler we just ask user to find out those values -- guess or check on their own -- and then set them via environment or cross file.

pavanbalaji commented 5 years ago

That can be done too. We could use the same mechanism as in aclocal_f77: link the Fortran code with C, and have C output that file. But either way, we will need ask user manually compile and manually run and then manually re run configure -- just to set 3 environment variables. It may appear simpler we just ask user to find out those values -- guess or check on their own -- and then set them via environment or cross file.

Users can manually enter them too, if they like. But having a program check them is generally more accurate. Is it just 3 variables? I thought there were some Fortran 90 variables too.

jounathaen commented 5 years ago

My initial question was aiming for a documentation of all those environment variables (C and fortran)😉. A script to generate them is nice, but knowing the variables as fallback solution would be helpful too.

hzhou commented 5 years ago

Is it just 3 variables? I thought there were some Fortran 90 variables too.

I only documented what I read from configure.ac, and only the f77 section. I'll read more and run some tests later.

But having a program check them is generally more accurate.

Certainly. But if we ask the user having to manually run the program in the host system, it doesn't really help much. In cross compiling situation, the host is often not easily accessible.

I think it is possible to develop scripts that directly parse the binary format (ELF etc.), or maybe ask CC to dump assembly output. That way we can do the tests without running it in the host. It won't be universal, but it can cover a large portion of situations.

PS: it seems SIZEOF is available in Fortran as a gnu extension. And Fortran 2008 has c_sizeof...

pavanbalaji commented 5 years ago

Is it just 3 variables? I thought there were some Fortran 90 variables too.

I only documented what I read from configure.ac, and only the f77 section. I'll read more and run some tests later.

Thanks.

But having a program check them is generally more accurate.

Certainly. But if we ask the user having to manually run the program in the host system, it doesn't really help much. In cross compiling situation, the host is often not easily accessible.

I think it is possible to develop scripts that directly parse the binary format (ELF etc.), or maybe ask CC to dump assembly output. That way we can do the tests without running it in the host. It won't be universal, but it can cover a large portion of situations.

PS: it seems SIZEOF is available in Fortran as a gnu extension. And Fortran 2008 has c_sizeof...

I agree that we can have multiple options to check for these, as long as those options are reliable. That is, they should either give the correct value or "unknown", but not an incorrect value. If we can autodetect it even in some cases, that'd be a win. In the cases where we cannot autodetect, we can ask the user to provide the cross file (either hand-written or by running the program that we give them on the target machine).

hzhou commented 5 years ago

For the compilers that support -S, we can simply declare global variables of given type and look for assembly output. It is fast, compile only, and reliable (if available). F77 does not really support global variables, so it is difficult; but assume most FORTRAN compilers should support F90, we could use MODULE and it is equally easy and reliable.

For this to work, we need to look out for compilers that do not use/support binutils assembly and FORTRAN compilers that only support F77. Linux, FreeBSD, mac os X are covered. Microsoft cl uses /FA flag and different syntax, but easily workable if needed.

EDIT: I believe this solution will cover all current cases.