# 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 17) set(MLARROW_VERSION "22.0.0-SNAPSHOT") 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}/$") 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()