Long-Term Support for LLVM Projects Extension to Build System?

Dear All,

Will the LLVM project system (the extension to the build system that allows sub-projects to reuse the LLVM Makefiles) be maintained long term, or is the slow push to CMake intending to deprecate this functionality?

We used this feature a lot for research projects at UIUC, but if the current maintainers of the build system are planning on deprecating it, I'll have my students avoid using it.

Regards,

John Criswell

Hi John,

Long term we don’t want to keep the burden of two build systems in tree. CMake is turning out to be the build system we want because of its multi-platform support, etc and as soon as the CMake system can do everything we can do with the autoconf/makefile build I plan on turning down the support for that and removing the code.

Thanks!

-eric

Thanks, but I wasn’t asking about autoconf vs. cmake. I’m wanting to know whether the ability to “plug into” the LLVM build system by external projects will be maintained. For example, SAFECode doesn’t have its own build system; it uses LLVM’s, and it does so without being a “patch” to the LLVM source tree. You can put the SAFECode source code anywhere you like, use LLVM-style Makefiles in its source code, and build it. All of the PROJ_SRC_ROOT, PROJ_OBJ_ROOT magic in the autoconf build system is what permits that feature to work. Do you intend to keep this functionality when you replace autoconf with cmake, or will all projects that want to use the LLVM build system need to place their source code in the LLVM source tree? To put it another way, do you intend to deprecate the PROJ_SRC_ROOT/PROJ_OBJ_ROOT stuff? While I’ve enjoyed the PROJ_* magic, I can see why you’d want to get rid of it. I just want to ensure that you are not planning on replacing it. Regards, John Criswell

Hi John,

Long term we don’t want to keep the burden of two build systems in tree. CMake is turning out to be the build system we want because of its multi-platform support, etc and as soon as the CMake system can do everything we can do with the autoconf/makefile build I plan on turning down the support for that and removing the code.

Thanks, but I wasn’t asking about autoconf vs. cmake.

Well, you are, but only sorta.

I’m wanting to know whether the ability to “plug into” the LLVM build system by external projects will be maintained. For example, SAFECode doesn’t have its own build system; it uses LLVM’s, and it does so without being a “patch” to the LLVM source tree. You can put the SAFECode source code anywhere you like, use LLVM-style Makefiles in its source code, and build it. All of the PROJ_SRC_ROOT, PROJ_OBJ_ROOT magic in the autoconf build system is what permits that feature to work.

Do you intend to keep this functionality when you replace autoconf with cmake, or will all projects that want to use the LLVM build system need to place their source code in the LLVM source tree? To put it another way, do you intend to deprecate the PROJ_SRC_ROOT/PROJ_OBJ_ROOT stuff?

While I’ve enjoyed the PROJ_* magic, I can see why you’d want to get rid of it. I just want to ensure that you are not planning on replacing it.

Right. So this is a “autoconf/makefile build system vs cmake build system” question as the Makefiles would, theoretically, all go away at the end. I don’t think anyone has plans of replacing this functionality (Chris?), but migrating out of tree projects to hook in via modifying the cmake build locally shouldn’t be too bad.

-eric

From: "Eric Christopher" <echristo@gmail.com>
To: "John Criswell" <jtcriswel@gmail.com>, LLVMdev@cs.uiuc.edu, "Chris Bieneman" <beanz@apple.com>
Sent: Thursday, June 18, 2015 7:14:06 PM
Subject: Re: [LLVMdev] Long-Term Support for LLVM Projects Extension to Build System?

Hi John,

Long term we don't want to keep the burden of two build systems in
tree. CMake is turning out to be the build system we want because of
its multi-platform support, etc and as soon as the CMake system can
do everything we can do with the autoconf/makefile build I plan on
turning down the support for that and removing the code.

Thanks, but I wasn't asking about autoconf vs. cmake.

Well, you are, but only sorta.

I'm wanting to know whether the ability to "plug into" the LLVM build
system by external projects will be maintained. For example,
SAFECode doesn't have its own build system; it uses LLVM's, and it
does so without being a "patch" to the LLVM source tree. You can put
the SAFECode source code anywhere you like, use LLVM-style Makefiles
in its source code, and build it. All of the PROJ_SRC_ROOT,
PROJ_OBJ_ROOT magic in the autoconf build system is what permits
that feature to work.

