10000 AX_C_FLOAT_WORDS_BIGENDIAN: fix bug with Emscripten target by hoodmane · Pull Request #316 · autoconf-archive/autoconf-archive · GitHub
[go: up one dir, main page]

Skip to content

AX_C_FLOAT_WORDS_BIGENDIAN: fix bug with Emscripten target #316

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

Merged
merged 1 commit into from
Nov 9, 2024

Conversation

hoodmane
Copy link
Contributor
@hoodmane hoodmane commented Oct 31, 2024

Commit 23be7cc "Fix AX_C_FLOAT_WORDS_BIGENDIAN fails whenever interprocedural optimization is enabled." introduced a regression on the Emscripten target because it switched from grepping the object file where the float definitely will live, to grepping aclocal$EXEEXT which in the case of Emscripten will be aclocal.js but the float is in aclocal.wasm. This problem is unique to Emscripten, it is not present on any other webassembly platform.

To fix, grep conftest* for the float.

@hoodmane
Copy link
Contributor Author
hoodmane commented 10000 Oct 31, 2024

cc @damelang @erlend-aasland @peti

ax_cv_c_float_words_bigendian=yes
fi
if grep seesnoon conftest$EXEEXT >/dev/null ; then
if grep seesnoon conftest$TOINSPECTEXT >/dev/null ; then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does .wasm come from? Other Autoconf checks normally use conftest$ac_exeext or conftest$ac_ext. I believe that using one of these would be a better fix rather than special casing Emscripten in one in a multitude of Autoconf macros.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well what about falling back to the original check on the object file in that case?

Copy link
Contributor Author
@hoodmane hoodmane Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I added a second approach in 1402d85, but left the first option in aa8ea4c. A third option would be to hard code it:

