blob: c7cefc06d38c3111c972c15ce830cdfe9ba63dc0 [file] [log] [blame]
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07001# Copyright 2019 The IREE Authors
Ben Vanik512d2d32019-09-20 13:22:34 -07002#
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07003# Licensed under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ben Vanik512d2d32019-09-20 13:22:34 -07006
7include(CMakeParseArguments)
8
9# external_cc_library()
10#
11# CMake function to imitate Bazel's cc_library rule.
12# This is used for external libraries (from third_party, etc) that don't live
13# in the IREE namespace.
14#
15# Parameters:
16# PACKAGE: Name of the package (overrides actual path)
17# NAME: Name of target (see Note)
18# ROOT: Path to the source root where files are found
19# HDRS: List of public header files for the library
20# SRCS: List of source files for the library
Scott Toddda2d2392020-03-09 16:42:55 -070021# DATA: List of other targets and files required for this binary
Ben Vanik512d2d32019-09-20 13:22:34 -070022# DEPS: List of other libraries to be linked in to the binary targets
23# COPTS: List of private compile options
24# DEFINES: List of public defines
25# INCLUDES: Include directories to add to dependencies
26# LINKOPTS: List of link options
Ben Vanik6b112ef2019-10-03 10:45:14 -070027# PUBLIC: Add this so that this library will be exported under ${PACKAGE}::
28# Also in IDE, target will appear in ${PACKAGE} folder while non PUBLIC will be
29# in ${PACKAGE}/internal.
30# TESTONLY: When added, this target will only be built if user passes
31# -DIREE_BUILD_TESTS=ON to CMake.
Ben Vanik512d2d32019-09-20 13:22:34 -070032#
33# Note:
Ben Vanik6b112ef2019-10-03 10:45:14 -070034# By default, external_cc_library will always create a library named
35# ${PACKAGE}_${NAME}, and alias target ${PACKAGE}::${NAME}. The ${PACKAGE}::
36# form should always be used. This is to reduce namespace pollution.
Ben Vanik512d2d32019-09-20 13:22:34 -070037#
38# external_cc_library(
39# PACKAGE
40# some_external_thing
41# NAME
42# awesome
43# ROOT
44# "third_party/foo"
45# HDRS
46# "a.h"
47# SRCS
48# "a.cc"
49# )
50# external_cc_library(
51# PACKAGE
52# some_external_thing
53# NAME
54# fantastic_lib
55# ROOT
56# "third_party/foo"
57# SRCS
58# "b.cc"
59# DEPS
60# some_external_thing::awesome # not "awesome" !
61# PUBLIC
62# )
63#
64# iree_cc_library(
65# NAME
66# main_lib
67# ...
68# DEPS
69# some_external_thing::fantastic_lib
70# )
Ben Vanik512d2d32019-09-20 13:22:34 -070071function(external_cc_library)
Ben Vanik6b112ef2019-10-03 10:45:14 -070072 cmake_parse_arguments(_RULE
Ben Vanikbf091d32020-11-16 05:53:58 -080073 "PUBLIC;TESTONLY"
Ben Vanik512d2d32019-09-20 13:22:34 -070074 "PACKAGE;NAME;ROOT"
Scott Toddda2d2392020-03-09 16:42:55 -070075 "HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;INCLUDES"
Ben Vanik512d2d32019-09-20 13:22:34 -070076 ${ARGN}
77 )
78
Lei Zhangd454ee42020-06-02 11:48:57 -070079 if(_RULE_TESTONLY AND NOT IREE_BUILD_TESTS)
80 return()
81 endif()
Ben Vanik512d2d32019-09-20 13:22:34 -070082
Lei Zhangd454ee42020-06-02 11:48:57 -070083 # Prefix the library with the package name.
84 string(REPLACE "::" "_" _PACKAGE_NAME ${_RULE_PACKAGE})
85 set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}")
Ben Vanik512d2d32019-09-20 13:22:34 -070086
Lei Zhangd454ee42020-06-02 11:48:57 -070087 # Prefix paths with the root.
88 list(TRANSFORM _RULE_HDRS PREPEND ${_RULE_ROOT})
89 list(TRANSFORM _RULE_SRCS PREPEND ${_RULE_ROOT})
90
91 # Check if this is a header-only library.
92 # Note that as of February 2019, many popular OS's (for example, Ubuntu
93 # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't
94 # use list(FILTER...)
95 set(_CC_SRCS "${_RULE_SRCS}")
Scott Todd1a1aea62022-04-28 09:12:11 -070096 foreach(_SRC_FILE IN LISTS _CC_SRCS)
hehaoqianc7ef4be2022-07-06 06:13:12 +080097 if(${_SRC_FILE} MATCHES ".*\\.(h|inc)$")
Scott Todd1a1aea62022-04-28 09:12:11 -070098 list(REMOVE_ITEM _CC_SRCS "${_SRC_FILE}")
Lei Zhangd454ee42020-06-02 11:48:57 -070099 endif()
100 endforeach()
101 if("${_CC_SRCS}" STREQUAL "")
102 set(_RULE_IS_INTERFACE 1)
103 else()
104 set(_RULE_IS_INTERFACE 0)
105 endif()
106
107 if(NOT _RULE_IS_INTERFACE)
108 add_library(${_NAME} STATIC "")
109 target_sources(${_NAME}
110 PRIVATE
111 ${_RULE_SRCS}
112 ${_RULE_HDRS}
113 )
Ben Vanikafd7abe2020-10-07 09:01:53 -0700114 target_include_directories(${_NAME} SYSTEM
Lei Zhangd454ee42020-06-02 11:48:57 -0700115 PUBLIC
Ben Vanik6bc6f902020-11-16 05:37:08 -0800116 "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
117 "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
Lei Zhangd454ee42020-06-02 11:48:57 -0700118 "$<BUILD_INTERFACE:${_RULE_INCLUDES}>"
119 )
120 target_compile_options(${_NAME}
121 PRIVATE
122 ${_RULE_COPTS}
123 ${IREE_DEFAULT_COPTS}
124 )
Ben Vanik2f0b75c2020-12-23 19:29:55 -0800125 target_link_options(${_NAME}
Lei Zhangd454ee42020-06-02 11:48:57 -0700126 PRIVATE
Lei Zhangd454ee42020-06-02 11:48:57 -0700127 ${IREE_DEFAULT_LINKOPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800128 ${_RULE_LINKOPTS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700129 )
Ben Vanik2f0b75c2020-12-23 19:29:55 -0800130 target_link_libraries(${_NAME}
131 PUBLIC
132 ${_RULE_DEPS}
133 )
Lei Zhangd454ee42020-06-02 11:48:57 -0700134 target_compile_definitions(${_NAME}
135 PUBLIC
136 ${_RULE_DEFINES}
137 )
138 iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
139
Lei Zhangd454ee42020-06-02 11:48:57 -0700140 # Add all external targets to a a folder in the IDE for organization.
141 if(_RULE_PUBLIC)
142 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party)
143 elseif(_RULE_TESTONLY)
144 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party/test)
Ben Vanik512d2d32019-09-20 13:22:34 -0700145 else()
Lei Zhangd454ee42020-06-02 11:48:57 -0700146 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party/internal)
Ben Vanik512d2d32019-09-20 13:22:34 -0700147 endif()
148
Lei Zhangd454ee42020-06-02 11:48:57 -0700149 # INTERFACE libraries can't have the CXX_STANDARD property set
150 set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD})
151 set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
152 else()
153 # Generating header-only library
154 add_library(${_NAME} INTERFACE)
Ben Vanikafd7abe2020-10-07 09:01:53 -0700155 target_include_directories(${_NAME} SYSTEM
Lei Zhangd454ee42020-06-02 11:48:57 -0700156 INTERFACE
Ben Vanik6bc6f902020-11-16 05:37:08 -0800157 "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
158 "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
Lei Zhangd454ee42020-06-02 11:48:57 -0700159 "$<BUILD_INTERFACE:${_RULE_INCLUDES}>"
160 )
161 target_compile_options(${_NAME}
162 INTERFACE
Lei Zhangd454ee42020-06-02 11:48:57 -0700163 ${IREE_DEFAULT_COPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800164 ${_RULE_COPTS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700165 )
Ben Vanik2f0b75c2020-12-23 19:29:55 -0800166 target_link_options(${_NAME}
Lei Zhangd454ee42020-06-02 11:48:57 -0700167 INTERFACE
Lei Zhangd454ee42020-06-02 11:48:57 -0700168 ${IREE_DEFAULT_LINKOPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800169 ${_RULE_LINKOPTS}
Ben Vanik2f0b75c2020-12-23 19:29:55 -0800170 )
171 target_link_libraries(${_NAME}
172 INTERFACE
Ben Vanikbf4069e2020-11-14 11:23:01 -0800173 ${_RULE_DEPS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700174 )
175 iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
176 target_compile_definitions(${_NAME}
177 INTERFACE
178 ${_RULE_DEFINES}
179 )
180 endif()
Ben Vanik512d2d32019-09-20 13:22:34 -0700181
Lei Zhangd454ee42020-06-02 11:48:57 -0700182 add_library(${_RULE_PACKAGE}::${_RULE_NAME} ALIAS ${_NAME})
Geoffrey Martin-Nobleb5d90ac2021-05-12 13:49:59 -0700183 # If the library name matches the final component of the package then treat it
184 # as a default. For example, 'foo::bar' library 'bar' would end up as
185 # 'foo::bar'.
186 string(REGEX REPLACE "^.*::" "" _PACKAGE_DIR ${_RULE_PACKAGE})
187 if(${_PACKAGE_DIR} STREQUAL ${_RULE_NAME})
188
Lei Zhangd454ee42020-06-02 11:48:57 -0700189 add_library(${_RULE_PACKAGE} ALIAS ${_NAME})
Ben Vanik512d2d32019-09-20 13:22:34 -0700190 endif()
191endfunction()