[PATCH] D20992: [CMake] Add LLVM runtimes directory

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 22 16:13:59 PDT 2016


> On Jun 22, 2016, at 2:11 PM, Justin Bogner <mail at justinbogner.com> wrote:
> 
> Chris Bieneman <beanz at apple.com <mailto:beanz at apple.com>> writes:
>> beanz updated this revision to Diff 61451.
>> beanz added a comment.
>> 
>> I kinda went a bit off into the woods after the llvm-dev thread, and I
>> think I came back with something either interesting or insane... you
>> decide.
>> 
>> This patch changed a few things about how I'm handling the runtimes
>> subdirectory. First, it handles the compiler-rt builtin library
>> dependency by building the builtins first as their own external
>> project call. Second, it glumps all the other runtime libraries
>> (including compiler-rt's sanitizers) into a single external project by
>> using the runtimes/CMakeLists.txt file as the top-level CMake.
>> 
>> This is interesting for a few reasons. The biggest is a potential for
>> reduced CMake-overhead when building runtime libraries. Additionally
>> it will allow cross-project dependencies to be more easily modeled in
>> CMake because the runtime libraries will be able to be aware of the
>> targets coming from other runtime projects.
>> 
>> Thoughts?
> 
> This is, well, interesting. Are there any pitfalls we'll have to be
> aware of in terms of how each runtime's cmake is set up?

In the short term, doing it this way will allow some flexibility in getting it to work because we have a place in CMake to normalize the interfaces between runtime libraries. Longer term, I think we should move toward having all the runtime libraries conform to a consistent interface (ideally LLVMConfig.cmake).

> 
> I think the advantages are worth the extra complexity, so this LGTM as
> long as the answer to my question above isn't too scary, but please do
> add some comments explaining what's going on. This is strange enough
> that it's hard to follow as is.

Yea, comments would be good, this is a bit magic. I will update the patch shortly.

-Chris

> 
>> 
>> http://reviews.llvm.org/D20992 <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,67 @@
>> +# 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.
>> +
>> +file(GLOB entries *)
>> +foreach(entry ${entries})
>> +  if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
>> +    list(APPEND runtimes ${entry})
>> +  endif()
>> +endforeach()
>> +
>> +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
>> +
>> +  cmake_minimum_required(VERSION 3.4.3)
> 
> I guess this is in here because it's redundant in the other path?
> 
>> +  
>> +  list(INSERT CMAKE_MODULE_PATH 0
>> +    "${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
>> +    "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
>> +    "${LLVM_BINARY_DIR}/lib/cmake/llvm"
>> +  )
>> +
>> +  include(LLVMConfig)
>> +
>> +  set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR})
>> +  set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_BINARY_DIR})
>> +
> 
> A comment like "configure all of the runtimes together in a single cmake
> invocation" would probably help here.
> 
>> +  foreach(entry ${runtimes})
>> +    get_filename_component(projName ${entry} NAME)
>> +
>> +    # TODO: Clean this up as part of an interface standardization
>> +    string(REPLACE "-" "_" canon_name ${projName})
>> +    string(TOUPPER ${canon_name} canon_name)
>> +    # The subdirectories need to treat this as standalone builds
>> +    set(${canon_name}_STANDALONE_BUILD On)
>> +    set(${canon_name}_BUILT_STANDALONE On)
>> +
>> +    add_subdirectory(${projName})
>> +  endforeach()
>> +
>> +else()
>> +  include(LLVMExternalProjectUtils)
>> +
>> +  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt)
>> +    llvm_ExternalProject_Add(builtins
>> +                             ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt/lib/builtins
>> +                             PASSTHROUGH_PREFIXES COMPILER_RT
>> +                             USE_TOOLCHAIN)
>> +    set(deps builtins)
>> +  endif()
>> +
>> +  foreach(entry ${runtimes})
>> +    get_filename_component(projName ${entry} NAME)
>> +    string(REPLACE "-" "_" canon_name ${projName})
>> +    string(TOUPPER ${canon_name} canon_name)
>> +    list(APPEND prefixes ${canon_name})
>> +  endforeach()
> 
> Maybe explain that the prefix collection here is defining which cmake
> variables will be available in the child invocation?
> 
>> +
>> +  if(runtimes)
>> +    llvm_ExternalProject_Add(runtimes
>> +                             ${CMAKE_CURRENT_SOURCE_DIR}
>> +                             DEPENDS ${deps} llvm-config
>> +                             # Builtins were built separately above
>> +                             CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=Off
>> +                             PASSTHROUGH_PREFIXES ${prefixes}
>> +                             USE_TOOLCHAIN)
> 
> Probably worth pointing out that this recursively configures and follows
> the other branch of the if.
> 
>> +  endif()
>> +endif()
>> Index: cmake/modules/LLVMExternalProjectUtils.cmake
>> ===================================================================
>> --- cmake/modules/LLVMExternalProjectUtils.cmake
>> +++ cmake/modules/LLVMExternalProjectUtils.cmake
>> @@ -19,19 +19,25 @@
>> #     Exclude this project from the all target
>> #   NO_INSTALL
>> #     Don't generate install targets for this project
>> +#   ALWAYS_CLEAN
>> +#     Always clean the sub-project before building
>> #   CMAKE_ARGS arguments...
>> #     Optional cmake arguments to pass when configuring the project
>> #   TOOLCHAIN_TOOLS targets...
>> #     Targets for toolchain tools (defaults to clang;lld)
>> #   DEPENDS targets...
>> #     Targets that this project depends on
>> #   EXTRA_TARGETS targets...
>> #     Extra targets in the subproject to generate targets for
>> +#   PASSTHROUGH_PREFIXES prefix...
>> +#     Extra variable prefixes (name is always included) to pass down
>> #   )
>> 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})
>> +    "CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES"
>> +    ${ARGN})
>>   canonicalize_tool_name(${name} nameCanon)
>>   if(NOT ARG_TOOLCHAIN_TOOLS)
>>     set(ARG_TOOLCHAIN_TOOLS clang lld)
>> @@ -52,6 +58,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)
>> @@ -71,15 +81,18 @@
>>     USES_TERMINAL
>>     )
>> 
>> -  # Find all variables that start with COMPILER_RT and populate a variable with
>> -  # them.
>> +  # Find all variables that start with a prefix and propagate them through
>>   get_cmake_property(variableNames VARIABLES)
>> -  foreach(variableName ${variableNames})
>> -    if(variableName MATCHES "^${nameCanon}")
>> -      string(REPLACE ";" "\;" value "${${variableName}}")
>> -      list(APPEND PASSTHROUGH_VARIABLES
>> -        -D${variableName}=${value})
>> -    endif()
>> +
>> +  list(APPEND ARG_PASSTHROUGH_PREFIXES ${nameCanon})
>> +  foreach(prefix ${ARG_PASSTHROUGH_PREFIXES})
>> +    foreach(variableName ${variableNames})
>> +      if(variableName MATCHES "^${prefix}")
>> +        string(REPLACE ";" "\;" value "${${variableName}}")
>> +        list(APPEND PASSTHROUGH_VARIABLES
>> +          -D${variableName}=${value})
>> +      endif()
>> +    endforeach()
>>   endforeach()
>> 
>>   if(ARG_USE_TOOLCHAIN)
>> @@ -117,6 +130,12 @@
>>     CMAKE_ARGS ${${nameCanon}_CMAKE_ARGS}
>>                ${compiler_args}
>>                -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
>> +               -DLLVM_BINARY_DIR=${PROJECT_BINARY_DIR}
>> +               -DLLVM_CONFIG_PATH=$<TARGET_FILE:llvm-config>
>> +               -DLLVM_ENABLE_WERROR=${LLVM_ENABLE_WERROR}
>> +               -DPACKAGE_VERSION=${PACKAGE_VERSION}
>> +               -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
>> +               -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
>>                ${ARG_CMAKE_ARGS}
>>                ${PASSTHROUGH_VARIABLES}
>>     INSTALL_COMMAND ""
>> @@ -138,6 +157,7 @@
>>     DEPENDEES configure
>>     ${force_deps}
>>     WORKING_DIRECTORY ${BINARY_DIR}
>> +    EXCLUDE_FROM_MAIN 1
>>     USES_TERMINAL 1
>>     )
>>   ExternalProject_Add_StepTargets(${name} clean)
>> Index: CMakeLists.txt
>> ===================================================================
>> --- CMakeLists.txt
>> +++ CMakeLists.txt
>> @@ -732,6 +732,8 @@
>>   add_subdirectory(tools)
>> endif()
>> 
>> +add_subdirectory(runtimes)
>> +
>> if( LLVM_INCLUDE_EXAMPLES )
>>   add_subdirectory(examples)
>> endif()
>> @@ -742,7 +744,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)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160622/b678bef1/attachment.html>


More information about the llvm-commits mailing list