Do you intend to keep this functionality when you replace autoconf
with cmake, or will all projects that want to use the LLVM build
system need to place their source code in the LLVM source tree? To
put it another way, do you intend to deprecate the
PROJ_SRC_ROOT/PROJ_OBJ_ROOT stuff?

While I've enjoyed the PROJ_* magic, I can see why you'd want to get
rid of it. I just want to ensure that you are not planning on
replacing it.

Right. So this is a "autoconf/makefile build system vs cmake build
system" question as the Makefiles would, theoretically, all go away
at the end. I don't think anyone has plans of replacing this
functionality (Chris?), but migrating out of tree projects to hook
in via modifying the cmake build locally shouldn't be too bad.

This is also related to the metapoint that the cmake build system doesn't glob for source files (or anything else), unlike the makefile build system. This is understandable given the constraints, but we might want to restore some of that functionality for the purpose of supporting out-of-tree projects.

What I mean specifically, is that, for example, we could have a normally-empty directory tools/extensions, and tools/CMakeLists.txt could glob for directories in tools/extensions and call add_llvm_tool_subdirectory on all of them. It is true that you'd need to re-run cmake whenever you added something there (we could have a README in that directory to remind people of that), but that seems like a much smaller price than having to maintain a patched version of the upstream sources.

-Hal

From: “Eric Christopher” <echristo@gmail.com>
To: “John Criswell” <jtcriswel@gmail.com>, LLVMdev@cs.uiuc.edu, “Chris Bieneman” <beanz@apple.com>
Sent: Thursday, June 18, 2015 7:14:06 PM
Subject: Re: [LLVMdev] Long-Term Support for LLVM Projects Extension to Build System?

Hi John,

Long term we don’t want to keep the burden of two build systems in
tree. CMake is turning out to be the build system we want because of
its multi-platform support, etc and as soon as the CMake system can
do everything we can do with the autoconf/makefile build I plan on
turning down the support for that and removing the code.

Thanks, but I wasn’t asking about autoconf vs. cmake.

Well, you are, but only sorta.

I’m wanting to know whether the ability to “plug into” the LLVM build
system by external projects will be maintained. For example,
SAFECode doesn’t have its own build system; it uses LLVM’s, and it
does so without being a “patch” to the LLVM source tree. You can put
the SAFECode source code anywhere you like, use LLVM-style Makefiles
in its source code, and build it. All of the PROJ_SRC_ROOT,
PROJ_OBJ_ROOT magic in the autoconf build system is what permits
that feature to work.

Do you intend to keep this functionality when you replace autoconf
with cmake, or will all projects that want to use the LLVM build
system need to place their source code in the LLVM source tree? To
put it another way, do you intend to deprecate the
PROJ_SRC_ROOT/PROJ_OBJ_ROOT stuff?

While I’ve enjoyed the PROJ_* magic, I can see why you’d want to get
rid of it. I just want to ensure that you are not planning on
replacing it.

Right. So this is a “autoconf/makefile build system vs cmake build
system” question as the Makefiles would, theoretically, all go away
at the end. I don’t think anyone has plans of replacing this
functionality (Chris?), but migrating out of tree projects to hook
in via modifying the cmake build locally shouldn’t be too bad.

This is also related to the metapoint that the cmake build system doesn’t glob for source files (or anything else), unlike the makefile build system. This is understandable given the constraints, but we might want to restore some of that functionality for the purpose of supporting out-of-tree projects.

What I mean specifically, is that, for example, we could have a normally-empty directory tools/extensions, and tools/CMakeLists.txt could glob for directories in tools/extensions and call add_llvm_tool_subdirectory on all of them. It is true that you’d need to re-run cmake whenever you added something there (we could have a README in that directory to remind people of that), but that seems like a much smaller price than having to maintain a patched version of the upstream sources.

Sure, seems reasonable to me. I’m not working on the cmake transition so I’m just answering as far as “things I plan on deleting when I can delete” :slight_smile:

-eric

