This is an archive of the discontinued LLVM Phabricator instance.

[CMake] Use LLVM own tools in extract_symbols.py
ClosedPublic

Authored by ikudrin on Apr 24 2023, 8:52 PM.

Details

Summary

As for now, extract_symbols.py can use several tools to extract symbols from object files and libraries and to guess if the target is 32-bit Windows. The tools are being found via PATH, so in most cases, they are just system tools. This approach has a number of limitations, in particular:

  • System tools may not be able to handle the target format in case of cross-platform builds,
  • They cannot read symbols from LLVM bitcode files, so the staged LTO build with plugins is not supported,
  • The auto-selected tools may be suboptimal (see D113557),
  • Support for multiple tools for a single task increases the complexity of the script code.

The patch proposes using LLVM's own tools to solve these issues. Specifically, llvm-readobj detects the target platform, and llvm-nm reads symbols from all supported formats, including bitcode files. The tools can be built in Release mode for the host platform or overridden using CMake settings LLVM_READOBJ and LLVM_NM respectively. The implementation also supports using precompiled tools via LLVM_NATIVE_TOOL_DIR.

Diff Detail

Event Timeline

ikudrin created this revision.Apr 24 2023, 8:52 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 24 2023, 8:52 PM
ikudrin requested review of this revision.Apr 24 2023, 8:52 PM

This looks like a nice addition. Would it make sense to use llvm-nm always, not restricted to bootstrap builds? And would that work on Windows and allow us to simplify this script substantially by using one tool for all platforms?

This looks like a nice addition. Would it make sense to use llvm-nm always, not restricted to bootstrap builds? And would that work on Windows and allow us to simplify this script substantially by using one tool for all platforms?

If I understand it right, we might not be able to build llvm-nm in cases like cross-platform building, right?

Supporting only a single tool and simplifying the script would be my preference as well. I see that the script already supports llvm-readobj, do we need the llvm-nm support in that case?

Supporting only a single tool and simplifying the script would be my preference as well. I see that the script already supports llvm-readobj, do we need the llvm-nm support in that case?

I remember seeing it mentioned somewhere (I don't immediately see where right now though), llvm-readobj only handles regular object files, while llvm-nm handles bitcode too.

If I understand it right, we might not be able to build llvm-nm in cases like cross-platform building, right?

LLVM has a way to build tools that need to run on the build machine as part of the build (tablegen for example), llvm-nm could be added to that system and then it would be available when extract_symbols.py is run. It would be an issue if llvm-nm ever had to depend on extract_symbols.py but that is not currently the case afaik.

Do LLVM's current portability goals include the constraint that you can only build LLVM for a platform it can also target? If not, then there surely still needs to be some kind of escape hatch so that you can avoid needing llvm-nm to already support the object file format of the host platform.

I suppose you could say that in that unusual situation it's up to you to adapt extract_symbols.py so that it has some other way to get the answers.

Do LLVM's current portability goals include the constraint that you can only build LLVM for a platform it can also target? If not, then there surely still needs to be some kind of escape hatch so that you can avoid needing llvm-nm to already support the object file format of the host platform.

I suppose you could say that in that unusual situation it's up to you to adapt extract_symbols.py so that it has some other way to get the answers.

If I understand it right, the main targets to use extract_symbols.py are AIX and Windows. For both these platforms llvm-nm and llvm-readobj can be built. Support for more exotic situations can be added relatively easily should it be required.

ikudrin updated this revision to Diff 520277.May 8 2023, 12:08 AM
ikudrin retitled this revision from [CMake] Use llvm-nm to extract symbols for staged LTO builds on Windows to [CMake] Use LLVM own tools in extract_symbols.py.
ikudrin edited the summary of this revision. (Show Details)
  • Reworked the patch to always use llvm-nm to extract symbols and llvm-readobj to detect targeting 32-bit Windows.
tmatheson accepted this revision.May 9 2023, 4:17 AM

LGTM, thank you for doing this. Please give it a couple of days in case others have comments.

This revision is now accepted and ready to land.May 9 2023, 4:17 AM

I've not really looked into this patch significantly, so this may well be addressed in the patch, given I see you have modified stuff to do with the NATIVE build, but in the past I have seen LLVM using its own tools to build other parts of its system. I believe it was using llvm-nm to extract the list of symbols needed for export, possibly to do with part of the clang build, possibly even using this script, I don't remember. The problem was that it was using the just-built version of llvm-nm, rather than specifically one from a release build. On a debug build this caused particularly slow builds for me, so much so that I stopped building the relevant parts of LLVM. Please don't introduce a similar situation/make the situation worse (it's quite possible this was fixed some time ago, but I haven't tried recently, nor do I remember the exact thing causing the issue): much like tablegen, any parts of the LLVM build that use just-built tools should make use of release builds, even in debug configuration, at least if an appropriate cmake option is specified.

beanz added a comment.May 9 2023, 7:01 AM

One potential area of concern here: If llvm-driver is ever extended to work as a plugin loader (thus exporting its symbols), removing support for the pre-installed host tools could cause a cyclic dependency.

LGTM, thank you for doing this. Please give it a couple of days in case others have comments.

Thanks!

I've not really looked into this patch significantly, so this may well be addressed in the patch, given I see you have modified stuff to do with the NATIVE build, but in the past I have seen LLVM using its own tools to build other parts of its system. I believe it was using llvm-nm to extract the list of symbols needed for export, possibly to do with part of the clang build, possibly even using this script, I don't remember. The problem was that it was using the just-built version of llvm-nm, rather than specifically one from a release build. On a debug build this caused particularly slow builds for me, so much so that I stopped building the relevant parts of LLVM. Please don't introduce a similar situation/make the situation worse (it's quite possible this was fixed some time ago, but I haven't tried recently, nor do I remember the exact thing causing the issue): much like tablegen, any parts of the LLVM build that use just-built tools should make use of release builds, even in debug configuration, at least if an appropriate cmake option is specified.

Your concerns are legit, but the tools in this patch follow the same principle as TableGen, i.e. if LLVM_OPTIMIZED_TABLEGEN is ON then the tools are forced to be built with optimization.

One potential area of concern here: If llvm-driver is ever extended to work as a plugin loader (thus exporting its symbols), removing support for the pre-installed host tools could cause a cyclic dependency.

In that case, we will need to add an option to build the tools without plugin support so that they can be used in the build process.

LGTM, thank you for doing this. Please give it a couple of days in case others have comments.

Thanks!

I've not really looked into this patch significantly, so this may well be addressed in the patch, given I see you have modified stuff to do with the NATIVE build, but in the past I have seen LLVM using its own tools to build other parts of its system. I believe it was using llvm-nm to extract the list of symbols needed for export, possibly to do with part of the clang build, possibly even using this script, I don't remember. The problem was that it was using the just-built version of llvm-nm, rather than specifically one from a release build. On a debug build this caused particularly slow builds for me, so much so that I stopped building the relevant parts of LLVM. Please don't introduce a similar situation/make the situation worse (it's quite possible this was fixed some time ago, but I haven't tried recently, nor do I remember the exact thing causing the issue): much like tablegen, any parts of the LLVM build that use just-built tools should make use of release builds, even in debug configuration, at least if an appropriate cmake option is specified.

Your concerns are legit, but the tools in this patch follow the same principle as TableGen, i.e. if LLVM_OPTIMIZED_TABLEGEN is ON then the tools are forced to be built with optimization.

Thanks - that's fine with me (though raises the question as to whether we should be renaming that variable at some point...).

This revision was automatically updated to reflect the committed changes.