Closed jounathaen closed 2 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
.
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.
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?
Well, It is basically a GCC 6.3
and it does support _Complex
as well as --std=c99
config.log says that the compiler couldn’t find long double _Complex
. Can you try that out?
Oh, and I already specified --disable-fortran
for the config.log
I attached previously
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.
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.
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
?
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.
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?
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...
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?
@pavanbalaji I'll take a look.
Documenting my understanding:
For cross-compiling, always specify --build=xxx --host=xxx
explicitly. Failing to do so, configure
will try to run a test program which will fail to yield the correct datatype size. I agree with @jounathaen that the error message is rather misleading; but on the other hand, the configure tests can fail in myriad mysterious ways including even when user is specifying the correct --build
and --host
. While it is possible to add more checks to provide better error messages, it may not be worthwhile.
In cross-compiling mode, Autoconf's ability to check data type size is limited. It tries to compile the following statement:
static int test_array [ 1 - 2 * !((sizeof(TYPE)) <= N) ];
varying N for upper bound or lower bound until a fixed value. It relys on compiler throw error for int array[-1]
. Obviously, it is much more straight forward to directly compile and run a test program.
FORTRAN, being a higher-level language, does not provide any means to yield storage size directly.
** If not cross-compiling, confdb/aclocal_f77.m4
achieves the size check by compile a FORTRAN code and then link with a C program which outputs the data storage size.
** There isn't a (portable) way to check sizes if it's cross-compiling, so one has to provide a cross file (that is what the configure error message trying to say).
** The remedy is to pass-in a cross file using --with-cross=path/to/file
explicitly, or src/cross/$host_alias
implicitly ($host_alias
is the same name as specified in --host=xxx
). It is also possible to specify the file with environment variable MPID_DEFAULT_CROSS_FILE
.
** The cross file is simply a shell script setting varaibles. Any variables inside that file will be sourced
into configure. In particular for cross-compiling FORTRAN, we'll need
CROSS_F77_SIZEOF_INTEGER
CROSS_F77_SIZEOF_REAL
CROSS_F77_SIZEOF_DOUBLE_PRECISION
Most likely, they are 4
, 4
, and 8
, but ultimately they depend on the particular Fortran compiler and platform.
The current way of MPICH
configureing datatype sizes are less than ideal. I have following ideas:
mpi.h.in
, e.g. based on x86_64-linux
. It covers a large base. For the rest odd systems, it may make more sense to ask the user to manually update those values directly in mpi.h
-- it may not be that unpleasant if we document clearly, won't be any more difficult than asking user to create a cross-file.mpi.h.in
into mpi.h
directly. While this is essentially the same as what we do today, it restores the datatype handle logic back to mpi.h
and factors the datatype size checks from configure for better maintainability.limit.h
; also the autoconf compile trick.@hzhou I think you might have misunderstood what I was asking you to look at. Let me clarify that here.
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.
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?
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.
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.
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.
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
...
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 thef77
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 hasc_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).
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.
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:
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 forCROSS_SIZEOF_typename
?Best Regards Jonathan