From: "Eric Christopher" <echristo@gmail.com>
To: "Hal Finkel" <hfinkel@anl.gov>
Cc: "John Criswell" <jtcriswel@gmail.com>, LLVMdev@cs.uiuc.edu, "Chris Bieneman" <beanz@apple.com>
Sent: Thursday, June 18, 2015 7:57:40 PM
Subject: Re: [LLVMdev] Long-Term Support for LLVM Projects Extension to Build System?

> From: "Eric Christopher" < echristo@gmail.com >
> To: "John Criswell" < jtcriswel@gmail.com >, LLVMdev@cs.uiuc.edu ,
> "Chris Bieneman" < beanz@apple.com >
> Sent: Thursday, June 18, 2015 7:14:06 PM
> Subject: Re: [LLVMdev] Long-Term Support for LLVM Projects
> Extension to Build System?
>
>
>
>
>
>
>
> Hi John,
>
>
> Long term we don't want to keep the burden of two build systems in
> tree. CMake is turning out to be the build system we want because
> of
> its multi-platform support, etc and as soon as the CMake system can
> do everything we can do with the autoconf/makefile build I plan on
> turning down the support for that and removing the code.
>
> Thanks, but I wasn't asking about autoconf vs. cmake.
>
>
>
>
> Well, you are, but only sorta.
>
>
>
> I'm wanting to know whether the ability to "plug into" the LLVM
> build
> system by external projects will be maintained. For example,
> SAFECode doesn't have its own build system; it uses LLVM's, and it
> does so without being a "patch" to the LLVM source tree. You can
> put
> the SAFECode source code anywhere you like, use LLVM-style
> Makefiles
> in its source code, and build it. All of the PROJ_SRC_ROOT,
> PROJ_OBJ_ROOT magic in the autoconf build system is what permits
> that feature to work.
>
> Do you intend to keep this functionality when you replace autoconf
> with cmake, or will all projects that want to use the LLVM build
> system need to place their source code in the LLVM source tree? To
> put it another way, do you intend to deprecate the
> PROJ_SRC_ROOT/PROJ_OBJ_ROOT stuff?
>
> While I've enjoyed the PROJ_* magic, I can see why you'd want to
> get
> rid of it. I just want to ensure that you are not planning on
> replacing it.
>
>
> Right. So this is a "autoconf/makefile build system vs cmake build
> system" question as the Makefiles would, theoretically, all go away
> at the end. I don't think anyone has plans of replacing this
> functionality (Chris?), but migrating out of tree projects to hook
> in via modifying the cmake build locally shouldn't be too bad.
>

This is also related to the metapoint that the cmake build system
doesn't glob for source files (or anything else), unlike the
makefile build system. This is understandable given the constraints,
but we might want to restore some of that functionality for the
purpose of supporting out-of-tree projects.

What I mean specifically, is that, for example, we could have a
normally-empty directory tools/extensions, and tools/CMakeLists.txt
could glob for directories in tools/extensions and call
add_llvm_tool_subdirectory on all of them. It is true that you'd
need to re-run cmake whenever you added something there (we could
have a README in that directory to remind people of that), but that
seems like a much smaller price than having to maintain a patched
version of the upstream sources.

Sure, seems reasonable to me. I'm not working on the cmake transition
so I'm just answering as far as "things I plan on deleting when I
can delete" :slight_smile:

Sounds good :wink:

John, I think you're probably the best person to send a patch for this kind of thing since that way you can make sure the solution actually makes sense for you.

-Hal

There is actually some support for this already in the CMake build. see projects/CMakeLists.txt and add_llvm_external_project which specifically allows projects to live outside of LLVM’s source tree.

But this is for known sub-projects, not for arbitrary ones. I understand that your use case is slightly different in that respect.

The use of LLVM’s makefiles for completely unrelated projects being built outside of the LLVM source tree I think is likely to “go away” but that is because the functionality it provides is largely provided directly by CMake already.

The CMake modules that LLVM ships with which provide the missing functionality are easily reused in an independent CMake build by setting up the CMake module path to include LLVM’s cmake directory… But I don’t really recommend it as it seems more trouble than it is worth compared to just using the functionality that ships with CMake.

