| # 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 |
| |
| include(CMakeParseArguments) |
| |
| # iree_cc_binary() |
| # |
| # CMake function to imitate Bazel's cc_binary rule. |
| # |
| # Parameters: |
| # NAME: name of target (see Usage below) |
| # SRCS: List of source files for the binary |
| # 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 |
| # LINKOPTS: List of link options |
| # TESTONLY: for testing; won't compile when tests are disabled |
| # HOSTONLY: host only; compile using host toolchain when cross-compiling |
| # SETUP_INSTALL_RPATH: Sets an install RPATH which assumes the standard |
| # directory layout (to be used if linking against installed shared libs). |
| # INSTALL_COMPONENT: CMake install component (Defaults to "IREETool-${_RULE_NAME}"). |
| # Note: |
| # iree_cc_binary will create a binary called ${PACKAGE_NAME}_${NAME}, e.g. |
| # iree_base_foo with an alias to ${PACKAGE_NS}::${NAME}. |
| # |
| # Usage: |
| # iree_cc_library( |
| # NAME |
| # awesome |
| # HDRS |
| # "a.h" |
| # SRCS |
| # "a.cc" |
| # PUBLIC |
| # ) |
| # |
| # iree_cc_binary( |
| # NAME |
| # awesome_tool |
| # SRCS |
| # "awesome-tool-main.cc" |
| # DEPS |
| # iree::awesome |
| # ) |
| function(iree_cc_binary) |
| cmake_parse_arguments( |
| _RULE |
| "EXCLUDE_FROM_ALL;HOSTONLY;TESTONLY;SETUP_INSTALL_RPATH;DISABLE_LLVM_LINK_LLVM_DYLIB" |
| "NAME;INSTALL_COMPONENT" |
| "SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS" |
| ${ARGN} |
| ) |
| |
| if(_RULE_TESTONLY AND NOT IREE_BUILD_TESTS) |
| return() |
| endif() |
| |
| # Prefix the library with the package name, so we get: iree_package_name |
| iree_package_name(_PACKAGE_NAME) |
| iree_package_ns(_PACKAGE_NS) |
| if("${_PACKAGE_NAME}" STREQUAL "") |
| set(_NAME "${_RULE_NAME}") |
| else() |
| set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}") |
| endif() |
| |
| if(_DEBUG_IREE_PACKAGE_NAME) |
| message(STATUS " : iree_cc_binary(${_NAME})") |
| endif() |
| |
| add_executable(${_NAME} "") |
| |
| if(NOT "${_PACKAGE_NS}" STREQUAL "") |
| # Alias the iree_package_name binary 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() |
| add_executable(${_PACKAGE_NS}::${_RULE_NAME} ALIAS ${_NAME}) |
| |
| # If the binary name matches the package then treat it as a default. For |
| # example, foo/bar/ library 'bar' would end up as 'foo::bar'. This isn't |
| # likely to be common for binaries, but is consistent with the behavior for |
| # libraries and in Bazel. |
| iree_package_dir(_PACKAGE_DIR) |
| if("${_RULE_NAME}" STREQUAL "${_PACKAGE_DIR}") |
| add_executable(${_PACKAGE_NS} ALIAS ${_NAME}) |
| endif() |
| endif() |
| |
| set_target_properties(${_NAME} PROPERTIES OUTPUT_NAME "${_RULE_NAME}") |
| if(_RULE_SRCS) |
| target_sources(${_NAME} |
| PRIVATE |
| ${_RULE_SRCS} |
| ) |
| else() |
| set(_DUMMY_SRC "${CMAKE_CURRENT_BINARY_DIR}/${_NAME}_dummy.cc") |
| iree_make_empty_file("${_DUMMY_SRC}") |
| target_sources(${_NAME} |
| PRIVATE |
| ${_DUMMY_SRC} |
| ) |
| endif() |
| target_include_directories(${_NAME} SYSTEM |
| PUBLIC |
| "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>" |
| "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>" |
| ) |
| target_compile_definitions(${_NAME} |
| PUBLIC |
| ${_RULE_DEFINES} |
| ) |
| target_compile_options(${_NAME} |
| PRIVATE |
| ${IREE_DEFAULT_COPTS} |
| ${IREE_INTERFACE_COPTS} |
| ${_RULE_COPTS} |
| ) |
| target_link_options(${_NAME} |
| PRIVATE |
| ${IREE_DEFAULT_LINKOPTS} |
| ${_RULE_LINKOPTS} |
| ) |
| |
| # 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() |
| |
| # Implicit deps. |
| if(IREE_IMPLICIT_DEFS_CC_DEPS) |
| list(APPEND _RULE_DEPS ${IREE_IMPLICIT_DEFS_CC_DEPS}) |
| endif() |
| |
| target_link_libraries(${_NAME} |
| PUBLIC |
| ${_RULE_DEPS} |
| ) |
| iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA}) |
| |
| # Add all IREE targets to a folder in the IDE for organization. |
| set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/binaries) |
| |
| set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD}) |
| set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) |
| |
| set(_INSTALL_COMPONENT "${_RULE_INSTALL_COMPONENT}") |
| if(NOT _INSTALL_COMPONENT) |
| set(_INSTALL_COMPONENT "IREETool-${_RULE_NAME}") |
| endif() |
| |
| if(_RULE_EXCLUDE_FROM_ALL) |
| set_property(TARGET ${_NAME} PROPERTY EXCLUDE_FROM_ALL ON) |
| install(TARGETS ${_NAME} |
| RENAME ${_RULE_NAME} |
| COMPONENT ${_INSTALL_COMPONENT} |
| RUNTIME DESTINATION bin |
| BUNDLE DESTINATION bin |
| EXCLUDE_FROM_ALL) |
| else() |
| install(TARGETS ${_NAME} |
| RENAME ${_RULE_NAME} |
| COMPONENT ${_INSTALL_COMPONENT} |
| RUNTIME DESTINATION bin |
| BUNDLE DESTINATION bin) |
| endif() |
| |
| # Setup RPATH if on a Unix-like system. We have two use cases that we are |
| # handling here: |
| # 1. Install tree layouts like bin/ and lib/ directories that are |
| # peers. |
| # 2. Single directory bundles (language bindings do this) where the |
| # shared library is placed next to the consumer. |
| # |
| # The common solution is to use an RPATH of the origin and the |
| # lib/ directory that may be a peer of the origin. Distributions |
| # outside of this setup will need to do their own manipulation. |
| if(_RULE_SETUP_INSTALL_RPATH) |
| if(APPLE OR UNIX) |
| set(_origin_prefix "\$ORIGIN") |
| if(APPLE) |
| set(_origin_prefix "@loader_path") |
| endif() |
| # See: https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html |
| # Assume relative path as a sibling of the lib dir. |
| set(_lib_dir "${CMAKE_INSTALL_LIBDIR}") |
| if (NOT _lib_dir) |
| set(_lib_dir "lib") |
| endif() |
| set(_install_rpath "${_origin_prefix}" "${_origin_prefix}/../${_lib_dir}") |
| if(_lib_dir) |
| cmake_path(IS_ABSOLUTE _lib_dir _is_abs_libdir) |
| if(_is_abs_libdir) |
| # Use the libdir verbatim. |
| set(_install_rpath "${_origin_prefix}" "${_lib_dir}") |
| endif() |
| endif() |
| set_target_properties(${_NAME} PROPERTIES |
| BUILD_WITH_INSTALL_RPATH OFF |
| INSTALL_RPATH "${_install_rpath}" |
| ) |
| endif() |
| endif() |
| |
| # Set up Info.plist properties when building macOS/iOS app bundles. |
| get_target_property(APPLE_BUNDLE ${_NAME} MACOSX_BUNDLE) |
| if (APPLE_BUNDLE) |
| set_target_properties(${_NAME} PROPERTIES |
| MACOSX_BUNDLE_BUNDLE_NAME "${_RULE_NAME}" |
| MACOSX_BUNDLE_GUI_IDENTIFIER "dev.iree.${_RULE_NAME}" |
| MACOSX_BUNDLE_COPYRIGHT "Copyright © 2023 The IREE Authors" |
| # These are just placeholder version numbers until we define proper |
| # version scheme and support. |
| MACOSX_BUNDLE_BUNDLE_VERSION 0.1 |
| MACOSX_BUNDLE_SHORT_VERSION_STRING 0.1 |
| MACOSX_BUNDLE_LONG_VERSION_STRING 0.1) |
| endif() |
| endfunction() |