| # Copyright 2019 The IREE Authors | |
| # | |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. | |
| # See https://llvm.org/LICENSE.txt for license information. | |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| # iree_redirect_llvm_dylib_deps(DEPS_VAR) | |
| # | |
| # Filters a list of CC dependencies, making alterations as needed to | |
| # to redirect LLVM libraries to the libLLVM.so dynamic library, when LLVM | |
| # has been configured to link against it. | |
| # This is necessary to preserve the one-definition rule in the build graph | |
| # in a consistent way as to how AddLLVM.cmake does it. | |
| # Note that this only really works if libLLVM.so was configured to contain | |
| # "all" components. If this ever becomes unworkable, we may need to port the | |
| # component naming logic and selectively choose when to divert. | |
| function(iree_redirect_llvm_dylib_deps DEPS_VAR) | |
| set(_deps ${${DEPS_VAR}}) | |
| set(_new_deps) | |
| set(_modified FALSE) | |
| foreach(_dep ${_deps}) | |
| # If linking against the LLVM dylib, then divert any LLVM prefixed | |
| # targets there. | |
| if(LLVM_LINK_LLVM_DYLIB AND _dep MATCHES "^LLVM") | |
| list(APPEND _new_deps "LLVM") | |
| set(_modified TRUE) | |
| else() | |
| list(APPEND _new_deps "${_dep}") | |
| endif() | |
| endforeach() | |
| if(_modified) | |
| set(${DEPS_VAR} "${_new_deps}" PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| # iree_cc_library() | |
| # | |
| # CMake function to imitate Bazel's cc_library rule. | |
| # | |
| # Parameters: | |
| # PACKAGE: Name of the package (overrides actual path) | |
| # NAME: name of target (see Note) | |
| # HDRS: List of public header files for the library | |
| # TEXTUAL_HDRS: List of public header files that cannot be compiled on their own | |
| # SRCS: List of source files for the library | |
| # DATA: List of other targets and files required for this binary | |
| # DEPS: List of other libraries to be linked in to the binary targets | |
| # DISABLE_LLVM_LINK_LLVM_DYLIB: Disables linking against the libLLVM.so dynamic | |
| # library, even if the build is configured to do so. This must be used with | |
| # care as it can only contain dependencies and be used by binaries that also | |
| # so disable it (either in upstream LLVM or locally). In practice, it is used | |
| # for LLVM dependency chains that must always result in static-linked tools. | |
| # COPTS: List of private compile options | |
| # DEFINES: List of public defines | |
| # INCLUDES: Include directories to add to dependencies | |
| # SYSTEM_INCLUDES: Include directories that should be used with "SYSTEM" scope, | |
| # which makes them more tolerant to certain classes of warnings and issues. | |
| # LINKOPTS: List of link options | |
| # PUBLIC: Add this so that this library will be exported under iree:: | |
| # Also in IDE, target will appear in IREE folder while non PUBLIC will be in IREE/internal. | |
| # TESTONLY: When added, this target will only be built if user passes -DIREE_BUILD_TESTS=ON to CMake. | |
| # SHARED: If set, will compile to a shared object. | |
| # WINDOWS_DEF_FILE: If set, will add a windows .def file to a shared library link | |
| # Note: | |
| # By default, iree_cc_library will always create a library named iree_${NAME}, | |
| # and alias target iree::${NAME}. The iree:: form should always be used. | |
| # This is to reduce namespace pollution. | |
| # | |
| # iree_cc_library( | |
| # NAME | |
| # awesome | |
| # HDRS | |
| # "a.h" | |
| # SRCS | |
| # "a.cc" | |
| # ) | |
| # iree_cc_library( | |
| # NAME | |
| # fantastic_lib | |
| # SRCS | |
| # "b.cc" | |
| # DEPS | |
| # iree::package::awesome # not "awesome" ! | |
| # PUBLIC | |
| # ) | |
| # | |
| # iree_cc_library( | |
| # NAME | |
| # main_lib | |
| # ... | |
| # DEPS | |
| # iree::package::fantastic_lib | |
| # ) | |
| function(iree_cc_library) | |
| cmake_parse_arguments( | |
| _RULE | |
| "PUBLIC;TESTONLY;SHARED;DISABLE_LLVM_LINK_LLVM_DYLIB;ALWAYSLINK" | |
| "PACKAGE;NAME;WINDOWS_DEF_FILE" | |
| "HDRS;TEXTUAL_HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;INCLUDES;SYSTEM_INCLUDES" | |
| ${ARGN} | |
| ) | |
| if(_RULE_TESTONLY AND NOT IREE_BUILD_TESTS) | |
| return() | |
| endif() | |
| # Prefix the library with the package name, so we get: iree_package_name. | |
| if(_RULE_PACKAGE) | |
| set(_PACKAGE_NS "${_RULE_PACKAGE}") | |
| string(REPLACE "::" "_" _PACKAGE_NAME ${_RULE_PACKAGE}) | |
| else() | |
| iree_package_ns(_PACKAGE_NS) | |
| iree_package_name(_PACKAGE_NAME) | |
| endif() | |
| set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}") | |
| set(_OBJECTS_NAME ${_NAME}.objects) | |
| if(_DEBUG_IREE_PACKAGE_NAME) | |
| message(STATUS " : iree_cc_library(${_NAME})") | |
| endif() | |
| # Replace dependencies passed by ::name with iree::package::name | |
| list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::") | |
| if(NOT _RULE_DISABLE_LLVM_LINK_LLVM_DYLIB) | |
| iree_redirect_llvm_dylib_deps(_RULE_DEPS) | |
| endif() | |
| # Bazel srcs can name generated files. Point missing sources at the binary | |
| # tree so target_sources can attach the producer custom command edge. | |
| set(_RULE_SRC_TARGET_SRCS) | |
| set(_RULE_GENERATED_SRC_TARGET_SRCS) | |
| foreach(_SRC_FILE IN LISTS _RULE_SRCS) | |
| if(IS_ABSOLUTE "${_SRC_FILE}" OR "${_SRC_FILE}" MATCHES "^\\$<") | |
| list(APPEND _RULE_SRC_TARGET_SRCS "${_SRC_FILE}") | |
| elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_SRC_FILE}") | |
| list(APPEND _RULE_SRC_TARGET_SRCS "${_SRC_FILE}") | |
| else() | |
| set(_SRC_BINARY_FILE "${CMAKE_CURRENT_BINARY_DIR}/${_SRC_FILE}") | |
| list(APPEND _RULE_SRC_TARGET_SRCS "${_SRC_BINARY_FILE}") | |
| list(APPEND _RULE_GENERATED_SRC_TARGET_SRCS "${_SRC_BINARY_FILE}") | |
| endif() | |
| endforeach() | |
| if(_RULE_GENERATED_SRC_TARGET_SRCS) | |
| set_source_files_properties(${_RULE_GENERATED_SRC_TARGET_SRCS} | |
| PROPERTIES | |
| GENERATED TRUE | |
| ) | |
| endif() | |
| # Check if this is a header-only library. | |
| # Note that as of February 2019, many popular OS's (for example, Ubuntu | |
| # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't | |
| # use list(FILTER...) | |
| set(_CC_SRCS "${_RULE_SRC_TARGET_SRCS}") | |
| foreach(_SRC_FILE IN LISTS _CC_SRCS) | |
| if(${_SRC_FILE} MATCHES ".*\\.(h|inc)") | |
| list(REMOVE_ITEM _CC_SRCS "${_SRC_FILE}") | |
| endif() | |
| endforeach() | |
| if("${_CC_SRCS}" STREQUAL "") | |
| set(_RULE_IS_INTERFACE 1) | |
| else() | |
| set(_RULE_IS_INTERFACE 0) | |
| endif() | |
| # Wrap user specified INCLUDES in the $<BUILD_INTERFACE:> | |
| # generator. | |
| list(TRANSFORM _RULE_INCLUDES PREPEND "$<BUILD_INTERFACE:") | |
| list(TRANSFORM _RULE_INCLUDES APPEND ">") | |
| list(TRANSFORM _RULE_SYSTEM_INCLUDES PREPEND "$<BUILD_INTERFACE:") | |
| list(TRANSFORM _RULE_SYSTEM_INCLUDES APPEND ">") | |
| # Bazel hdrs can name generated files. Point missing headers at the binary | |
| # tree so target_sources can attach the producer custom command edge. | |
| set(_RULE_HDR_TARGET_SRCS) | |
| set(_RULE_GENERATED_HDR_TARGET_SRCS) | |
| set(_RULE_GENERATED_HDR_FILES) | |
| foreach(_HDR_FILE IN LISTS _RULE_HDRS _RULE_TEXTUAL_HDRS) | |
| if(IS_ABSOLUTE "${_HDR_FILE}" OR "${_HDR_FILE}" MATCHES "^\\$<") | |
| list(APPEND _RULE_HDR_TARGET_SRCS "${_HDR_FILE}") | |
| elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_HDR_FILE}") | |
| list(APPEND _RULE_HDR_TARGET_SRCS "${_HDR_FILE}") | |
| else() | |
| set(_HDR_BINARY_FILE "${CMAKE_CURRENT_BINARY_DIR}/${_HDR_FILE}") | |
| list(APPEND _RULE_HDR_TARGET_SRCS "${_HDR_BINARY_FILE}") | |
| list(APPEND _RULE_GENERATED_HDR_TARGET_SRCS "$<BUILD_INTERFACE:${_HDR_BINARY_FILE}>") | |
| list(APPEND _RULE_GENERATED_HDR_FILES "${_HDR_BINARY_FILE}") | |
| endif() | |
| endforeach() | |
| if(_RULE_GENERATED_HDR_FILES) | |
| set_source_files_properties(${_RULE_GENERATED_HDR_FILES} | |
| PROPERTIES | |
| GENERATED TRUE | |
| ) | |
| endif() | |
| # Implicit deps. | |
| if(IREE_IMPLICIT_DEFS_CC_DEPS) | |
| list(APPEND _RULE_DEPS ${IREE_IMPLICIT_DEFS_CC_DEPS}) | |
| endif() | |
| if(NOT _RULE_IS_INTERFACE AND NOT _RULE_ALWAYSLINK) | |
| # Normal library: OBJECT for compilation, STATIC (or SHARED) for linking. | |
| add_library(${_OBJECTS_NAME} OBJECT) | |
| if(_RULE_SHARED OR BUILD_SHARED_LIBS) | |
| add_library(${_NAME} SHARED "$<TARGET_OBJECTS:${_OBJECTS_NAME}>") | |
| if(_RULE_WINDOWS_DEF_FILE AND WIN32) | |
| target_sources(${_NAME} PRIVATE "${_RULE_WINDOWS_DEF_FILE}") | |
| endif() | |
| else() | |
| add_library(${_NAME} STATIC "$<TARGET_OBJECTS:${_OBJECTS_NAME}>") | |
| if(_RULE_WINDOWS_DEF_FILE AND WIN32) | |
| message(SEND_ERROR "If specifying a .def file library must be shared") | |
| endif() | |
| endif() | |
| # Sources get added to the object library. | |
| target_sources(${_OBJECTS_NAME} | |
| PRIVATE | |
| ${_RULE_SRC_TARGET_SRCS} | |
| ${_RULE_HDR_TARGET_SRCS} | |
| ) | |
| # Keep track of objects transitively in our special property. | |
| set_property(TARGET ${_NAME} PROPERTY | |
| INTERFACE_IREE_TRANSITIVE_OBJECTS "$<TARGET_OBJECTS:${_OBJECTS_NAME}>") | |
| _iree_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS}) | |
| # We define everything else on the regular rule. However, the object | |
| # library needs compiler definition related properties, so we forward them. | |
| # We also forward link libraries -- not because the OBJECT libraries do | |
| # linking but because they get transitive compile definitions from them. | |
| # Yes. This is state of the art. | |
| target_include_directories(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_INCLUDE_DIRECTORIES> | |
| ) | |
| target_include_directories(${_OBJECTS_NAME} SYSTEM | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
| ) | |
| target_include_directories(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_INCLUDE_DIRECTORIES> | |
| ) | |
| target_compile_options(${_OBJECTS_NAME} | |
| PRIVATE | |
| $<TARGET_PROPERTY:${_NAME},COMPILE_OPTIONS> | |
| ) | |
| target_compile_definitions(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_COMPILE_DEFINITIONS> | |
| ) | |
| target_link_libraries(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_LINK_LIBRARIES> | |
| ) | |
| target_include_directories(${_NAME} | |
| PUBLIC | |
| "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>" | |
| "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>" | |
| ) | |
| target_include_directories(${_NAME} | |
| PUBLIC | |
| ${_RULE_INCLUDES} | |
| ) | |
| target_include_directories(${_NAME} | |
| SYSTEM PUBLIC | |
| ${_RULE_SYSTEM_INCLUDES} | |
| ) | |
| target_compile_options(${_NAME} | |
| PRIVATE | |
| ${IREE_DEFAULT_COPTS} | |
| ${_RULE_COPTS} | |
| INTERFACE | |
| ${IREE_INTERFACE_COPTS} | |
| ) | |
| target_link_options(${_NAME} | |
| PRIVATE | |
| ${IREE_DEFAULT_LINKOPTS} | |
| ${_RULE_LINKOPTS} | |
| ) | |
| target_link_libraries(${_NAME} | |
| PUBLIC | |
| ${_RULE_DEPS} | |
| ${IREE_THREADS_DEPS} | |
| ) | |
| iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA}) | |
| target_compile_definitions(${_NAME} | |
| PUBLIC | |
| ${_RULE_DEFINES} | |
| ) | |
| # If in BUILD_SHARED_LIBS mode, then we need to make sure that visibility | |
| # is not hidden. We default to hidden visibility in the main copts so | |
| # need to undo it here. | |
| # TODO: Switch to the CXX_VISIBILITY_PRESET property and fix the global | |
| # hidden setting to follow suit. | |
| if(BUILD_SHARED_LIBS AND IREE_SUPPORTS_VISIBILITY_DEFAULT) | |
| target_compile_options(${_OBJECTS_NAME} PRIVATE | |
| "-fvisibility=default" | |
| ) | |
| endif() | |
| # Add all IREE targets to a folder in the IDE for organization. | |
| if(_RULE_PUBLIC) | |
| set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}) | |
| elseif(_RULE_TESTONLY) | |
| set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/test) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/test) | |
| else() | |
| set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/internal) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/internal) | |
| endif() | |
| # INTERFACE libraries can't have the CXX_STANDARD property set so only | |
| # set here. | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD}) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) | |
| elseif(NOT _RULE_IS_INTERFACE AND _RULE_ALWAYSLINK) | |
| # ALWAYSLINK library: OBJECT for compilation, INTERFACE for propagation. | |
| # The INTERFACE library propagates $<TARGET_OBJECTS:...> directly, ensuring | |
| # all objects are always included in the final binary. STATIC archives let | |
| # the linker strip unreferenced objects (dropping static init registrations); | |
| # propagating objects directly bypasses the archive and eliminates that | |
| # problem. This is the CMake equivalent of Bazel's alwayslink = True. | |
| add_library(${_OBJECTS_NAME} OBJECT) | |
| add_library(${_NAME} INTERFACE) | |
| target_sources(${_OBJECTS_NAME} | |
| PRIVATE | |
| ${_RULE_SRC_TARGET_SRCS} | |
| ${_RULE_HDR_TARGET_SRCS} | |
| ) | |
| set_property(TARGET ${_NAME} PROPERTY | |
| INTERFACE_IREE_TRANSITIVE_OBJECTS "$<TARGET_OBJECTS:${_OBJECTS_NAME}>") | |
| _iree_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS}) | |
| # INTERFACE library propagates objects and link dependencies to consumers. | |
| target_link_libraries(${_NAME} | |
| INTERFACE | |
| $<TARGET_OBJECTS:${_OBJECTS_NAME}> | |
| ${_RULE_DEPS} | |
| ${IREE_THREADS_DEPS} | |
| ) | |
| target_include_directories(${_NAME} | |
| INTERFACE | |
| "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>" | |
| "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>" | |
| ${_RULE_INCLUDES} | |
| ) | |
| target_include_directories(${_NAME} | |
| SYSTEM INTERFACE | |
| ${_RULE_SYSTEM_INCLUDES} | |
| ) | |
| target_link_options(${_NAME} | |
| INTERFACE | |
| ${IREE_DEFAULT_LINKOPTS} | |
| ${_RULE_LINKOPTS} | |
| ) | |
| target_compile_definitions(${_NAME} | |
| INTERFACE | |
| ${_RULE_DEFINES} | |
| ) | |
| # OBJECT library needs compile-related properties for building the sources. | |
| # Compile options go directly on the OBJECT library (INTERFACE libraries | |
| # cannot have PRIVATE properties). | |
| target_compile_options(${_OBJECTS_NAME} | |
| PRIVATE | |
| ${IREE_DEFAULT_COPTS} | |
| ${_RULE_COPTS} | |
| ) | |
| # Forward transitive compile properties from the INTERFACE library's | |
| # dependency chain to the OBJECT library so sources see all transitive | |
| # include directories and definitions. | |
| target_include_directories(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_INCLUDE_DIRECTORIES> | |
| ) | |
| target_include_directories(${_OBJECTS_NAME} SYSTEM | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | |
| ) | |
| target_compile_definitions(${_OBJECTS_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_NAME},INTERFACE_COMPILE_DEFINITIONS> | |
| ) | |
| # Forward deps to the OBJECT library for transitive compile definitions. | |
| # We forward deps directly rather than $<TARGET_PROPERTY:INTERFACE_LINK_LIBRARIES> | |
| # because the latter contains $<TARGET_OBJECTS:${_OBJECTS_NAME}> which would | |
| # create a circular reference. | |
| target_link_libraries(${_OBJECTS_NAME} | |
| PUBLIC | |
| ${_RULE_DEPS} | |
| ) | |
| iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA}) | |
| if(BUILD_SHARED_LIBS AND IREE_SUPPORTS_VISIBILITY_DEFAULT) | |
| target_compile_options(${_OBJECTS_NAME} PRIVATE | |
| "-fvisibility=default" | |
| ) | |
| endif() | |
| if(_RULE_PUBLIC) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}) | |
| elseif(_RULE_TESTONLY) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/test) | |
| else() | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/internal) | |
| endif() | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD}) | |
| set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) | |
| else() | |
| # Generating header-only library (no sources, or ALWAYSLINK on header-only | |
| # which is meaningless since there are no objects). | |
| add_library(${_NAME} INTERFACE) | |
| target_include_directories(${_NAME} | |
| INTERFACE | |
| "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>" | |
| "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>" | |
| ${_RULE_INCLUDES} | |
| ) | |
| target_include_directories(${_NAME} | |
| SYSTEM INTERFACE | |
| ${_RULE_SYSTEM_INCLUDES} | |
| ) | |
| target_link_options(${_NAME} | |
| INTERFACE | |
| ${IREE_DEFAULT_LINKOPTS} | |
| ${_RULE_LINKOPTS} | |
| ) | |
| if(_RULE_GENERATED_HDR_TARGET_SRCS) | |
| target_sources(${_NAME} | |
| INTERFACE | |
| ${_RULE_GENERATED_HDR_TARGET_SRCS} | |
| ) | |
| endif() | |
| target_link_libraries(${_NAME} | |
| INTERFACE | |
| ${_RULE_DEPS} | |
| ) | |
| _iree_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS}) | |
| iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA}) | |
| target_compile_definitions(${_NAME} | |
| INTERFACE | |
| ${_RULE_DEFINES} | |
| ) | |
| endif() | |
| if(NOT _RULE_TESTONLY) | |
| iree_install_targets( | |
| TARGETS ${_NAME} | |
| HDRS ${_RULE_HDRS} ${_RULE_TEXTUAL_HDRS} | |
| ) | |
| endif() | |
| # Alias the iree_package_name library to iree::package::name. | |
| # This lets us more clearly map to Bazel and makes it possible to | |
| # disambiguate the underscores in paths vs. the separators. | |
| if(_DEBUG_IREE_PACKAGE_NAME) | |
| message(STATUS " + alias ${_PACKAGE_NS}::${_RULE_NAME}") | |
| endif() | |
| iree_add_alias_library(${_PACKAGE_NS}::${_RULE_NAME} ${_NAME}) | |
| if(NOT "${_PACKAGE_NS}" STREQUAL "") | |
| # If the library name matches the final component of the package then treat | |
| # it as a default. For example, foo/bar/ library 'bar' would end up as | |
| # 'foo::bar'. | |
| iree_package_dir(_PACKAGE_DIR) | |
| if("${_RULE_NAME}" STREQUAL "${_PACKAGE_DIR}") | |
| iree_add_alias_library(${_PACKAGE_NS} ${_NAME}) | |
| endif() | |
| endif() | |
| endfunction() | |
| # _iree_cc_library_add_object_deps() | |
| # | |
| # Helper to add deps to an iree_cc_library. This only operates on the unaliased | |
| # raw name (i.e. 'iree_vm_vm'), not aliased names (i.e. 'iree::vm'). | |
| # | |
| # This appends to two properties: | |
| # INTERFACE_IREE_TRANSITIVE_OBJECTS: Transitive list of all objects from | |
| # this library and all "iree::" prefixed dependent libraries. This will | |
| # allow you to create mondo objects for any transitive libraries that are | |
| # part of IREE, but it will not contain outside. | |
| # INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS: Transitive list of any dependency | |
| # targets that are not under the "iree::" namespace but are encountered | |
| # in the dependency dag. | |
| function(_iree_cc_library_add_object_deps name) | |
| foreach(_DEP_TARGET ${ARGN}) | |
| if(_DEP_TARGET MATCHES "^iree::") | |
| set_property(TARGET ${name} APPEND PROPERTY | |
| INTERFACE_IREE_TRANSITIVE_OBJECTS | |
| "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},INTERFACE_IREE_TRANSITIVE_OBJECTS>>" | |
| ) | |
| set_property(TARGET ${name} APPEND PROPERTY | |
| INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS | |
| "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS>>" | |
| ) | |
| # Propagate wasm JS companion metadata through the iree:: dep chain. | |
| # These are genex recipe strings — they resolve at generation time after | |
| # all targets are defined, making this fully order-independent. | |
| if(CMAKE_SYSTEM_PROCESSOR STREQUAL "wasm32") | |
| set_property(TARGET ${name} APPEND PROPERTY | |
| IREE_WASM_JS_ENTRIES | |
| "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},IREE_WASM_JS_ENTRIES>>" | |
| ) | |
| set_property(TARGET ${name} APPEND PROPERTY | |
| IREE_WASM_JS_SRCS | |
| "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},IREE_WASM_JS_SRCS>>" | |
| ) | |
| endif() | |
| else() | |
| set_property(TARGET ${name} APPEND PROPERTY | |
| INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS | |
| ${_DEP_TARGET} | |
| ) | |
| endif() | |
| endforeach() | |
| endfunction() | |
| # iree_cc_unified_library() | |
| # | |
| # Creates a unified library out of the iree:: namespaced transitive deps+self | |
| # of some ROOT library. The resulting library will contain the union of all | |
| # objects from all transitive library-deps in the iree:: namespace. Such | |
| # libraries are typically the only libraries that we install for outside use | |
| # and they must only be used by leaf demos or out of tree libraries/executables. | |
| # Commingling with any regular libraries will result in duplicate symbols. | |
| # | |
| # Note that the resulting library will not contain any libraries outside of the | |
| # iree:: namespace but will be configured to link to them. For external use | |
| # it is expected that they will be installed and used separately as needed. | |
| # | |
| # Compile and link options are forwarded from the ROOT target non-transitively. | |
| # Ensure that this target directly references all definitions that need to | |
| # be exported to end consumers. | |
| # | |
| # Parameters: | |
| # NAME: name of target | |
| # ROOT: Root target library to extract objects and deps from. | |
| function(iree_cc_unified_library) | |
| cmake_parse_arguments( | |
| _RULE | |
| "SHARED" | |
| "NAME;ROOT" | |
| "" | |
| ${ARGN} | |
| ) | |
| # Replace dependencies passed by ::name with iree::package::name | |
| iree_package_ns(_PACKAGE_NS) | |
| list(TRANSFORM _RULE_ROOT REPLACE "^::" "${_PACKAGE_NS}::") | |
| # Prefix the library with the package name, so we get: iree_package_name. | |
| iree_package_name(_PACKAGE_NAME) | |
| set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}") | |
| # Evaluate the object and libs. | |
| set(_OBJECTS "$<REMOVE_DUPLICATES:$<GENEX_EVAL:$<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_IREE_TRANSITIVE_OBJECTS>>>") | |
| set(_LIBS "$<REMOVE_DUPLICATES:$<GENEX_EVAL:$<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS>>>") | |
| # For debugging, write out evaluated objects to a file. | |
| # This cannot be enabled for Xcode given that Xcode does not support | |
| # per-configuration sources. | |
| if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode") | |
| file(GENERATE OUTPUT "${_RULE_NAME}.$<CONFIG>.contents.txt" CONTENT | |
| "OBJECTS:\n${_OBJECTS}\n\nLIBS:\n${_LIBS}\n") | |
| endif() | |
| if(_RULE_SHARED) | |
| add_library(${_NAME} SHARED ${_OBJECTS}) | |
| else() | |
| add_library(${_NAME} STATIC ${_OBJECTS}) | |
| endif() | |
| target_link_libraries(${_NAME} | |
| PUBLIC | |
| ${_LIBS} | |
| ) | |
| # Forward compile usage requirements from the root library. | |
| target_include_directories(${_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_INCLUDE_DIRECTORIES> | |
| ) | |
| target_include_directories(${_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_INCLUDE_DIRECTORIES> | |
| ) | |
| target_compile_options(${_NAME} | |
| PRIVATE | |
| $<TARGET_PROPERTY:${_RULE_ROOT},COMPILE_OPTIONS> | |
| ) | |
| target_compile_definitions(${_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_COMPILE_DEFINITIONS> | |
| ) | |
| target_link_libraries(${_NAME} | |
| PUBLIC | |
| $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_LINK_LIBRARIES> | |
| ) | |
| iree_install_targets( | |
| TARGETS ${_NAME} | |
| ) | |
| # Alias the iree_package_name library to iree::package::name. | |
| # This lets us more clearly map to Bazel and makes it possible to | |
| # disambiguate the underscores in paths vs. the separators. | |
| iree_add_alias_library(${_PACKAGE_NS}::${_RULE_NAME} ${_NAME}) | |
| # If the library name matches the final component of the package then treat | |
| # it as a default. For example, foo/bar/ library 'bar' would end up as | |
| # 'foo::bar'. | |
| iree_package_dir(_PACKAGE_DIR) | |
| if(${_RULE_NAME} STREQUAL ${_PACKAGE_DIR}) | |
| iree_add_alias_library(${_PACKAGE_NS} ${_NAME}) | |
| endif() | |
| endfunction() | |
| # iree_cc_library_exclude_from_all(target exclude) | |
| # | |
| # For a target previously defined in the same package, set the | |
| # EXCLUDE_FROM_ALL property. | |
| # | |
| # This is necessary because cc_library targets consist of multiple sub-targets | |
| # and they all must have the property set. | |
| function(iree_cc_library_exclude_from_all target exclude_from_all) | |
| iree_package_ns(_PACKAGE_NS) | |
| iree_package_name(_PACKAGE_NAME) | |
| set(_NAME "${_PACKAGE_NAME}_${target}") | |
| set(_OBJECTS_NAME ${_NAME}.objects) | |
| set_target_properties(${_NAME} ${_OBJECTS_NAME} | |
| PROPERTIES EXCLUDE_FROM_ALL ${exclude_from_all}) | |
| endfunction() |