If you’re using LLVM’s makefiles to build code against the LLVM libraries but out of tree and not as part of an LLVM build, I don’t know how this works and don’t really know what to suggest. I’m just not familiar with that pattern.

This is also related to the metapoint that the cmake build system doesn’t glob for source files (or anything else), unlike the makefile build system. This is understandable given the constraints, but we might want to restore some of that functionality for the purpose of supporting out-of-tree projects.

I actually think these are completely separate. See below.

What I mean specifically, is that, for example, we could have a normally-empty directory tools/extensions, and tools/CMakeLists.txt could glob for directories in tools/extensions and call add_llvm_tool_subdirectory on all of them. It is true that you’d need to re-run cmake whenever you added something there (we could have a README in that directory to remind people of that), but that seems like a much smaller price than having to maintain a patched version of the upstream sources.

We already do this in numerous places. See projects/CMakeLists.txt which does exactly this.

We don’t automatically support external projects in different locations through globbing, but that’s because that doesn’t make any sense.

We can add globbing-based recursion to subproject CMake files anywhere it is useful.

There is no problem with globbing to add subdirectories IMO because subdirectories with new CMake files clearly have to be introduced and maintained at the points you run the ‘cmake’ tool. Only globbing for source files seems problematic to me at all.

-Chandler

Dear All,

Thanks for the feedback.

To clarify, this is for LLVM-related projects that are linking against the LLVM libraries.

The feature for keeping our source code in arbitrary locations isn't something we need. If we can just drop our source code into llvm/projects (or some other designated LLVM subdirectory) and write LLVM-esque CMake files, that should be enough for projects that don't need to patch the existing LLVM tools.

Regards,

John Criswell

Hi,

If you just want to link to LLVM, it is not clear to me why you are not just relying on LLVM being built separately and have your project CMake pointing to the llvm build directory and using llvm-config to populate the linker argument?

Best,

This is what I do in my Pascal compiler project. It may not be the perfect
solution, but I have not found any HUGE drawback yet.

Supporting out-of-tree tools without needing to modify the in-tree CMake code is something I’ve been thinking about adding to the CMake build system (we already support this for projects, but I was thinking about doing it differently for tools). I’ve written loads of internal tools, and it is obnoxious to have out-of-tree modifications to the CMakeLists files.

The idea I had for tools was to do something similar to the globing Chandler posted out in projects/CMakeLists.txt, but to treat globed external projects more like how we treat Polly; off by default and requiring a setting to enable them.

-Chris

This is what I effectively do. Although because I build the projects I
work on I use the CMake config file that LLVM exports to make it
trivially easy to use the LLVM libraries from within CMake (see
http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project).

Thanks,
Dan.

The last time that I tried this, I hit all sorts of errors when LLVM was built as shared libraries and eventually just had my cmake files invoke llvm-config and manually populate the relevant CXX / LD flags.

I don’t know if there’s something that we can do with buildbots to make sure that this is better tested.

David

This is what I effectively do. Although because I build the projects I
work on I use the CMake config file that LLVM exports to make it
trivially easy to use the LLVM libraries from within CMake (see
http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project).

The last time that I tried this, I hit all sorts of errors when LLVM was built as shared libraries and eventually just had my cmake files invoke llvm-config and manually populate the relevant CXX / LD flags.

AFAIK the exported CMake targets only work with the static LLVM
libraries right now. The intention is that user's of LLVM should use
the llvm_map_components_to_libnames() function in CMake. Right now
that returns the names of the static library targets. In principle I
suppose it could be modified to return the shared library target
instead if a shared build was done. But there are a few issues to
consider here:

* When LLVM is built it possible to pick what components go into the
shared library which means in some cases
``llvm_map_components_to_libnames()`` would not work as intended if
just returns the LLVM shared library target name.
* A user of LLVM may want the ability to pick the static libraries
even though the shared libraries were built.
* In the shared library the C++ symbols hidden so we would need to add
an option to disable this behaviour.

Here's what I'd like to suggest:

- Modify ``llvm_map_components_to_libnames()`` to take an optional
keyword which is either STATIC or SHARED. To avoid ambiguity this
means we cannot have a component called "STATIC" or "SHARED", I don't
imagine this would ever happen in practice. So the signature would
look like this

