[llvm-dev] [RFC] LLVM Directory Structure Changes (was Re: [PATCH] D20992: [CMake] Add LLVM runtimes directory)
Craig, Ben via llvm-dev
llvm-dev at lists.llvm.org
Thu Jun 9 11:26:02 PDT 2016
I'm great with moving the runtimes into their own directory and making
cmake modules to standardize an interface between the LLVM build process
and the runtime build process. I would like to ask for more though.
I find working with the runtimes a bit frustrating at times, and I think
a lot of that frustration stems from the second-class nature of the
runtime build process. The "best" way to build just the runtimes today
is to clone them in the llvm tree, pass a very long cmake line, then run
a very specific make / ninja line (i.e. ninja cxx, ninja
check-libcxxabi). This is even the case if I don't want to use the
freshly generated compiler. Here are some specific nuisances that
running in-tree has caused me:
* I routinely need to pull a new LLVM for new cmake files, even though
I am not building LLVM.
* I don't get to use "standard" commands to build and test the
components I work with. I want to just run make / ninja with no
arguments, but instead, I need to build specific targets.
* Choices made for LLVM's build end up affecting mine, and I don't
have a good way to change them. For example, I wanted to perform
some libcxx builds without -Wl,-z,defs. I had to do some wacky
string filtering to remove it from the compile line after the fact,
instead of preventing it from getting added in the first place.
There wasn't a flag available on the LLVM side to disable it at
configure time.
* To get cmake to work, I have to set HAVE_CXX_ATOMICS_WITHOUT_LIB,
even though I have no intention of building LLVM. I then get to set
LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB too, because reasons.
* Multi-libs require multiple independent build directories, with all
the associated cmake overhead.
So why not run out of tree instead you may ask?
* No lit tests or lit utilities (FileCheck, not, etc...)
* Even more difficult to manage dependencies between libcxxabi and libcxx
So some things I would like to see...
* Standalone runtime builds should use the "normal" build interfaces
(bare make, make all, make check, make install. s/make/ninja as
desired).
* For in-tree builds, LLVM would use the new cmake ExternalProject
feature. This way LLVM's in-tree support could be implemented in
terms of the runtime's "normal" build interfaces. LLVM may also
define a refinement of that interface to provide extra LLVM
information on top.
o For example, maybe all llvm runtime projects get passed
something like LLVM_RUNTIME_LIBCXXABI_PRESENT and
LLVM_RUNTIME_LIBCXXABI_PATH, and those projects can act on that
or not.
* Developers using standalone builds can use the same "LLVM build"
interface as the in-tree builds use.
* Break out testing infrastructure to a common repo, so that the
runtimes can have access to the testing "banana" without dragging
along the LLVM "gorilla".
On 6/9/2016 12:20 PM, Chris Bieneman via llvm-dev wrote:
> Moving to llvm-dev (I think this has gone a bit further than a patch
> review discussion)
>
> In hindsight I probably should have explained more of my thinking on
> this with the patch, or done an RFC on llvm-dev to start with. I’l do
> that now, and answer the questions along the way. I sent a separate
> email discussing Justin’s patch review feedback.
>
> In the build system today there is no strong distinction between
> ‘projects’ and ‘tools’. There are a few subtle differences, but I’m
> not sure any of them really matter. The differences are:
>
> (1) The projects directory is always configured, tools can be disabled
> using LLVM_INCLUDE_TOOLS=Off (projects and tools can both be
> individually disabled too)
> (2) Projects are configured before tools, so tools can rely on targets
> being created for projects (we don’t really use this, and anywhere we
> are is probably a bug)
> (3) Some projects have special handling. For example test-suite isn’t
> actually treated as a project, it has special handling in
> LLVM/CMakeLists.txt:727, and Compiler-RT is handled by clang if you
> set LLVM_BUILD_EXTERNAL_COMPILER_RT=On.
>
> With this in mind I was thinking about the general usability of our
> build system. The distinction between a project and a tool is not very
> clear. At a high level I see three different use cases that are
> covered by our current projects & tools directories.
>
> (1) Projects that are configured with LLVM
> (2) Runtime projects that should be configured using the just-built tools
> (3) The LLVM test-suite, which is really just external tests that
> should be configured and run with the just-built tools
>
> My proposal is that we make the tools subdirectory the *only* place
> for projects that fall into category 1. I don’t think there is any
> technical reason to drop an in-tree project into projects over tools
> today, and I think we migrating people who are doing that away from it
> should be easy.
>
> Second I want to add a “runtimes” directory to LLVM to cover case 2
> (see D20992). The idea behind this is to use common code in LLVM to
> support building runtimes. This will allow the full LLVM toolchain to
> be visible during configuration. I will abstract this functionality
> into an installed CMake module so that Clang can use it for
> out-of-tree clang builds.
>
> Lastly we need to give the test-suite a new home. I’m not super
> concerned with where we do that. It could be under tests, it could
> just be at the root of the LLVM directory. I don’t think it matters
> too much because it is a one-off. Thoughts welcome.
>
> My proposed patch makes the runtimes directory work for Compiler-RT,
> but it doesn’t yet handle libcxxabi, libcxx and libunwind. There is
> some special case handling between libcxxabi and libcxx that will need
> to be handled to make the dependencies work between the two, and I
> still need to work that out.
>
> If we want to go with this proposal I envision the transition being
> multi-staged:
>
> (1) Adding the new functionality, getting it up and fully working for
> all runtime projects - this will involve changes to runtime projects
> (2) Work with bot maintainers to migrate bots, and fix any issues that
> come up
> (3) Add support for a new secondary location for the test-suite
> (4) Set a date for removing the projects directory, post patches
> including updated documentation
> (5) Remove the projects directory entirely
>
> Thoughts?
> -Chris
>
>> On Jun 8, 2016, at 6:59 PM, Chandler Carruth <chandlerc at gmail.com
>> <mailto:chandlerc at gmail.com>> wrote:
>>
>> On Wed, Jun 8, 2016 at 4:39 PM Justin Bogner via llvm-commits
>> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>>
>> Chris Bieneman <beanz at apple.com <mailto:beanz at apple.com>> writes:
>> > beanz created this revision.
>> > beanz added reviewers: chandlerc, bogner.
>> > beanz added a subscriber: llvm-commits.
>> >
>> > There are a few LLVM projects that produce runtime libraries.
>> Ideally
>> > runtime libraries should be built differently than other projects,
>> > specifically they should be built using the just-built toolchain.
>> >
>> > There is support for building compiler-rt in this way from the
>> clang
>> > build. Moving this logic into the LLVM build is interesting
>> because it
>> > provides a simpler way to extend the just-built toolchain to
>> include
>> > LLD and the LLVM object file tools.
>> >
>> > Once this functionality is better fleshed out and tested we’ll
>> want to
>> > encapsulate it in a module that can be used for clang standalone
>> > builds, and we’ll want to make it the default way to build
>> compiler-rt.
>> >
>> > With this patch applied there is no immediate change in the build.
>> > Moving compiler-rt out from llvm/projects into llvm/runtimes
>> enables
>> > the functionality.
>>
>> This seems reasonable, but I am a little worried about how
>> transitioning
>> to the new system will work. Will everyone have to move their
>> compiler-rt checkout? Will we continue to support compiler-rt in
>> either
>> place? Both of these are workable, but neither is great. Thoughts?
>>
>>
>> I share your concerns, but I also kind of like the direction this is
>> going.
>>
>> But there is a higher-level meta-point: do we want to keep the
>> 'projects' directory *at all*.
>>
>> Every single resident of it I can think of except for the test-suite
>> is either dead (dragonegg) or a runtime library.
>>
>> I think we should either have all the build-integrated projects in a
>> single 'projects' directory (including LLD and Clang), or we should
>> have none of them and use more domain relevant organization (today
>> "tools", you're adding "runtimes", maybe we move the test-suite to go
>> under one of the test directories).
>>
>> I think we should have a consistent plan here before moving stuff.
>> But once we have it, I think we shouldn't be afraid of re-organizing
>> stuff to make more sense, and just work to get folks to update their
>> checkouts.
>>
>> -Chandler
>>
>>
>> > This code has a few improvements over the method provided by
>> > LLVM_BUILD_EXTERNAL_COMPILER_RT. Specifically the sub-ninja
>> command is
>> > always invoked, so changes to compiler-rt source files will get
>> built
>> > properly, so this patch can be used for iterative development with
>> > just-built tools.
>> >
>> >http://reviews.llvm.org/D20992
>> >
>> > Files:
>> > CMakeLists.txt
>> > cmake/modules/LLVMExternalProjectUtils.cmake
>> > runtimes/CMakeLists.txt
>> >
>> > Index: runtimes/CMakeLists.txt
>> > ===================================================================
>> > --- /dev/null
>> > +++ runtimes/CMakeLists.txt
>> > @@ -0,0 +1,16 @@
>> > +include(LLVMExternalProjectUtils)
>> > +
>> > +# Discover the projects that use CMake in the subdirectories.
>> > +# Note that explicit cmake invocation is required every time a
>> new project is
>> > +# added or removed.
>> > +
>> > +add_custom_target(runtimes)
>> > +
>> > +file(GLOB entries *)
>> > +foreach(entry ${entries})
>> > + if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
>> > + get_filename_component(projName ${entry} NAME)
>> > + llvm_ExternalProject_Add(${projName} ${entry} USE_TOOLCHAIN)
>> > + add_dependencies(runtimes ${projName})
>> > + endif()
>> > +endforeach(entry)
>> > Index: cmake/modules/LLVMExternalProjectUtils.cmake
>> > ===================================================================
>> > --- cmake/modules/LLVMExternalProjectUtils.cmake
>> > +++ cmake/modules/LLVMExternalProjectUtils.cmake
>> > @@ -29,7 +29,8 @@
>> > # Extra targets in the subproject to generate targets for
>> > # )
>> > function(llvm_ExternalProject_Add name source_dir)
>> > - cmake_parse_arguments(ARG
>> "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL"
>> > + cmake_parse_arguments(ARG
>> > + "USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
>> > "SOURCE_DIR"
>> >
>> "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS"
>> ${ARGN})
>> > canonicalize_tool_name(${name} nameCanon)
>> > @@ -52,6 +53,10 @@
>> > endif()
>> > endforeach()
>> >
>> > + if(ARG_ALWAYS_CLEAN)
>> > + set(always_clean clean)
>> > + endif()
>> > +
>> > list(FIND TOOLCHAIN_TOOLS clang FOUND_CLANG)
>> > if(FOUND_CLANG GREATER -1)
>> > set(CLANG_IN_TOOLCHAIN On)
>> > @@ -135,6 +140,14 @@
>> > CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
>> > ${compiler_args}
>> > -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
>> > + -DLLVM_CONFIG_PATH=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-config
>> > + -DLLVM_LIBRARY_OUTPUT_INTDIR=${LLVM_LIBRARY_OUTPUT_INTDIR}
>> > + -DLLVM_RUNTIME_OUTPUT_INTDIR=${LLVM_RUNTIME_OUTPUT_INTDIR}
>> > + -DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX}
>> > + -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
>> > + -DPACKAGE_VERSION=${PACKAGE_VERSION}
>> > + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
>> > + -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
>>
>> How did you decide which variables need to be passed through like
>> this?
>> The set seems somewhat arbitrary, but I may be missing something
>> obvious.
>>
>> > ${ARG_CMAKE_ARGS}
>> > ${PASSTHROUGH_VARIABLES}
>> > INSTALL_COMMAND ""
>> > @@ -152,7 +165,7 @@
>> > ExternalProject_Add_Step(${name} force-rebuild
>> > COMMAND ${run_build}
>> > COMMENT "Forcing rebuild of ${name}"
>> > - DEPENDEES configure clean
>> > + DEPENDEES configure ${always_clean}
>>
>> I'm not sure I understand what this does. If I had to guess I'd
>> say that
>> when ALWAYS_CLEAN is passed the rebuild of the external project
>> always
>> invokes clean first, but if it's not passed we'll just invoke the
>> external build and allow it to be incremental if appropriate. Is that
>> right?
>>
>> > DEPENDS ${ALWAYS_REBUILD} ${ARG_DEPENDS} ${TOOLCHAIN_BINS}
>> > ${cmake_3_4_USES_TERMINAL} )
>> > endif()
>> > Index: CMakeLists.txt
>> > ===================================================================
>> > --- CMakeLists.txt
>> > +++ CMakeLists.txt
>> > @@ -720,6 +720,8 @@
>> > add_subdirectory(tools)
>> > endif()
>> >
>> > +add_subdirectory(runtimes)
>> > +
>> > if( LLVM_INCLUDE_EXAMPLES )
>> > add_subdirectory(examples)
>> > endif()
>> > @@ -730,7 +732,8 @@
>> > llvm_ExternalProject_Add(test-suite
>> ${LLVM_MAIN_SRC_DIR}/projects/test-suite
>> > USE_TOOLCHAIN
>> > EXCLUDE_FROM_ALL
>> > - NO_INSTALL)
>> > + NO_INSTALL
>> > + ALWAYS_CLEAN)
>> > endif()
>> > add_subdirectory(test)
>> > add_subdirectory(unittests)
>> >
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160609/8a41cdbe/attachment.html>
More information about the llvm-dev
mailing list