+
+# Add external project that may want to be built as part of llvm such as Clang,
+# lld, and Polly. This adds two options. One for the source directory of the
+# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to
+# enable or disable building it with everything else.
+# Additional parameter can be specified as the name of directory.
+macro(add_llvm_external_project name)
+ set(add_llvm_external_dir "${ARGN}")
+ if("${add_llvm_external_dir}" STREQUAL "")
+ set(add_llvm_external_dir ${name})
+ endif()
+ list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
+ string(REPLACE "-" "_" nameUNDERSCORE ${name})
+ string(TOUPPER ${nameUNDERSCORE} nameUPPER)
+ set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}"
+ CACHE PATH "Path to ${name} source directory")
+ if (NOT ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} STREQUAL ""
+ AND EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
+ option(LLVM_EXTERNAL_${nameUPPER}_BUILD
+ "Whether to build ${name} as part of LLVM" ON)
+ if (LLVM_EXTERNAL_${nameUPPER}_BUILD)
+ add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})
+ endif()
+ endif()
+endmacro(add_llvm_external_project)
+
+macro(add_llvm_tool_subdirectory name)
+ list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
+ add_subdirectory(${name})
+endmacro(add_llvm_tool_subdirectory)
+
+macro(ignore_llvm_tool_subdirectory name)
+ list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
+endmacro(ignore_llvm_tool_subdirectory)
+
+function(add_llvm_implicit_external_projects)
+ set(list_of_implicit_subdirs "")
+ file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
+ foreach(dir ${sub-dirs})
+ if(IS_DIRECTORY "${dir}")
+ list(FIND LLVM_IMPLICIT_PROJECT_IGNORE "${dir}" tool_subdir_ignore)
+ if( tool_subdir_ignore EQUAL -1
+ AND EXISTS "${dir}/CMakeLists.txt")
+ get_filename_component(fn "${dir}" NAME)
+ list(APPEND list_of_implicit_subdirs "${fn}")
+ endif()
+ endif()
+ endforeach()
+
+ foreach(external_proj ${list_of_implicit_subdirs})
+ add_llvm_external_project("${external_proj}")
+ endforeach()
+endfunction(add_llvm_implicit_external_projects)
+
+# Generic support for adding a unittest.
+function(add_unittest test_suite test_name)
+ if( NOT LLVM_BUILD_TESTS )
+ set(EXCLUDE_FROM_ALL ON)
+ endif()
+
+ # Visual Studio 2012 only supports up to 8 template parameters in
+ # std::tr1::tuple by default, but gtest requires 10
+ if (MSVC AND MSVC_VERSION EQUAL 1700)
+ list(APPEND LLVM_COMPILE_DEFINITIONS _VARIADIC_MAX=10)
+ endif ()
+
+ include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include)
+ if (NOT LLVM_ENABLE_THREADS)
+ list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_PTHREAD=0)
+ endif ()
+
+ if (SUPPORTS_NO_VARIADIC_MACROS_FLAG)
+ list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros")
+ endif ()
+
+ set(LLVM_REQUIRES_RTTI OFF)
+
+ add_llvm_executable(${test_name} ${ARGN})
+ set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
+ set_output_directory(${test_name} ${outdir} ${outdir})
+ target_link_libraries(${test_name}
+ gtest
+ gtest_main
+ LLVMSupport # gtest needs it for raw_ostream.
+ )
+
+ add_dependencies(${test_suite} ${test_name})
+ get_target_property(test_suite_folder ${test_suite} FOLDER)
+ if (NOT ${test_suite_folder} STREQUAL "NOTFOUND")
+ set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}")
+ endif ()
+endfunction()
+
+# This function provides an automatic way to 'configure'-like generate a file
+# based on a set of common and custom variables, specifically targeting the
+# variables needed for the 'lit.site.cfg' files. This function bundles the
+# common variables that any Lit instance is likely to need, and custom
+# variables can be passed in.
+function(configure_lit_site_cfg input output)
+ foreach(c ${LLVM_TARGETS_TO_BUILD})
+ set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")
+ endforeach(c)
+ set(TARGETS_TO_BUILD ${TARGETS_BUILT})
+
+ set(SHLIBEXT "${LTDL_SHLIB_EXT}")
+
+ if(BUILD_SHARED_LIBS)
+ set(LLVM_SHARED_LIBS_ENABLED "1")
+ else()
+ set(LLVM_SHARED_LIBS_ENABLED "0")
+ endif(BUILD_SHARED_LIBS)
+
+ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ set(SHLIBPATH_VAR "DYLD_LIBRARY_PATH")
+ else() # Default for all other unix like systems.
+ # CMake hardcodes the library locaction using rpath.
+ # Therefore LD_LIBRARY_PATH is not required to run binaries in the
+ # build dir. We pass it anyways.
+ set(SHLIBPATH_VAR "LD_LIBRARY_PATH")
+ endif()
+
+ # Configuration-time: See Unit/lit.site.cfg.in
+ if (CMAKE_CFG_INTDIR STREQUAL ".")
+ set(LLVM_BUILD_MODE ".")
+ else ()
+ set(LLVM_BUILD_MODE "%(build_mode)s")
+ endif ()
+
+ # They below might not be the build tree but provided binary tree.
+ set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
+ set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_TOOLS_DIR ${LLVM_TOOLS_BINARY_DIR})
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLVM_LIBS_DIR ${LLVM_LIBRARY_DIR})
+
+ # SHLIBDIR points the build tree.
+ string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} SHLIBDIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+
+ set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
+ set(ENABLE_SHARED ${LLVM_SHARED_LIBS_ENABLED})
+ set(SHLIBPATH_VAR ${SHLIBPATH_VAR})
+
+ if(LLVM_ENABLE_ASSERTIONS AND NOT MSVC_IDE)
+ set(ENABLE_ASSERTIONS "1")
+ else()
+ set(ENABLE_ASSERTIONS "0")
+ endif()
+
+ set(HOST_OS ${CMAKE_SYSTEM_NAME})
+ set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
+
+ if (CLANG_ENABLE_ARCMT)
+ set(ENABLE_CLANG_ARCMT "1")
+ else()
+ set(ENABLE_CLANG_ARCMT "0")
+ endif()
+ if (CLANG_ENABLE_REWRITER)
+ set(ENABLE_CLANG_REWRITER "1")
+ else()
+ set(ENABLE_CLANG_REWRITER "0")
+ endif()
+ if (CLANG_ENABLE_STATIC_ANALYZER)
+ set(ENABLE_CLANG_STATIC_ANALYZER "1")
+ else()
+ set(ENABLE_CLANG_STATIC_ANALYZER "0")
+ endif()
+
+ configure_file(${input} ${output} @ONLY)
+endfunction()
+
+# A raw function to create a lit target. This is used to implement the testuite
+# management functions.
+function(add_lit_target target comment)
+ parse_arguments(ARG "PARAMS;DEPENDS;ARGS" "" ${ARGN})
+ set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}")
+ separate_arguments(LIT_ARGS)
+ if (NOT CMAKE_CFG_INTDIR STREQUAL ".")
+ list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})
+ endif ()
+ set(LIT_COMMAND
+ ${PYTHON_EXECUTABLE}
+ ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py
+ ${LIT_ARGS}
+ )
+ foreach(param ${ARG_PARAMS})
+ list(APPEND LIT_COMMAND --param ${param})
+ endforeach()
+ if( ARG_DEPENDS )
+ add_custom_target(${target}
+ COMMAND ${LIT_COMMAND} ${ARG_DEFAULT_ARGS}
+ COMMENT "${comment}"
+ )
+ add_dependencies(${target} ${ARG_DEPENDS})
+ else()
+ add_custom_target(${target}
+ COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")
+ message(STATUS "${target} does nothing.")
+ endif()
+
+ # Tests should be excluded from "Build Solution".
+ set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
+endfunction()
+
+# A function to add a set of lit test suites to be driven through 'check-*' targets.
+function(add_lit_testsuite target comment)
+ parse_arguments(ARG "PARAMS;DEPENDS;ARGS" "" ${ARGN})
+
+ # EXCLUDE_FROM_ALL excludes the test ${target} out of check-all.
+ if(NOT EXCLUDE_FROM_ALL)
+ # Register the testsuites, params and depends for the global check rule.
+ set_property(GLOBAL APPEND PROPERTY LLVM_LIT_TESTSUITES ${ARG_DEFAULT_ARGS})
+ set_property(GLOBAL APPEND PROPERTY LLVM_LIT_PARAMS ${ARG_PARAMS})
+ set_property(GLOBAL APPEND PROPERTY LLVM_LIT_DEPENDS ${ARG_DEPENDS})
+ set_property(GLOBAL APPEND PROPERTY LLVM_LIT_EXTRA_ARGS ${ARG_ARGS})
+ endif()
+
+ # Produce a specific suffixed check rule.
+ add_lit_target(${target} ${comment}
+ ${ARG_DEFAULT_ARGS}
+ PARAMS ${ARG_PARAMS}
+ DEPENDS ${ARG_DEPENDS}
+ ARGS ${ARG_ARGS}
+ )
+endfunction()