llvm_map_components_to_libnames(OUTPUTVAR [STATIC|SHARED] component0 ...)

- If set to static the static library names will be returned if the
components exists, otherwise emit an error message.
- If SHARED is specified CMake will check that the requested
components were added to the shared library when it was built. For
this to work the names of the components will need to be written into
LLVMConfig.cmake. If all the components requested are supposed to be
in the shared library then return the shared library target, otherwise
emit an error message (this includes the case where the shared library
was not built).
- If STATIC or SHARED is not specified use STATIC so as to not break
the interface for existing users of llvm_map_components_to_libnames().
- Switch C++ symbol hiding in the shared library off by default.

Thoughts?

I don’t know if there’s something that we can do with buildbots to make sure that this is better tested.

I was thinking it would be nice to make a very simple toy project that
uses CMake to build and uses ``llvm_map_components_to_libnames()``.
The CMake build bots could be taught to build this from scratch
against a completed build of LLVM. I thinking testing this is a very
good idea because I recently had to fix this feature which was broken
under Windows.

Thanks,
Dan.

This all sounds great to me. That said, my use case is quite unusual: I want a single debug build of LLVM and a single release build on a shared file server so that students can link things against a debug build without ending up with a few hundred MBs of object code in their home directories for each exercise and hitting quota issues. I suspect that this isn’t a problem that doesn’t affect most other people.

David

This is what I effectively do. Although because I build the projects I
work on I use the CMake config file that LLVM exports to make it
trivially easy to use the LLVM libraries from within CMake (see
http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project).

The last time that I tried this, I hit all sorts of errors when LLVM was built as shared libraries and eventually just had my cmake files invoke llvm-config and manually populate the relevant CXX / LD flags.

AFAIK the exported CMake targets only work with the static LLVM
libraries right now.

That depends. It should work with shared libraries if the LLVM you are importing was built with BUILD_SHARED_LIBS=On. It will also work with llvm-shlib if it was built with LLVM_BUILD_LLVM_DYLIB=On.

The intention is that user's of LLVM should use
the llvm_map_components_to_libnames() function in CMake. Right now
that returns the names of the static library targets. In principle I
suppose it could be modified to return the shared library target
instead if a shared build was done. But there are a few issues to
consider here:

* When LLVM is built it possible to pick what components go into the
shared library which means in some cases
``llvm_map_components_to_libnames()`` would not work as intended if
just returns the LLVM shared library target name.
* A user of LLVM may want the ability to pick the static libraries
even though the shared libraries were built.

If static libraries are built, but the user wants shared libraries, there is no way to handle this other than re-configuring and rebuilding LLVM.

* In the shared library the C++ symbols hidden so we would need to add
an option to disable this behaviour.

LLVM_DYLIB_EXPORT_ALL=On will export all symbols from the dylib.

Here's what I'd like to suggest:

- Modify ``llvm_map_components_to_libnames()`` to take an optional
keyword which is either STATIC or SHARED. To avoid ambiguity this
means we cannot have a component called "STATIC" or "SHARED", I don't
imagine this would ever happen in practice. So the signature would
look like this

llvm_map_components_to_libnames(OUTPUTVAR [STATIC|SHARED] component0 ...)

- If set to static the static library names will be returned if the
components exists, otherwise emit an error message.
- If SHARED is specified CMake will check that the requested
components were added to the shared library when it was built. For
this to work the names of the components will need to be written into
LLVMConfig.cmake. If all the components requested are supposed to be
in the shared library then return the shared library target, otherwise
emit an error message (this includes the case where the shared library
was not built).

I have thought about doing this, and it wouldn’t be terribly complicated. There is already some goop in tools/llvm-c-test/CMakeLists.txt to check against the list of libraries in the dylib before linking the libraries separately.

While I don’t disagree with what you’re proposing, I actually think we need a larger reworking of how llvm_map_components_to_libnames works. The file that function comes from is basically a re-implementation of llvm-config in CMake, and it is really a bit of a dirty hack, and it unfortunately results in us having 2 different systems for expressing libraries dependencies at varying levels of robustness. I would like to find a way to get rid of all of the duplication, and to have a project-agnostic way to do this so that clang and other sub-projects could benefit from it as well.

