1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements.  See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership.  The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License.  You may obtain a copy of the License at
8#
9#   http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied.  See the License for the
15# specific language governing permissions and limitations
16# under the License.
17
18message(STATUS "Using vcpkg to find dependencies")
19
20# ----------------------------------------------------------------------
21# Define macros
22
23# macro to list subdirectirectories (non-recursive)
24macro(list_subdirs SUBDIRS DIR)
25  file(GLOB children_
26       RELATIVE ${DIR}
27       ${DIR}/*)
28  set(subdirs_ "")
29  foreach(child_ ${children_})
30    if(IS_DIRECTORY "${DIR}/${child_}")
31      list(APPEND subdirs_ ${child_})
32    endif()
33  endforeach()
34  set("${SUBDIRS}" ${subdirs_})
35  unset(children_)
36  unset(subdirs_)
37endmacro()
38
39# ----------------------------------------------------------------------
40# Get VCPKG_ROOT
41
42if(DEFINED CMAKE_TOOLCHAIN_FILE)
43  # Get it from the CMake variable CMAKE_TOOLCHAIN_FILE
44  get_filename_component(_VCPKG_DOT_CMAKE "${CMAKE_TOOLCHAIN_FILE}" NAME)
45  if(EXISTS "${CMAKE_TOOLCHAIN_FILE}" AND _VCPKG_DOT_CMAKE STREQUAL "vcpkg.cmake")
46    get_filename_component(_VCPKG_BUILDSYSTEMS_DIR "${CMAKE_TOOLCHAIN_FILE}" DIRECTORY)
47    get_filename_component(VCPKG_ROOT "${_VCPKG_BUILDSYSTEMS_DIR}/../.." ABSOLUTE)
48  else()
49    message(FATAL_ERROR "vcpkg toolchain file not found at path specified in -DCMAKE_TOOLCHAIN_FILE"
50    )
51  endif()
52else()
53  if(DEFINED VCPKG_ROOT)
54    # Get it from the CMake variable VCPKG_ROOT
55    find_program(_VCPKG_BIN vcpkg
56                 PATHS "${VCPKG_ROOT}"
57                 NO_DEFAULT_PATH)
58    if(NOT _VCPKG_BIN)
59      message(FATAL_ERROR "vcpkg not found in directory specified in -DVCPKG_ROOT")
60    endif()
61  elseif(DEFINED ENV{VCPKG_ROOT})
62    # Get it from the environment variable VCPKG_ROOT
63    set(VCPKG_ROOT $ENV{VCPKG_ROOT})
64    find_program(_VCPKG_BIN vcpkg
65                 PATHS "${VCPKG_ROOT}"
66                 NO_DEFAULT_PATH)
67    if(NOT _VCPKG_BIN)
68      message(FATAL_ERROR "vcpkg not found in directory in environment variable VCPKG_ROOT"
69      )
70    endif()
71  else()
72    # Get it from the file vcpkg.path.txt
73    find_program(_VCPKG_BIN vcpkg)
74    if(_VCPKG_BIN)
75      get_filename_component(_VCPKG_REAL_BIN "${_VCPKG_BIN}" REALPATH)
76      get_filename_component(VCPKG_ROOT "${_VCPKG_REAL_BIN}" DIRECTORY)
77    else()
78      if(CMAKE_HOST_WIN32)
79        set(_VCPKG_PATH_TXT "$ENV{LOCALAPPDATA}/vcpkg/vcpkg.path.txt")
80      else()
81        set(_VCPKG_PATH_TXT "$ENV{HOME}/.vcpkg/vcpkg.path.txt")
82      endif()
83      if(EXISTS "${_VCPKG_PATH_TXT}")
84        file(READ "${_VCPKG_PATH_TXT}" VCPKG_ROOT)
85      else()
86        message(FATAL_ERROR "vcpkg not found. Install vcpkg if not installed, "
87                            "then run vcpkg integrate install or set environment variable VCPKG_ROOT."
88        )
89      endif()
90      find_program(_VCPKG_BIN vcpkg
91                   PATHS "${VCPKG_ROOT}"
92                   NO_DEFAULT_PATH)
93      if(NOT _VCPKG_BIN)
94        message(FATAL_ERROR "vcpkg not found. Re-run vcpkg integrate install "
95                            "or set environment variable VCPKG_ROOT.")
96      endif()
97    endif()
98  endif()
99  set(CMAKE_TOOLCHAIN_FILE
100      "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
101      CACHE FILEPATH "Path to vcpkg CMake toolchain file")
102endif()
103message(STATUS "Using CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
104message(STATUS "Using VCPKG_ROOT: ${VCPKG_ROOT}")
105
106# ----------------------------------------------------------------------
107# Get VCPKG_TARGET_TRIPLET
108
109if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
110  set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}")
111endif()
112# Explicitly set manifest mode on if it is not set and vcpkg.json exists
113if(NOT DEFINED VCPKG_MANIFEST_MODE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg.json")
114  set(VCPKG_MANIFEST_MODE
115      ON
116      CACHE BOOL "Use vcpkg.json manifest")
117  message(STATUS "vcpkg.json manifest found. Using VCPKG_MANIFEST_MODE: ON")
118endif()
119# vcpkg can install packages in three different places
120set(_INST_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed") # try here first
121set(_INST_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg_installed") # try here second
122set(_INST_VCPKG_ROOT "${VCPKG_ROOT}/installed")
123# Iterate over the places
124foreach(_INST_DIR IN LISTS _INST_BUILD_DIR _INST_SOURCE_DIR _INST_VCPKG_ROOT "notfound")
125  if(_INST_DIR STREQUAL "notfound")
126    message(FATAL_ERROR "vcpkg installed libraries directory not found. "
127                        "Install packages with vcpkg before executing cmake.")
128  elseif(NOT EXISTS "${_INST_DIR}")
129    continue()
130  elseif((_INST_DIR STREQUAL _INST_BUILD_DIR OR _INST_DIR STREQUAL _INST_SOURCE_DIR)
131         AND NOT VCPKG_MANIFEST_MODE)
132    # Do not look for packages in the build or source dirs if manifest mode is off
133    message(STATUS "Skipped looking for installed packages in ${_INST_DIR} "
134                   "because -DVCPKG_MANIFEST_MODE=OFF")
135    continue()
136  else()
137    message(STATUS "Looking for installed packages in ${_INST_DIR}")
138  endif()
139  if(DEFINED VCPKG_TARGET_TRIPLET)
140    # Check if a subdirectory named VCPKG_TARGET_TRIPLET
141    # exists in the vcpkg installed directory
142    if(EXISTS "${_INST_DIR}/${VCPKG_TARGET_TRIPLET}")
143      set(_VCPKG_INSTALLED_DIR "${_INST_DIR}")
144      break()
145    endif()
146  else()
147    # Infer VCPKG_TARGET_TRIPLET from the name of the
148    # subdirectory in the vcpkg installed directory
149    list_subdirs(_VCPKG_TRIPLET_SUBDIRS "${_INST_DIR}")
150    list(REMOVE_ITEM _VCPKG_TRIPLET_SUBDIRS "vcpkg")
151    list(LENGTH _VCPKG_TRIPLET_SUBDIRS _NUM_VCPKG_TRIPLET_SUBDIRS)
152    if(_NUM_VCPKG_TRIPLET_SUBDIRS EQUAL 1)
153      list(GET _VCPKG_TRIPLET_SUBDIRS 0 VCPKG_TARGET_TRIPLET)
154      set(_VCPKG_INSTALLED_DIR "${_INST_DIR}")
155      break()
156    endif()
157  endif()
158endforeach()
159if(NOT DEFINED VCPKG_TARGET_TRIPLET)
160  message(FATAL_ERROR "Could not infer VCPKG_TARGET_TRIPLET. "
161                      "Specify triplet with -DVCPKG_TARGET_TRIPLET.")
162elseif(NOT DEFINED _VCPKG_INSTALLED_DIR)
163  message(FATAL_ERROR "Could not find installed vcpkg packages for triplet ${VCPKG_TARGET_TRIPLET}. "
164                      "Install packages with vcpkg before executing cmake.")
165endif()
166
167set(VCPKG_TARGET_TRIPLET
168    "${VCPKG_TARGET_TRIPLET}"
169    CACHE STRING "vcpkg triplet for the target environment")
170
171if(NOT DEFINED VCPKG_BUILD_TYPE)
172  set(VCPKG_BUILD_TYPE
173      "${LOWERCASE_BUILD_TYPE}"
174      CACHE STRING "vcpkg build type (release|debug)")
175endif()
176
177if(NOT DEFINED VCPKG_LIBRARY_LINKAGE)
178  if(ARROW_DEPENDENCY_USE_SHARED)
179    set(VCPKG_LIBRARY_LINKAGE "dynamic")
180  else()
181    set(VCPKG_LIBRARY_LINKAGE "static")
182  endif()
183  set(VCPKG_LIBRARY_LINKAGE
184      "${VCPKG_LIBRARY_LINKAGE}"
185      CACHE STRING "vcpkg preferred library linkage (static|dynamic)")
186endif()
187
188message(STATUS "Using vcpkg installed libraries directory: ${_VCPKG_INSTALLED_DIR}")
189message(STATUS "Using VCPKG_TARGET_TRIPLET: ${VCPKG_TARGET_TRIPLET}")
190message(STATUS "Using VCPKG_BUILD_TYPE: ${VCPKG_BUILD_TYPE}")
191message(STATUS "Using VCPKG_LIBRARY_LINKAGE: ${VCPKG_LIBRARY_LINKAGE}")
192
193set(ARROW_VCPKG_PREFIX
194    "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}"
195    CACHE PATH "Path to target triplet subdirectory in vcpkg installed directory")
196
197set(ARROW_VCPKG
198    ON
199    CACHE BOOL "Use vcpkg for dependencies")
200
201set(ARROW_DEPENDENCY_SOURCE
202    "SYSTEM"
203    CACHE STRING "The specified value VCPKG is implemented internally as SYSTEM" FORCE)
204
205set(BOOST_ROOT
206    "${ARROW_VCPKG_PREFIX}"
207    CACHE STRING "")
208set(BOOST_INCLUDEDIR
209    "${ARROW_VCPKG_PREFIX}/include/boost"
210    CACHE STRING "")
211set(BOOST_LIBRARYDIR
212    "${ARROW_VCPKG_PREFIX}/lib"
213    CACHE STRING "")
214set(OPENSSL_INCLUDE_DIR
215    "${ARROW_VCPKG_PREFIX}/include"
216    CACHE STRING "")
217set(OPENSSL_LIBRARIES
218    "${ARROW_VCPKG_PREFIX}/lib"
219    CACHE STRING "")
220set(OPENSSL_ROOT_DIR
221    "${ARROW_VCPKG_PREFIX}"
222    CACHE STRING "")
223set(Thrift_ROOT
224    "${ARROW_VCPKG_PREFIX}/lib"
225    CACHE STRING "")
226set(ZSTD_INCLUDE_DIR
227    "${ARROW_VCPKG_PREFIX}/include"
228    CACHE STRING "")
229set(ZSTD_ROOT
230    "${ARROW_VCPKG_PREFIX}"
231    CACHE STRING "")
232set(BROTLI_ROOT
233    "${ARROW_VCPKG_PREFIX}"
234    CACHE STRING "")
235set(LZ4_ROOT
236    "${ARROW_VCPKG_PREFIX}"
237    CACHE STRING "")
238
239if(CMAKE_HOST_WIN32)
240  set(LZ4_MSVC_LIB_PREFIX
241      ""
242      CACHE STRING "")
243  set(LZ4_MSVC_STATIC_LIB_SUFFIX
244      ""
245      CACHE STRING "")
246  set(ZSTD_MSVC_LIB_PREFIX
247      ""
248      CACHE STRING "")
249endif()
250