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

"wasm-ld: error: Expected at most one ThinLTO module per bitcode file" #12763

Closed
icculus opened this issue Nov 12, 2020 · 7 comments
Closed

"wasm-ld: error: Expected at most one ThinLTO module per bitcode file" #12763

icculus opened this issue Nov 12, 2020 · 7 comments

Comments

@icculus
Copy link
Contributor

icculus commented Nov 12, 2020

Emscripten fails to link if using -flto=thin and one of the inputs is a static library (.a file) that contains two object files with the same name. This happens to me because I'm building mRuby into a library, which has two unrelated source files in different directories named "array.c" (and others, too).

This seems to be an error inherited from LLVM, based on limited results from Googling, but here's how to reproduce this (tested against 2.0.8) ...

echo 'int a(int x) { return x + 3; }' > a.c
echo 'int b(int x) { return x + 1; }' > b.c
echo 'int a(int); int b(int); int main(int argc, char **argv) { return a(1) + b(2); }' > m.c
mkdir -p subdir
emcc -c -flto=thin -o a.o a.c
emcc -c -flto=thin -o subdir/a.o b.c
emar r a.ar a.o subdir/a.o
emcc -c -flto=thin -o m.o m.c
emcc -flto=thin -s WASM=1 -o a.js a.ar m.o

On the last emcc command, it generates the error:

wasm-ld: error: Expected at most one ThinLTO module per bitcode file

Changing one of the object names to something other than "a.o" works around this--as does linking against the .o files instead of the .a--but a proper fix would be appreciated, especially if it just needs something pulled in or adapted from LLVM: https://reviews.llvm.org/D79880

@kripken
Copy link
Member

kripken commented Nov 12, 2020

Looks like that commit has landed on LLVM months ago, so it should be in 2.0.8 definitely, unless LLVM backed it out.

Can you test to see if the error happens with plain clang as well? I'd expect it to since I think we just let LLVM do this linking stuff now. If so, it's an LLVM bug we should file there.

@sbc100
Copy link
Collaborator

sbc100 commented Nov 12, 2020

Does this only happen with -flto=thin and not with -flto?

Note that we do basically no testing with -flto=thin either in emscripten or in upstream llvm. We should fix that.. but you might be first person to try to use in the real world, so expect issues.

@icculus
Copy link
Contributor Author

icculus commented Nov 18, 2020

Following up, this works with Clang 10.0.0 with -flto=thin ...

clang -c -flto=thin -o a.o a.c
clang -c -flto=thin -o subdir/a.o b.c
llvm-ar r a.ar a.o subdir/a.o
clang -c -flto=thin -o m.o m.c
clang -fuse-ld=lld -flto=thin -o a.out a.ar m.o

(I had to use -fuse-ld=lld because of the way this Clang was built, and it's worth noting that this could totally be what avoids this bug in the first place.)

I am absolutely unfamiliar with all these details, but the LLVM fix I linked to appears to be ELF-specific, so possibly it doesn't apply to Emscripten output?

As for -flto vs -flto=thin: using -flto works (at least, it links, I haven't tested the results further yet); this bug only reproduces with -flto=thin.

It's worth noting, however, that when you set CMAKE_INTERPROCEDURAL_OPTIMIZATION to True in a CMake project, it sets -flto=thin without any way to specify the specific option directly, which is how I came to stumble into this problem, so others will eventually hit this, too, I assume.

@haraldF
Copy link

haraldF commented May 3, 2021

It's worth noting, however, that when you set CMAKE_INTERPROCEDURAL_OPTIMIZATION to True in a CMake project, it sets -flto=thin without any way to specify the specific option directly

Seems you can override it in CMake via:

set(CMAKE_CXX_COMPILE_OPTIONS_IPO "-flto")

@icculus
Copy link
Contributor Author

icculus commented May 3, 2021

@haraldF oh, nice, I'll try that, thanks!

@andrewevstyukhin
Copy link
Contributor

andrewevstyukhin commented Oct 28, 2021

Hi there,
problem exists in emscripten 2.0.32 also.

This happens with -flto=thin and not with -flto.

LTO::addThinLTO
if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
return make_error(
"Expected at most one ThinLTO module per bitcode file",
inconvertibleErrorCode());

ModuleIdentifier = "engine/libengine.aUtils.cpp.o"
ModuleIdentifier = "engine/libengine.aPath.cpp.o"

@sbc100
Copy link
Collaborator

sbc100 commented Oct 28, 2021

It will take a few hours for this fix to show up in tot version emsdk and then it will be in the next release (2.0.33).

mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
This entire change, including the test case, comes almost verbatim
from the ELF driver.

Fixes: emscripten-core/emscripten#12763

Differential Revision: https://reviews.llvm.org/D112723
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

No branches or pull requests

5 participants