That’s all a bit of a pipe dream though, so we shouldn’t let it prevent us from making the existing hacks work better.

- If STATIC or SHARED is not specified use STATIC so as to not break
the interface for existing users of llvm_map_components_to_libnames().
- Switch C++ symbol hiding in the shared library off by default.

I disagree with this. When I added llvm-shlib to the CMake build system I did it this way intentionally with specific clients in mind (the key one being WebKit). I’ve added lots of options to configure it in any way you want, but my inclination is that the default configuration should be what it is now. The library that llvm-shlib generates was not intended to be used by llvm in-tree tools, nor was it intended to be used by projects that import our build system. The whole point of having a single shared library is that your link command line is trivial (-lLLVM). While I’m completely in favor of extending it to work better for other use cases (and in fact we have a few planned uses ourselves), I would prefer if the default behavior didn’t change.

-Chris

AFAIK the exported CMake targets only work with the static LLVM
libraries right now. The intention is that user's of LLVM should use
the llvm_map_components_to_libnames() function in CMake. Right now
that returns the names of the static library targets. In principle I
suppose it could be modified to return the shared library target
instead if a shared build was done. But there are a few issues to
consider here:

* When LLVM is built it possible to pick what components go into the
shared library which means in some cases
``llvm_map_components_to_libnames()`` would not work as intended if
just returns the LLVM shared library target name.
* A user of LLVM may want the ability to pick the static libraries
even though the shared libraries were built.
* In the shared library the C++ symbols hidden so we would need to add
an option to disable this behaviour.

Here's what I'd like to suggest:

- Modify ``llvm_map_components_to_libnames()`` to take an optional
keyword which is either STATIC or SHARED. To avoid ambiguity this
means we cannot have a component called "STATIC" or "SHARED", I don't
imagine this would ever happen in practice. So the signature would
look like this

llvm_map_components_to_libnames(OUTPUTVAR [STATIC|SHARED] component0 ...)

- If set to static the static library names will be returned if the
components exists, otherwise emit an error message.
- If SHARED is specified CMake will check that the requested
components were added to the shared library when it was built. For
this to work the names of the components will need to be written into
LLVMConfig.cmake. If all the components requested are supposed to be
in the shared library then return the shared library target, otherwise
emit an error message (this includes the case where the shared library
was not built).
- If STATIC or SHARED is not specified use STATIC so as to not break
the interface for existing users of llvm_map_components_to_libnames().
- Switch C++ symbol hiding in the shared library off by default.

Thoughts?

This all sounds great to me. That said, my use case is quite unusual: I want a single debug build of LLVM and a single release build on a shared file server so that students can link things against a debug build without ending up with a few hundred MBs of object code in their home directories for each exercise and hitting quota issues. I suspect that this isn’t a problem that doesn’t affect most other people.

If you’re building this for students there is a much simpler way to do this, with the existing build system.

Configure LLVM with a command like this:

cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_OPTIMIZED_TABLEGEN=On -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" -DLLVM_BUILD_LLVM_DYLIB=On -DLLVM_DYLIB_EXPORT_ALL=On -DCMAKE_INSTALL_PREFIX=<install path> <path to llvm>

Setting the install prefix will result in you having a directory you can tar up and send to your students.

Build just the bits you need:
ninja LLVM

Install only the dylib and the headers:
ninja install-LLVM installhdrs

This will give you a working libLLVM that your students can link against, and the headers they need in the most reduced capacity. No need to use CMake, no need to rely on our build system. Much simpler.

You may need to check tools/llvm-shlib/CMakeLists.txt to make sure it has all the LLVM components you need in the default configuration. If it doesn’t you can change the list of components to include in the dylib by setting LLVM_DYLIB_COMPONENTS.

-Chris

I was looking this morning at supporting out-of-tree tools, and it is actually already there today. If you add a directory under tools that has a CMakeLists.txt file it will get picked up and added as long as LLVM_INCLUDE_TOOLS isn’t set to “bootstrap-only” (which is a dirty hack that needs to die). This happens through a call to add_llvm_implicit_external_projects().

There are some more bells and whistles I’d like to add in this area, but it is functional today.

-Chris