1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
|
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
cmake_minimum_required(VERSION 3.25)
# Build the Arrow C++ libraries using ExternalProject_Add.
function(build_arrow)
set(options)
set(one_value_args)
set(multi_value_args)
cmake_parse_arguments(ARG
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()
set(ARROW_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/arrow_ep-prefix")
set(ARROW_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/arrow_ep-build")
# Supply -DARROW_CXXFLAGS=-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR to fix
# a segfault on windows. See https://github.com/apache/arrow/issues/42015.
set(ARROW_CMAKE_ARGS
"-DCMAKE_INSTALL_PREFIX=${ARROW_PREFIX}"
"-DCMAKE_INSTALL_LIBDIR=lib"
"-DARROW_BUILD_STATIC=OFF"
"-DARROW_CSV=ON"
"-DARROW_CXXFLAGS=-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
add_library(arrow_shared SHARED IMPORTED)
set(ARROW_LIBRARY_TARGET arrow_shared)
# Set the runtime shared library (.dll, .so, or .dylib)
if(WIN32)
# The shared library (i.e. .dll) is located in the "bin" directory.
set(ARROW_SHARED_LIBRARY_DIR "${ARROW_PREFIX}/bin")
else()
# The shared library (i.e. .so or .dylib) is located in the "lib" directory.
set(ARROW_SHARED_LIBRARY_DIR "${ARROW_PREFIX}/lib")
endif()
set(ARROW_SHARED_LIB_FILENAME
"${CMAKE_SHARED_LIBRARY_PREFIX}arrow${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(ARROW_SHARED_LIB "${ARROW_SHARED_LIBRARY_DIR}/${ARROW_SHARED_LIB_FILENAME}")
set_target_properties(arrow_shared PROPERTIES IMPORTED_LOCATION ${ARROW_SHARED_LIB})
# Set the link-time import library (.lib)
if(WIN32)
# The import library (i.e. .lib) is located in the "lib" directory.
set(ARROW_IMPORT_LIB_FILENAME
"${CMAKE_IMPORT_LIBRARY_PREFIX}arrow${CMAKE_IMPORT_LIBRARY_SUFFIX}")
set(ARROW_IMPORT_LIB "${ARROW_PREFIX}/lib/${ARROW_IMPORT_LIB_FILENAME}")
set_target_properties(arrow_shared PROPERTIES IMPORTED_IMPLIB ${ARROW_IMPORT_LIB})
endif()
# Set the include directories
set(ARROW_INCLUDE_DIR "${ARROW_PREFIX}/include")
file(MAKE_DIRECTORY "${ARROW_INCLUDE_DIR}")
set_target_properties(arrow_shared PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
${ARROW_INCLUDE_DIR})
# Set the build byproducts for the ExternalProject build
if(WIN32)
set(ARROW_BUILD_BYPRODUCTS "${ARROW_IMPORT_LIB}")
else()
set(ARROW_BUILD_BYPRODUCTS "${ARROW_SHARED_LIB}")
endif()
# Building the Arrow C++ libraries requires ExternalProject.
include(ExternalProject)
externalproject_add(arrow_ep
SOURCE_DIR "${CMAKE_SOURCE_DIR}/../cpp"
BINARY_DIR "${ARROW_BINARY_DIR}"
CMAKE_ARGS "${ARROW_CMAKE_ARGS}"
BUILD_BYPRODUCTS "${ARROW_BUILD_BYPRODUCTS}")
add_dependencies(${ARROW_LIBRARY_TARGET} arrow_ep)
endfunction()
set(CMAKE_CXX_STANDARD 20)
set(MLARROW_VERSION "23.0.1")
string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" MLARROW_BASE_VERSION "${MLARROW_VERSION}")
project(mlarrow VERSION "${MLARROW_BASE_VERSION}")
# On Windows, set the global variable that determines the MSVC runtime library that is
# used by targets created in this CMakeLists.txt file.
if(WIN32)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
endif()
# Add tools/cmake directory to the CMAKE_MODULE_PATH.
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/tools/cmake)
# Configure find_package to look for arrow-config.cmake in Config mode
# underneath the Arrow installation directory hierarchy specified
# by ARROW_HOME or Arrow_ROOT.
# NOTE: ARROW_HOME is supported for backwards compatibility.
if(ARROW_HOME AND NOT Arrow_ROOT)
set(Arrow_ROOT "${ARROW_HOME}")
endif()
# Multi-Configuration generators (e.g. Visual Studio or XCode) place their build artifacts
# in a subdirectory named ${CMAKE_BUILD_TYPE} by default, where ${CMAKE_BUILD_TYPE} varies
# depending on the chosen build configuration (e.g. Release or Debug).
get_property(GENERATOR_IS_MULTI_CONFIG_VALUE GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG_VALUE)
set(MATLAB_BUILD_OUTPUT_DIR "${CMAKE_BINARY_DIR}/$<CONFIG>")
else()
set(MATLAB_BUILD_OUTPUT_DIR "${CMAKE_BINARY_DIR}")
endif()
find_package(Arrow QUIET)
if(NOT Arrow_FOUND)
build_arrow()
endif()
# MATLAB is Required
find_package(Matlab REQUIRED COMPONENTS MAIN_PROGRAM)
message(STATUS "Mex Library: ${Matlab_MEX_LIBRARY}")
message(STATUS "Mex Include Folder: ${Matlab_INCLUDE_DIRS}")
# ARROW_SHARED_LIB
# On Windows, this will be ARROW_HOME/bin/arrow.dll and on Linux and macOS, it is the arrow.so/dylib in the newly built arrow_shared library.
if(NOT Arrow_FOUND)
message(STATUS "ARROW_SHARED_LIB will be set using IMPORTED_LOCATION value when building."
)
get_target_property(ARROW_SHARED_LIB arrow_shared IMPORTED_LOCATION)
else()
# If not building Arrow, ARROW_SHARED_LIB derived from ARROW_PREFIX set to the ARROW_HOME specified with cmake would be non-empty.
message(STATUS "ARROW_SHARED_LIB: ${ARROW_SHARED_LIB}")
endif()
# ARROW_LINK_LIB
# On Windows, we use the arrow.lib for linking arrow_matlab against the Arrow C++ library.
# The location of arrow.lib is previously saved in IMPORTED_IMPLIB.
if(WIN32)
# If not building Arrow, IMPORTED_IMPLIB will be empty.
# Then set ARROW_LINK_LIB to ARROW_IMPORT_LIB which would have been derived from ARROW_PREFIX set to the ARROW_HOME specified with cmake. This will avoid the ARROW_LINK_LIB set to NOTFOUND error.
# The ARROW_IMPORT_LIB should be ARROW_HOME/lib/arrow.lib on Windows.
if(NOT Arrow_FOUND)
message(STATUS "ARROW_LINK_LIB will be set using IMPORTED_IMPLIB value when building."
)
get_target_property(ARROW_LINK_LIB arrow_shared IMPORTED_IMPLIB)
else()
set(ARROW_LINK_LIB "${ARROW_IMPORT_LIB}")
message(STATUS "Setting ARROW_LINK_LIB to ARROW_IMPORT_LIB: ${ARROW_IMPORT_LIB}, which is derived from the ARROW_HOME provided."
)
endif()
else()
# On Linux and macOS, it is the arrow.so/dylib in the newly built arrow_shared library used for linking.
# On Unix, this is the same as ARROW_SHARED_LIB.
message(STATUS "Setting ARROW_LINK_LIB to ARROW_SHARED_LIB as they are same on Unix.")
set(ARROW_LINK_LIB "${ARROW_SHARED_LIB}")
endif()
# ARROW_INCLUDE_DIR should be set so that header files in the include directory can be found correctly.
# The value of ARROW_INCLUDE_DIR should be ARROW_HOME/include on all platforms.
if(NOT Arrow_FOUND)
message(STATUS "ARROW_INCLUDE_DIR will be set using INTERFACE_INCLUDE_DIRECTORIES value when building."
)
get_target_property(ARROW_INCLUDE_DIR arrow_shared INTERFACE_INCLUDE_DIRECTORIES)
else()
# If not building Arrow, ARROW_INCLUDE_DIR derived from ARROW_PREFIX set to the ARROW_HOME specified with cmake would be non-empty.
message(STATUS "ARROW_INCLUDE_DIR: ${ARROW_INCLUDE_DIR}")
endif()
# ##############################################################################
# Install
# ##############################################################################
# Create a subdirectory at CMAKE_INSTALL_PREFIX to install the interface.
set(CMAKE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/arrow_matlab")
# Build the MATLAB Interface to Arrow.
include(BuildMatlabArrowInterface)
# Install MATLAB source files.
# On macOS, exclude '.DS_Store' files in the source tree from installation.
install(DIRECTORY "${CMAKE_SOURCE_DIR}/src/matlab/"
DESTINATION ${CMAKE_INSTALL_DIR}
PATTERN ".DS_Store" EXCLUDE)
get_filename_component(ARROW_SHARED_LIB_DIR ${ARROW_SHARED_LIB} DIRECTORY)
get_filename_component(ARROW_SHARED_LIB_FILENAME ${ARROW_SHARED_LIB} NAME_WE)
if(NOT Arrow_FOUND)
if(APPLE)
# Install libarrow.dylib (symlink) and the real files it points to.
# on macOS, we need to match these files: libarrow.dylib
# libarrow.1300.dylib
# libarrow.1300.0.0.dylib
# where the version number might change.
set(SHARED_LIBRARY_VERSION_REGEX
"${ARROW_SHARED_LIB_FILENAME}(([.][0-9]+)?([.][0-9]+)?([.][0-9]+)?)${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
elseif(UNIX AND NOT CYGWIN)
# Install libarrow.so (symlink) and the real files it points to.
# On Linux, we need to match these files: libarrow.so
# libarrow.so.1200
# libarrow.so.1200.0.0
# where the version number might change.
set(SHARED_LIBRARY_VERSION_REGEX
"${ARROW_SHARED_LIB_FILENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}(([.][0-9]+)?([.][0-9]+)?([.][0-9]+)?)"
)
else()
set(SHARED_LIBRARY_VERSION_REGEX
${ARROW_SHARED_LIB_FILENAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
endif()
endif()
# MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE toggles whether an addpath command to add the install
# directory path to the MATLAB Search Path is added to the startup.m file located in the MATLAB
# userpath directory.
option(MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE
"Sets whether the path to the install directory should be added to the startup.m file located at the MATLAB userpath"
OFF)
# If MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE is specified ON and MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH
# is not specified, then set MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH=OFF.
if(MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE AND NOT DEFINED
MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH)
set(MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH OFF)
endif()
# MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH toggles whether the path to the install directory should
# be directly added to the MATLAB Search Path.
option(MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH
"Sets whether the path to the install directory should be directly added to the MATLAB Search Path"
ON)
if(MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH OR MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE)
set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/tools")
# Pass Matlab_MAIN_PROGRAM, TOOLS_DIR, and INSTALL_DIR to the install step
# code/script execution scope.
install(CODE "set(Matlab_MAIN_PROGRAM \"${Matlab_MAIN_PROGRAM}\")")
install(CODE "set(TOOLS_DIR \"${TOOLS_DIR}\")")
install(CODE "set(INSTALL_DIR \"${CMAKE_INSTALL_DIR}\")")
install(CODE "set(MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE \"${MATLAB_ADD_INSTALL_DIR_TO_STARTUP_FILE}\")"
)
install(CODE "set(MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH \"${MATLAB_ADD_INSTALL_DIR_TO_SEARCH_PATH}\")"
)
# Call the CMake script that runs the MATLAB function to add the install directory
# to the MATLAB Search Path or add a command to the MATLAB startup file to add the
# install directory to the MATLAB Search Path.
install(SCRIPT "${TOOLS_DIR}/UpdateMatlabSearchPath.cmake")
endif()
|