Louis Dionne via llvm-dev
2020-Jun-18 17:57 UTC
[llvm-dev] RFC: A top level monorepo CMake file
Hi folks, Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507 <https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507>, where we need to account for some flags that might have been set globally by LLVM. I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: $ cd <monorepo-root> $ mkdir build $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. Relationship with Petr Hosek's "Runtimes" build --------------------------------------------------------------- What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. Thoughts? Louis -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200618/4c6f68d0/attachment.html>
Siva Chandra via llvm-dev
2020-Jun-18 18:20 UTC
[llvm-dev] RFC: A top level monorepo CMake file
On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hi folks, > > Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, where we need to account for some flags that might have been set globally by LLVM. >Just pointing out: processing the llvm directory is not really a problem for the libc project as it uses LLVM support libraries for build tooling and testing.> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do:I suppose vars like LLVM_CXX_STD_default will also be set up in the higher level CMake file.> > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`.Will rules like add_tablegen, add_llvm_library etc continue to work without any changes?> Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. > > Thoughts? > Louis > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Steven Wu via llvm-dev
2020-Jun-18 18:27 UTC
[llvm-dev] RFC: A top level monorepo CMake file
I like the proposal but I would like to go even further. If we are going to create a top level CMake file, we should just go ahead and eliminate all the standalone build configuration. The standalone build should just be `cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS=standalone-project ...`. That means less build configuration to maintain which is always good. That also means that we can refactor some of the cmake modules to put into the top level directories so sub-projects can just reuse them without duping the code worrying they are not available in the standalone build today. Steven> On Jun 18, 2020, at 10:57 AM, Louis Dionne via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi folks, > > Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507 <https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507>, where we need to account for some flags that might have been set globally by LLVM. > > I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: > > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. > > Thoughts? > Louis > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200618/54e78444/attachment.html>
Louis Dionne via llvm-dev
2020-Jun-18 18:30 UTC
[llvm-dev] RFC: A top level monorepo CMake file
> On Jun 18, 2020, at 14:20, Siva Chandra <sivachandra at google.com> wrote: > > On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> >> Hi folks, >> >> Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, where we need to account for some flags that might have been set globally by LLVM. >> > > Just pointing out: processing the llvm directory is not really a > problem for the libc project as it uses LLVM support libraries for > build tooling and testing.Good to know -- I was talking loosely about "runtime projects", but really I meant libc++, libc++abi and libunwind, since that's what I know best. If the issues I described don't apply to other projects, it may be reasonable to go for a more local solution too.> >> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. >> >> Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: > > I suppose vars like LLVM_CXX_STD_default will also be set up in the > higher level CMake file.No, I don't think that makes sense. Different project may decide to build with different standard versions. Actually, modern CMake advocates for the standard to be set on a per-target basis. This is really important -- for example changing the standard we build libc++ with might have ABI implications, so we need to be careful and explicit about changing it. I don't think it makes sense to be decided at such a high level.> >> >> $ cd <monorepo-root> >> $ mkdir build >> $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") >> >> Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Will rules like add_tablegen, add_llvm_library etc continue to work > without any changes?I would suggest they don't by default, however we could extract common CMake functionality into files that subprojects can include. Basically, we could have <monorepo-root>/cmake/foo.cmake. Louis> >> Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. >> >> Relationship with Petr Hosek's "Runtimes" build >> --------------------------------------------------------------- >> What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. >> >> Thoughts? >> Louis >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Louis Dionne via llvm-dev
2020-Jun-18 18:31 UTC
[llvm-dev] RFC: A top level monorepo CMake file
> On Jun 18, 2020, at 14:27, Steven Wu <stevenwu at apple.com> wrote: > > I like the proposal but I would like to go even further. If we are going to create a top level CMake file, we should just go ahead and eliminate all the standalone build configuration. The standalone build should just be `cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS=standalone-project ...`. That means less build configuration to maintain which is always good. > > That also means that we can refactor some of the cmake modules to put into the top level directories so sub-projects can just reuse them without duping the code worrying they are not available in the standalone build today.Yes, I fully agree. I would do it in a staged way to avoid breaking people, but I agree that a couple months down the road, we should have exactly one way of building any given runtime -- through the top-level CMake file. Louis> > Steven > >> On Jun 18, 2020, at 10:57 AM, Louis Dionne via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Hi folks, >> >> Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507 <https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507>, where we need to account for some flags that might have been set globally by LLVM. >> >> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. >> >> Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: >> >> $ cd <monorepo-root> >> $ mkdir build >> $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") >> >> Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. >> >> Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. >> >> Relationship with Petr Hosek's "Runtimes" build >> --------------------------------------------------------------- >> What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. >> >> Thoughts? >> Louis >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200618/0d038025/attachment-0001.html>
Josh Stone via llvm-dev
2020-Jun-18 18:40 UTC
[llvm-dev] RFC: A top level monorepo CMake file
On 6/18/20 11:27 AM, Steven Wu via llvm-dev wrote:> I like the proposal but I would like to go even further. If we are going > to create a top level CMake file, we should just go ahead and eliminate > all the standalone build configuration. The standalone build should just > be `cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS=standalone-project > ...`. That means less build configuration to maintain which is always good.This would break the release of standalone source tarballs, no?> That also means that we can refactor some of the cmake modules to put > into the top level directories so sub-projects can just reuse them > without duping the code worrying they are not available in the > standalone build today. > > Steven > >> On Jun 18, 2020, at 10:57 AM, Louis Dionne via llvm-dev >> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Hi folks, >> >> Building any LLVM project currently requires invoking CMake inside >> <monorepo-root>/llvm, while setting the projects to enable in the >> LLVM_ENABLE_PROJECTS variable. This has the downside that CMake >> processing for the LLVM subproject happens even when one doesn't >> really need or want it. It's also not great from a build hygiene >> perspective, as LLVM globally sets some flags and subprojects pick >> them up, when they don't really mean to. For example, see this >> workaround: >> https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, >> where we need to account for some flags that might have been set >> globally by LLVM. >> >> I'm not sure about other projects, however this is quite problematic >> for projects part of the C++ runtime (libc++/libc++abi/libunwind). >> Indeed, we often try to build those projects targetting not widely >> supported platforms, where the overall LLVM build doesn't work. For >> example, trying to use the LLVM_ENABLE_PROJECTS approach for building >> libc++ for Apple's DriverKit environment doesn't work, since it has a >> few unusual things that the LLVM build chokes on. However, building >> libc++ standalone works just fine because it has far fewer >> requirements. It's also not just an issue of working vs not working: >> because of global flag pollution, building libc++ standalone and as >> part of the rest of LLVM can result in slightly different flags being >> used, which could cause important and hard-to-diagnose issues. >> >> Hence, I think we should introduce a way to build LLVM projects (or at >> least the runtimes) without going through >> <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a >> top-level <monorepo-root>/CMakeLists.txt whose sole job is to include >> subprojects. We could also place basic LLVM-wide things like the check >> for the minimum CMake version there. More specifically, I would like >> to be able to do: >> >> Â Â $ cd <monorepo-root> >> Â Â $ mkdir build >> Â Â $ (cd build && cmake <monorepo-root> >> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") >> >> Pretty much the only difference with today is that you'd use `cmake >> <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. >> >> Like I said, this is a problem for the runtime projects, but I'm not >> sure about other projects. For the runtime projects, another option >> would be to only allow standalone builds. However, the runtime >> projects are often built in lockstep, and so running three CMake >> commands when one would suffice is both annoying and also an easy way >> to screw things up. Furthermore, the current standalone builds add >> complexity to the projects, because they require the ability to point >> to arbitrary headers/libraries from the other projects, when we really >> always want to point to the just-built ones. >> >> Relationship with Petr Hosek's "Runtimes" build >> --------------------------------------------------------------- >> What I'm proposing isn't a replacement for itl. The "Runtimes" build >> can be seen as a driver that sets up the individual >> libc++/libc++abi/libunwind builds with the just-built toolchain, and >> for the provided targets. That's really great, however it is built *on >> top of* the basic libc++/libc++abi/libunwind builds. So basically, >> after my proposal, the "Runtimes" build could simply build all >> elements from the runtime with a single CMake invocation, as opposed >> to multiple invocations. >> >> Thoughts? >> Louis >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Renato Golin via llvm-dev
2020-Jun-18 18:44 UTC
[llvm-dev] RFC: A top level monorepo CMake file
Hi Louis, I think that's a good cleanup, will make things more "reasonable", especially for new developers and may clean up a lot of the CMake dependencies we have. However, it will touch most (every?) sub-project, and have marginal benefits other than "feeling nice". Furthermore, some of the problems you describe below can already be fixed without changing the root CMake file. Maybe not as cleanly, but close enough. So, while I commend your effort, I think an easier approach would be to slowly fix the more critical problems in our usage of CMake and then move the root. On Thu, 18 Jun 2020 at 18:57, Louis Dionne via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues.In the end, we'll have to make sure it works for all existing builds, upstream and downstream, and that's not trivial. That's why I recommend we do one small step at a time.> What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations.Essentially, we may want to build the runtimes stand-alone, or multiple variations when selecting multiple targets_to_build, and that's not trivial. It would be good if we could join the infrastructure into one place and do it right. While not a requirement for your proposal, I fear it will create too many unforeseen problems as is. cheers, --renato
Louis Dionne via llvm-dev
2020-Jun-18 18:55 UTC
[llvm-dev] RFC: A top level monorepo CMake file
> On Jun 18, 2020, at 14:44, Renato Golin <rengolin at gmail.com> wrote: > > Hi Louis, > > I think that's a good cleanup, will make things more "reasonable", > especially for new developers and may clean up a lot of the CMake > dependencies we have. > > However, it will touch most (every?) sub-project, and have marginal > benefits other than "feeling nice". > > Furthermore, some of the problems you describe below can already be > fixed without changing the root CMake file. Maybe not as cleanly, but > close enough.I disagree. The root cause of the problem is that including <monorepo-root>/llvm/CMakeLists.txt is equivalent to asking to compile LLVM for the target we're targeting. However, this may simply not make sense for some target platforms, where one would never build a compiler for that target. I guess we could add conditionals to guard parts of llvm/CMakeLists.txt (and children of it) so that it appears to work on all targets we care about, but that would just be adding complexity to llvm/CMakeLists.txt, when what we *really* want to do is just bypass its CMake configuration altogether.> > So, while I commend your effort, I think an easier approach would be > to slowly fix the more critical problems in our usage of CMake and > then move the root.I think we both need to fix our CMake usage (like global variables, global flags setting and other anti patterns), and also allow bypassing projects that we don't want to build. I suspect the only reason why things were set up inside llvm/CMakeLists.txt is that historically, there was simply no monorepo root we could add a CMake file to. If there had been one, I strongly suspect things would have been the way I describe since the start. That being said, I agree the changes I suggest need to be done step by step, and that's the way I planned on doing it if we get consensus. Louis> > On Thu, 18 Jun 2020 at 18:57, Louis Dionne via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. > > In the end, we'll have to make sure it works for all existing builds, > upstream and downstream, and that's not trivial. That's why I > recommend we do one small step at a time. > >> What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. > > Essentially, we may want to build the runtimes stand-alone, or > multiple variations when selecting multiple targets_to_build, and > that's not trivial. It would be good if we could join the > infrastructure into one place and do it right. While not a requirement > for your proposal, I fear it will create too many unforeseen problems > as is. > > cheers, > --renato
Tom Stellard via llvm-dev
2020-Jun-18 21:25 UTC
[llvm-dev] RFC: A top level monorepo CMake file
On 06/18/2020 11:27 AM, Steven Wu via llvm-dev wrote:> I like the proposal but I would like to go even further. If we are going to create a top level CMake file, we should just go ahead and eliminate all the standalone build configuration. The standalone build should just be `cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS=standalone-project ...`. That means less build configuration to maintain which is always good. >Eliminating stand-alone builds would be an inconvenience for us in Fedora, since this is how we build LLVM packages. However, I think we may have different definitions of what a stand-alone build is. Does your proposal mean that `cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS=lld ..` would build lld only without llvm and be a replacement for what I consider to be a stand-alone build, which is `cmake <monorepo-root>/lld ...` -Tom> That also means that we can refactor some of the cmake modules to put into the top level directories so sub-projects can just reuse them without duping the code worrying they are not available in the standalone build today. > > Steven > >> On Jun 18, 2020, at 10:57 AM, Louis Dionne via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Hi folks, >> >> Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, where we need to account for some flags that might have been set globally by LLVM. >> >> I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. >> >> Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: >> >> $ cd <monorepo-root> >> $ mkdir build >> $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") >> >> Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. >> >> Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. >> >> Relationship with Petr Hosek's "Runtimes" build >> --------------------------------------------------------------- >> What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. >> >> Thoughts? >> Louis >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Petr Hosek via llvm-dev
2020-Jun-18 21:26 UTC
[llvm-dev] RFC: A top level monorepo CMake file
+1 for this change. On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne <ldionne at apple.com> wrote:> Hi folks, > > Building any LLVM project currently requires invoking CMake inside > <monorepo-root>/llvm, while setting the projects to enable in the > LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing > for the LLVM subproject happens even when one doesn't really need or want > it. It's also not great from a build hygiene perspective, as LLVM globally > sets some flags and subprojects pick them up, when they don't really mean > to. For example, see this workaround: > https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, > where we need to account for some flags that might have been set globally > by LLVM. > > I'm not sure about other projects, however this is quite problematic for > projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we > often try to build those projects targetting not widely supported > platforms, where the overall LLVM build doesn't work. For example, trying > to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's > DriverKit environment doesn't work, since it has a few unusual things that > the LLVM build chokes on. However, building libc++ standalone works just > fine because it has far fewer requirements. It's also not just an issue of > working vs not working: because of global flag pollution, building libc++ > standalone and as part of the rest of LLVM can result in slightly different > flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at > least the runtimes) without going through > <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level > <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We > could also place basic LLVM-wide things like the check for the minimum > CMake version there. More specifically, I would like to be able to do: > > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> > -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake > <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Like I said, this is a problem for the runtime projects, but I'm not sure > about other projects. For the runtime projects, another option would be to > only allow standalone builds. However, the runtime projects are often built > in lockstep, and so running three CMake commands when one would suffice is > both annoying and also an easy way to screw things up. Furthermore, the > current standalone builds add complexity to the projects, because they > require the ability to point to arbitrary headers/libraries from the other > projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can > be seen as a driver that sets up the individual libc++/libc++abi/libunwind > builds with the just-built toolchain, and for the provided targets. That's > really great, however it is built *on top of* the basic > libc++/libc++abi/libunwind builds. So basically, after my proposal, the > "Runtimes" build could simply build all elements from the runtime with a > single CMake invocation, as opposed to multiple invocations. >I think there may be a misunderstanding of how the "runtimes" build work. It already uses an equivalent of: cmake -DCMAKE_CXX_COMPILER=<path to just built clang> -DCMAKE_CXX_COMPILER=<path to just built clang++> <options> -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind" <llvm-project-root> The reason why it doesn't do exactly that is because LLVM's root CMakeLists.txt does too many things, and doesn't do some of the things we need. Instead we use a trick where llvm/runtimes/CMakeLists.txt re-invokes itself for different targets. When invoked as a the root file it drives the build for all runtimes, resembling the CMake invocation above, but it also exposes a "build API" to the parent build, so as the user of the "runtimes" build, you use the parent build and it drives the child builds through this API. When using runtimes build, you have to make one CMake invocation to build tools, and then one CMake invocation per-target to build runtimes (but *not* one CMake per project). I don't think there's a way to get down to a single CMake invocation unless CMake gains support for "scoped toolchains" (today there's only one global host toolchain), which is something that GN has and why in GN this is possible. I don't think that having a top-level CMake file changes anything for the "runtimes" build. We could consider merging llvm/runtimes/CMakeLists.txt into the top-level CMake file, but I don't see any immediate gains aside from clearer file structure. I think a bigger win, and not just for the runtimes build, would be to have a global CMake modules directory that would be shared by all subprojects avoiding the duplication we currently have, and allow sharing cached variables between runtimes which should significantly reduce the number of CMake checks we have to run. For example, today every runtime does the same set of checks to ensure your system has libc, libm, pthreads, etc. We really should only ever have to run those once per CMake invocation. Thoughts?> Louis > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200618/f35f0c91/attachment.html>
Mehdi AMINI via llvm-dev
2020-Jun-19 08:47 UTC
[llvm-dev] RFC: A top level monorepo CMake file
FWIW: +1 for me. I actually looked into doing this a couple of times already, but too many things are tangled for me to manage it, in particular around the runtimes. Having someone who understands the runtime situation driving it would make sense. I think I also tried to do "too much at once" instead of a sequence of smaller NFC refactorings to get closer to the desired state. -- Mehdi On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi folks, > > Building any LLVM project currently requires invoking CMake inside > <monorepo-root>/llvm, while setting the projects to enable in the > LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing > for the LLVM subproject happens even when one doesn't really need or want > it. It's also not great from a build hygiene perspective, as LLVM globally > sets some flags and subprojects pick them up, when they don't really mean > to. For example, see this workaround: > https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, > where we need to account for some flags that might have been set globally > by LLVM. > > I'm not sure about other projects, however this is quite problematic for > projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we > often try to build those projects targetting not widely supported > platforms, where the overall LLVM build doesn't work. For example, trying > to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's > DriverKit environment doesn't work, since it has a few unusual things that > the LLVM build chokes on. However, building libc++ standalone works just > fine because it has far fewer requirements. It's also not just an issue of > working vs not working: because of global flag pollution, building libc++ > standalone and as part of the rest of LLVM can result in slightly different > flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at > least the runtimes) without going through > <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level > <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We > could also place basic LLVM-wide things like the check for the minimum > CMake version there. More specifically, I would like to be able to do: > > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> > -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake > <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Like I said, this is a problem for the runtime projects, but I'm not sure > about other projects. For the runtime projects, another option would be to > only allow standalone builds. However, the runtime projects are often built > in lockstep, and so running three CMake commands when one would suffice is > both annoying and also an easy way to screw things up. Furthermore, the > current standalone builds add complexity to the projects, because they > require the ability to point to arbitrary headers/libraries from the other > projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can > be seen as a driver that sets up the individual libc++/libc++abi/libunwind > builds with the just-built toolchain, and for the provided targets. That's > really great, however it is built *on top of* the basic > libc++/libc++abi/libunwind builds. So basically, after my proposal, the > "Runtimes" build could simply build all elements from the runtime with a > single CMake invocation, as opposed to multiple invocations. > > Thoughts? > Louis > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200619/739de70b/attachment.html>
Russell Gallop via llvm-dev
2020-Jun-19 10:45 UTC
[llvm-dev] RFC: A top level monorepo CMake file
+1 for having a top level CMakeLists, but for a different reason. Having many subproject CMakeLists.txt in the repo can be confusing for Visual Studio CMake support, which tries to parse all subproject CMakeLists.txt. AFAICT it isn't able to understand the structure with llvm/CMakeLists.txt as the entry point. I have worked around this by adding a simple top level CMakeLists.txt: cmake_minimum_required(VERSION 3.4.3) project(llvm-top-level) add_subdirectory(llvm) Which helps this use case. Note that this does affect the layout of the build directory, moving things down into an llvm directory*. I don't know whether this helps other GUIs/tools, but a top level CMakeLists.txt is more conventional so it might. I also strongly agree with doing this in small, planned, steps. There might be a lot of use cases which are affected by these changes. Regards Russ * which can be fixed up in llvm/CMakeLists.txt: *** 292,295 **** # They are used as destination of target generators. ! set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) ! set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) if(WIN32 OR CYGWIN) --- 292,295 ---- # They are used as destination of target generators. ! set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) ! set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) if(WIN32 OR CYGWIN) On Fri, 19 Jun 2020 at 09:48, Mehdi AMINI via llvm-dev < llvm-dev at lists.llvm.org> wrote:> FWIW: +1 for me. > > I actually looked into doing this a couple of times already, but too many > things are tangled for me to manage it, in particular around the runtimes. > Having someone who understands the runtime situation driving it would make > sense. > I think I also tried to do "too much at once" instead of a sequence of > smaller NFC refactorings to get closer to the desired state. > > -- > Mehdi > > > > On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hi folks, >> >> Building any LLVM project currently requires invoking CMake inside >> <monorepo-root>/llvm, while setting the projects to enable in the >> LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing >> for the LLVM subproject happens even when one doesn't really need or want >> it. It's also not great from a build hygiene perspective, as LLVM globally >> sets some flags and subprojects pick them up, when they don't really mean >> to. For example, see this workaround: >> https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507, >> where we need to account for some flags that might have been set globally >> by LLVM. >> >> I'm not sure about other projects, however this is quite problematic for >> projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we >> often try to build those projects targetting not widely supported >> platforms, where the overall LLVM build doesn't work. For example, trying >> to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's >> DriverKit environment doesn't work, since it has a few unusual things that >> the LLVM build chokes on. However, building libc++ standalone works just >> fine because it has far fewer requirements. It's also not just an issue of >> working vs not working: because of global flag pollution, building libc++ >> standalone and as part of the rest of LLVM can result in slightly different >> flags being used, which could cause important and hard-to-diagnose issues. >> >> Hence, I think we should introduce a way to build LLVM projects (or at >> least the runtimes) without going through >> <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level >> <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We >> could also place basic LLVM-wide things like the check for the minimum >> CMake version there. More specifically, I would like to be able to do: >> >> $ cd <monorepo-root> >> $ mkdir build >> $ (cd build && cmake <monorepo-root> >> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") >> >> Pretty much the only difference with today is that you'd use `cmake >> <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. >> >> Like I said, this is a problem for the runtime projects, but I'm not sure >> about other projects. For the runtime projects, another option would be to >> only allow standalone builds. However, the runtime projects are often built >> in lockstep, and so running three CMake commands when one would suffice is >> both annoying and also an easy way to screw things up. Furthermore, the >> current standalone builds add complexity to the projects, because they >> require the ability to point to arbitrary headers/libraries from the other >> projects, when we really always want to point to the just-built ones. >> >> Relationship with Petr Hosek's "Runtimes" build >> --------------------------------------------------------------- >> What I'm proposing isn't a replacement for itl. The "Runtimes" build can >> be seen as a driver that sets up the individual libc++/libc++abi/libunwind >> builds with the just-built toolchain, and for the provided targets. That's >> really great, however it is built *on top of* the basic >> libc++/libc++abi/libunwind builds. So basically, after my proposal, the >> "Runtimes" build could simply build all elements from the runtime with a >> single CMake invocation, as opposed to multiple invocations. >> >> Thoughts? >> Louis >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200619/cc339d19/attachment.html>
Louis Dionne via llvm-dev
2020-Jun-19 14:26 UTC
[llvm-dev] RFC: A top level monorepo CMake file
> On Jun 18, 2020, at 17:26, Petr Hosek <phosek at chromium.org> wrote: > > +1 for this change. > > On Thu, Jun 18, 2020 at 10:57 AM Louis Dionne <ldionne at apple.com <mailto:ldionne at apple.com>> wrote: > Hi folks, > > Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507 <https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507>, where we need to account for some flags that might have been set globally by LLVM. > > I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: > > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. > > I think there may be a misunderstanding of how the "runtimes" build work. It already uses an equivalent of: > > cmake -DCMAKE_CXX_COMPILER=<path to just built clang> -DCMAKE_CXX_COMPILER=<path to just built clang++> <options> -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind" <llvm-project-root> > > The reason why it doesn't do exactly that is because LLVM's root CMakeLists.txt does too many things, and doesn't do some of the things we need. > > Instead we use a trick where llvm/runtimes/CMakeLists.txt re-invokes itself for different targets. When invoked as a the root file it drives the build for all runtimes, resembling the CMake invocation above, but it also exposes a "build API" to the parent build, so as the user of the "runtimes" build, you use the parent build and it drives the child builds through this API. > > When using runtimes build, you have to make one CMake invocation to build tools, and then one CMake invocation per-target to build runtimes (but *not* one CMake per project). I don't think there's a way to get down to a single CMake invocation unless CMake gains support for "scoped toolchains" (today there's only one global host toolchain), which is something that GN has and why in GN this is possible. > > I don't think that having a top-level CMake file changes anything for the "runtimes" build. We could consider merging llvm/runtimes/CMakeLists.txt into the top-level CMake file, but I don't see any immediate gains aside from clearer file structure.I agree with everything here. I didn't know the runtimes build used a single CMake invocation per target, though, thanks for correcting me on this. But the point I was trying to make, which you've made even clearer, is that there's basically no relationship between my proposed change and the runtimes build. Louis> > I think a bigger win, and not just for the runtimes build, would be to have a global CMake modules directory that would be shared by all subprojects avoiding the duplication we currently have, and allow sharing cached variables between runtimes which should significantly reduce the number of CMake checks we have to run. For example, today every runtime does the same set of checks to ensure your system has libc, libm, pthreads, etc. We really should only ever have to run those once per CMake invocation. > > Thoughts? > Louis-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200619/7ddc4875/attachment-0001.html>
Louis Dionne via llvm-dev
2020-Jun-22 15:00 UTC
[llvm-dev] [libcxx-dev] RFC: A top level monorepo CMake file
Folks, It looks like nobody is strongly objected to this, and a bunch of people would be happy with making those changes. Some concerns about scope and feasibility have been raised, however I believe tackling those concerns is just a matter of laying out the steps more concretely. So unless someone raises a voice here, I'll start exploring how we can make the changes I explained incrementally. I'll post again to the list with a rough plan of how I envision things, and hopefully a few patches to accompany that. We can then have a more concrete discussion that's productive for everyone! Cheers, Louis> On Jun 18, 2020, at 13:57, Louis Dionne via libcxx-dev <libcxx-dev at lists.llvm.org> wrote: > > Hi folks, > > Building any LLVM project currently requires invoking CMake inside <monorepo-root>/llvm, while setting the projects to enable in the LLVM_ENABLE_PROJECTS variable. This has the downside that CMake processing for the LLVM subproject happens even when one doesn't really need or want it. It's also not great from a build hygiene perspective, as LLVM globally sets some flags and subprojects pick them up, when they don't really mean to. For example, see this workaround: https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507 <https://github.com/llvm/llvm-project/blob/master/libcxx/CMakeLists.txt#L503-L507>, where we need to account for some flags that might have been set globally by LLVM. > > I'm not sure about other projects, however this is quite problematic for projects part of the C++ runtime (libc++/libc++abi/libunwind). Indeed, we often try to build those projects targetting not widely supported platforms, where the overall LLVM build doesn't work. For example, trying to use the LLVM_ENABLE_PROJECTS approach for building libc++ for Apple's DriverKit environment doesn't work, since it has a few unusual things that the LLVM build chokes on. However, building libc++ standalone works just fine because it has far fewer requirements. It's also not just an issue of working vs not working: because of global flag pollution, building libc++ standalone and as part of the rest of LLVM can result in slightly different flags being used, which could cause important and hard-to-diagnose issues. > > Hence, I think we should introduce a way to build LLVM projects (or at least the runtimes) without going through <monorepo-root>/llvm/CMakeLists.txt. What I suggest is to have a top-level <monorepo-root>/CMakeLists.txt whose sole job is to include subprojects. We could also place basic LLVM-wide things like the check for the minimum CMake version there. More specifically, I would like to be able to do: > > $ cd <monorepo-root> > $ mkdir build > $ (cd build && cmake <monorepo-root> -DLLVM_ENABLE_PROJECTS="<projects-to-enable>") > > Pretty much the only difference with today is that you'd use `cmake <monorepo-root>` instead of `cmake <monorepo-root>/llvm`. > > Like I said, this is a problem for the runtime projects, but I'm not sure about other projects. For the runtime projects, another option would be to only allow standalone builds. However, the runtime projects are often built in lockstep, and so running three CMake commands when one would suffice is both annoying and also an easy way to screw things up. Furthermore, the current standalone builds add complexity to the projects, because they require the ability to point to arbitrary headers/libraries from the other projects, when we really always want to point to the just-built ones. > > Relationship with Petr Hosek's "Runtimes" build > --------------------------------------------------------------- > What I'm proposing isn't a replacement for itl. The "Runtimes" build can be seen as a driver that sets up the individual libc++/libc++abi/libunwind builds with the just-built toolchain, and for the provided targets. That's really great, however it is built *on top of* the basic libc++/libc++abi/libunwind builds. So basically, after my proposal, the "Runtimes" build could simply build all elements from the runtime with a single CMake invocation, as opposed to multiple invocations. > > Thoughts? > Louis > > _______________________________________________ > libcxx-dev mailing list > libcxx-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200622/3c356e2d/attachment-0001.html>