blob: d9cd38ed158a33d7e537b79310eb55e3809185af [file] [log] [blame]
Ben Vanik512d2d32019-09-20 13:22:34 -07001# Copyright 2019 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15include(CMakeParseArguments)
16
17# external_cc_library()
18#
19# CMake function to imitate Bazel's cc_library rule.
20# This is used for external libraries (from third_party, etc) that don't live
21# in the IREE namespace.
22#
23# Parameters:
24# PACKAGE: Name of the package (overrides actual path)
25# NAME: Name of target (see Note)
26# ROOT: Path to the source root where files are found
27# HDRS: List of public header files for the library
28# SRCS: List of source files for the library
Scott Toddda2d2392020-03-09 16:42:55 -070029# DATA: List of other targets and files required for this binary
Ben Vanik512d2d32019-09-20 13:22:34 -070030# DEPS: List of other libraries to be linked in to the binary targets
31# COPTS: List of private compile options
32# DEFINES: List of public defines
33# INCLUDES: Include directories to add to dependencies
34# LINKOPTS: List of link options
Ben Vanik6b112ef2019-10-03 10:45:14 -070035# PUBLIC: Add this so that this library will be exported under ${PACKAGE}::
36# Also in IDE, target will appear in ${PACKAGE} folder while non PUBLIC will be
37# in ${PACKAGE}/internal.
38# TESTONLY: When added, this target will only be built if user passes
39# -DIREE_BUILD_TESTS=ON to CMake.
Ben Vanik512d2d32019-09-20 13:22:34 -070040#
41# Note:
Ben Vanik6b112ef2019-10-03 10:45:14 -070042# By default, external_cc_library will always create a library named
43# ${PACKAGE}_${NAME}, and alias target ${PACKAGE}::${NAME}. The ${PACKAGE}::
44# form should always be used. This is to reduce namespace pollution.
Ben Vanik512d2d32019-09-20 13:22:34 -070045#
46# external_cc_library(
47# PACKAGE
48# some_external_thing
49# NAME
50# awesome
51# ROOT
52# "third_party/foo"
53# HDRS
54# "a.h"
55# SRCS
56# "a.cc"
57# )
58# external_cc_library(
59# PACKAGE
60# some_external_thing
61# NAME
62# fantastic_lib
63# ROOT
64# "third_party/foo"
65# SRCS
66# "b.cc"
67# DEPS
68# some_external_thing::awesome # not "awesome" !
69# PUBLIC
70# )
71#
72# iree_cc_library(
73# NAME
74# main_lib
75# ...
76# DEPS
77# some_external_thing::fantastic_lib
78# )
Ben Vanik512d2d32019-09-20 13:22:34 -070079function(external_cc_library)
Ben Vanik6b112ef2019-10-03 10:45:14 -070080 cmake_parse_arguments(_RULE
Ben Vanikbf091d32020-11-16 05:53:58 -080081 "PUBLIC;TESTONLY"
Ben Vanik512d2d32019-09-20 13:22:34 -070082 "PACKAGE;NAME;ROOT"
Scott Toddda2d2392020-03-09 16:42:55 -070083 "HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;INCLUDES"
Ben Vanik512d2d32019-09-20 13:22:34 -070084 ${ARGN}
85 )
86
Lei Zhangd454ee42020-06-02 11:48:57 -070087 if(_RULE_TESTONLY AND NOT IREE_BUILD_TESTS)
88 return()
89 endif()
Ben Vanik512d2d32019-09-20 13:22:34 -070090
Lei Zhangd454ee42020-06-02 11:48:57 -070091 # Prefix the library with the package name.
92 string(REPLACE "::" "_" _PACKAGE_NAME ${_RULE_PACKAGE})
93 set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}")
Ben Vanik512d2d32019-09-20 13:22:34 -070094
Lei Zhangd454ee42020-06-02 11:48:57 -070095 # Prefix paths with the root.
96 list(TRANSFORM _RULE_HDRS PREPEND ${_RULE_ROOT})
97 list(TRANSFORM _RULE_SRCS PREPEND ${_RULE_ROOT})
98
99 # Check if this is a header-only library.
100 # Note that as of February 2019, many popular OS's (for example, Ubuntu
101 # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't
102 # use list(FILTER...)
103 set(_CC_SRCS "${_RULE_SRCS}")
104 foreach(src_file IN LISTS _CC_SRCS)
105 if(${src_file} MATCHES ".*\\.(h|inc)")
106 list(REMOVE_ITEM _CC_SRCS "${src_file}")
107 endif()
108 endforeach()
109 if("${_CC_SRCS}" STREQUAL "")
110 set(_RULE_IS_INTERFACE 1)
111 else()
112 set(_RULE_IS_INTERFACE 0)
113 endif()
114
115 if(NOT _RULE_IS_INTERFACE)
116 add_library(${_NAME} STATIC "")
117 target_sources(${_NAME}
118 PRIVATE
119 ${_RULE_SRCS}
120 ${_RULE_HDRS}
121 )
Ben Vanikafd7abe2020-10-07 09:01:53 -0700122 target_include_directories(${_NAME} SYSTEM
Lei Zhangd454ee42020-06-02 11:48:57 -0700123 PUBLIC
Ben Vanik6bc6f902020-11-16 05:37:08 -0800124 "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
125 "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
Lei Zhangd454ee42020-06-02 11:48:57 -0700126 "$<BUILD_INTERFACE:${_RULE_INCLUDES}>"
127 )
128 target_compile_options(${_NAME}
129 PRIVATE
130 ${_RULE_COPTS}
131 ${IREE_DEFAULT_COPTS}
132 )
133 target_link_libraries(${_NAME}
134 PUBLIC
135 ${_RULE_DEPS}
136 PRIVATE
Lei Zhangd454ee42020-06-02 11:48:57 -0700137 ${IREE_DEFAULT_LINKOPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800138 ${_RULE_LINKOPTS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700139 )
140 target_compile_definitions(${_NAME}
141 PUBLIC
142 ${_RULE_DEFINES}
143 )
144 iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
145
Lei Zhangd454ee42020-06-02 11:48:57 -0700146 # Add all external targets to a a folder in the IDE for organization.
147 if(_RULE_PUBLIC)
148 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party)
149 elseif(_RULE_TESTONLY)
150 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party/test)
Ben Vanik512d2d32019-09-20 13:22:34 -0700151 else()
Lei Zhangd454ee42020-06-02 11:48:57 -0700152 set_property(TARGET ${_NAME} PROPERTY FOLDER third_party/internal)
Ben Vanik512d2d32019-09-20 13:22:34 -0700153 endif()
154
Lei Zhangd454ee42020-06-02 11:48:57 -0700155 # INTERFACE libraries can't have the CXX_STANDARD property set
156 set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD})
157 set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
158 else()
159 # Generating header-only library
160 add_library(${_NAME} INTERFACE)
Ben Vanikafd7abe2020-10-07 09:01:53 -0700161 target_include_directories(${_NAME} SYSTEM
Lei Zhangd454ee42020-06-02 11:48:57 -0700162 INTERFACE
Ben Vanik6bc6f902020-11-16 05:37:08 -0800163 "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
164 "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
Lei Zhangd454ee42020-06-02 11:48:57 -0700165 "$<BUILD_INTERFACE:${_RULE_INCLUDES}>"
166 )
167 target_compile_options(${_NAME}
168 INTERFACE
Lei Zhangd454ee42020-06-02 11:48:57 -0700169 ${IREE_DEFAULT_COPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800170 ${_RULE_COPTS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700171 )
172 target_link_libraries(${_NAME}
173 INTERFACE
Lei Zhangd454ee42020-06-02 11:48:57 -0700174 ${IREE_DEFAULT_LINKOPTS}
Ben Vanikbf4069e2020-11-14 11:23:01 -0800175 ${_RULE_LINKOPTS}
176 ${_RULE_DEPS}
Lei Zhangd454ee42020-06-02 11:48:57 -0700177 )
178 iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
179 target_compile_definitions(${_NAME}
180 INTERFACE
181 ${_RULE_DEFINES}
182 )
183 endif()
Ben Vanik512d2d32019-09-20 13:22:34 -0700184
Lei Zhangd454ee42020-06-02 11:48:57 -0700185 add_library(${_RULE_PACKAGE}::${_RULE_NAME} ALIAS ${_NAME})
186 if(${_RULE_PACKAGE} STREQUAL ${_RULE_NAME})
187 add_library(${_RULE_PACKAGE} ALIAS ${_NAME})
Ben Vanik512d2d32019-09-20 13:22:34 -0700188 endif()
189endfunction()