AS_CASE([${host}],
  [*emscripten*], [ax_cv_c_float_words_bigendian=no]
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does .wasm come from?

Good question. My guess is that somewhere, someone decided that for Emscripten, the js file produced is the "executable" and the wasm file produced is the "object". Thus EXEEXT is ".js" and ac_objext is "wasm". If true, that design decision is the source of the problem here.

I, personally, would have considered the wasm file to be the executable, and the js file to be something different and perhaps unique to Emscripten, as a wrapper file or what not. Maybe there is some precedent already for similar targets that include a wrapper-ish file in the output, that Emscripten could have used. Anyway, if things had gone this way, EXEEXT would have been ".wasm" instead of ".js", the macro would have worked just fine as it is, this issue would not have come up, and all of us would have been spared some time and effort.

Alas, as things stand, we have this weird situation where, for Emscriptem only, AC_LINK_IFELSE apparently produces an object file along with an "executable", instead of just an executable. (Which might even be in counter to the documentation, perhaps.)

If I'm following things right (it is late for me), for Emscripten targets, this macro "needs" to look at conftest.$ac_object, which is conftest.wasm. But for everything else, it needs to look at conftest$EXEEXT.

I suggest a very simple fix: change the grep test to:

grep seesnoon conftest* >/dev/null

'cuz really...does anyone think that we'll get a false positive from some stray file that begins with conftest? IOW, that "seesnoon" or "noonsees" is found in some file not intended for this test, but does have a name that starts with conftest?

But in case that's too sloppy, we could do something a little more careful, like:

TESTFILES="conftest$EXEEXT $( [ -e conftest.$ac_objext ] && echo conftest.$ac_objext)"

and then:

grep seesnoon $TESTFILES ...

Make sense?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest a very simple fix: change the grep test to:

grep seesnoon conftest* >/dev/null

'cuz really...does anyone think that we'll get a false positive from some stray file that begins with conftest? IOW, that "seesnoon" or "noonsees" is found in some file not intended for this test, but does have a name that starts with conftest?

I agree with you that this is probably good enough.

But in case that's too sloppy, we could do something a little more careful, like:

TESTFILES="conftest$EXEEXT $( [ -e conftest.$ac_objext ] && echo conftest.$ac_objext)"

and then:

grep seesnoon $TESTFILES ...

Make sense?

Yes; and that extra carefulness does not add significant complexity, so it seems to be the best solution.

Copy link
Contributor Author
@hoodmane hoodmane Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TESTFILES="conftest$EXEEXT $( [ -e conftest.$ac_objext ] && echo conftest.$ac_objext)"

This would not work because conftest.$ac_objext is conftest.o which does not exist if you run AC_LINK_IFELSE, that only makes conftest.js and conftest.wasm. To make conftest.o you need to also run AC_COMPILE_IFELSE and then you end up with something pretty similar to what I've already written. There isn't an environment variable set to .wasm.

But grep seesnoon conftest* >/dev/null would work.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The object files are written a.o so $ac_objext is .o for Emscripten. We run the program like node conftest.js but the file conftest.wasm is necessary in order for the program to work. Thus, conftest.wasm is part of resulting program, not a build artifact. So if $EXEEXT is .js then AC_RUN_IFELSE works correctly. OTOH if we changed $EXEEXT to be .wasm, it would make this particular macro work but all the ones that actually want to run the program would fail.

Perhaps there is a standard way to deal with this situation, but I don't know of other targets where the executable consists of two files. It is possible to combine them into one file if we're willing to increase the size and startup time but it generally isn't worth it.

@sbc100 could perhaps provide additional context/advice.

I don't think I've groked all the context here but I don't think you wan to set $EXEEXT to .wasm since .wasm files on there own own are not runnable. In particular, as you have noted it would break the running on the executables during the build.

BTW, you can also leave EXEEXT as empty (like it is on UNIX) and emcc will produce a shell the .js file without and extension than then loads the wasm file. You might also want consider -sSINGLE_FILE which would then embed the wasm binaryn inside the js files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though even that would probably fail the grep for the float since it gets base 64 encoded.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that the macro is trying to detect the endianness of floats by linking an executable with a float in it that consists of the ascii bytes noonsees or seesnoon depending on the platform endianness. In Emscripten, the .wasm file and the .o file have it but the .js executable does not.

Copy link
Contributor
@damelang damelang Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all that, it seems like grep seesnoon conftest* >/dev/null is the way to go, no?

Or to be less "sloppy", modify the TESTFILES approach to pick up the .wasm file if present:

CONFTESTS="conftest$EXEEXT $( [ -e conftest.wasm ] && echo conftest.wasm)"

But, I kinda prefer the generality of grep on conftest*. It's not wasm specific, so it could help with some other target someday also. And the "sloppiness" of it just doesn't seem to have any real risk.

The fact that it is a such a small change to the existing code is also appealing.

@damelang
Copy link
Contributor
damelang commented Nov 7, 2024

... the object file where the float definitely will live...

Just to make sure we're on the same page: the above statement is only true when referring to Emscripten targets. Even then, it's possible that it won't apply to later versions of Emscripten.

Now, as a general statement: no, the float will not definitely live in an object file (in binary format). Per my documentation for the macro:

"The problem was that under these conditions, the compiler did not allocate for and write the special float value in the data segment of the test object file."

With the current version of the macro, there often isn't even an object file to inspect, only an executable.

@hoodmane
Copy link
Contributor Author
hoodmane commented Nov 7, 2024

the above statement is only true when referring to Emscripten targets. Even then, it's possible that it won't apply to later versions of Emscripten.

Agreed, I mean specifically for Emscripten and it could break in the future. But with no change the macro does not work with any combination of flags on the current version of Emscripten and it will continue to not work in the future.

@damelang what about the first commit aa8ea4c? Would something like that be acceptable? Since on Emscripten targets the float will be in conftest.wasm but conftest$EXEEXT points to contest.mjs or conftest.js.

And what about the third option of hard coding Emscripten as little endian? Are any of these three solutions acceptable?

@damelang
Copy link
Contributor
damelang commented Nov 7, 2024

the above statement is only true when referring to Emscripten targets. Even then, it's possible that it won't apply to later versions of Emscripten.

Agreed, I mean specifically for Emscripten and it could break in the future. But with no change the macro does no 8000 t work with any combination of flags on the current version of Emscripten and it will continue to not work in the future.

@damelang what about the first commit aa8ea4c? Would something like that be acceptable? Since on Emscripten targets the float will be in conftest.wasm but conftest$EXEEXT points to contest.mjs or conftest.js.

And what about the third option of hard coding Emscripten as little endian? Are any of these three solutions acceptable?

I hope you find my suggested change above to be both more general and less complicated than either of those three solutions.

@hoodmane hoodmane force-pushed the float-words-emscripten-fix branch from 1402d85 to 10c5b38 Compare November 8, 2024 09:01
@hoodmane
Copy link
Contributor Author
hoodmane commented Nov 8, 2024

Okay @damelang I updated the PR with your proposed solution since we seem to agree on it. I'll make sure double check that it actually works before merging.

Commit 23be7cc "Fix AX_C_FLOAT_WORDS_BIGENDIAN
fails whenever interprocedural optimization is enabled." introduced a regression
on the Emscripten target because it switched from grepping the object file where
the float definitely will live, to grepping conftest$EXEEXT which in the case of
Emscripten will be conftest.js but the float is in conftest.wasm. This problem
is unique to Emscripten, it is not present on any other webassembly platform.

To fix, grep `conftest*` for the float.
@hoodmane hoodmane force-pushed the float-words-emscripten-fix branch from 10c5b38 to 5a70049 Compare November 8, 2024 10:21
@hoodmane
Copy link
Contributor Author
hoodmane commented Nov 8, 2024

Okay, I tested this and it works.

@damelang
Copy link
Contributor
damelang commented Nov 9, 2024

I'm not a maintainer here, so now that we've got something we're all happy with, it's up to @peti to approve.

@hoodmane , will you be moving the python build away from hard coding for wasm and using this approach instead? It would be helpful to have the python community "kick the tires" of the grep conftest* approach.

@peti peti merged commit b261182 into autoconf-archive:master Nov 9, 2024
1 check passed
@hoodmane
Copy link
Contributor Author
hoodmane commented Nov 9, 2024

Yeah I plan to do that. Thanks @damelang and @erlend-aasland!

hoodmane added a commit to hoodmane/cpython-devcontainers that referenced this pull request Nov 11, 2024
The original patch:
autoconf-archive/autoconf-archive#279
broke endianness detection on Emscripten. This was fixed in this followup:
autoconf-archive/autoconf-archive#316

We also have worked around the problem by adjusting `configure.ac` in the Python
repo to handle this case:
python/cpython#126387
But it's useful for us to use the upstream autoconf-archive detection so that we
can be completely sure that the fix works in practice.
erlend-aasland pushed a commit to python/cpython-devcontainers that referenced this pull request Nov 11, 2024
hoodmane added a commit to hoodmane/cpython that referenced this pull request Nov 12, 2024
…nf-archive

Pulls in the updated docker container from this PR:
python/cpython-devcontainers#34
which contains the autoconf-archive PR:
autoconf-archive/autoconf-archive#316

I removed the workaround from configure.ac, regenerated everything, and manually
tested that the fix works.
hoodmane added a commit to hoodmane/cpython that referenced this pull request Nov 13, 2024
…nf-archive

Pulls in the updated docker container from this PR:
python/cpython-devcontainers#34
which contains the autoconf-archive PR:
autoconf-archive/autoconf-archive#316

I removed the workaround from configure.ac, regenerated everything, and manually
tested that the fix works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0