CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #/|/ Copyright (c) Prusa Research 2018 - 2022 Lukáš Matěna @lukasmatena, Tomáš Mészáros @tamasmeszaros, Filip Sykala @Jony01, Vojtěch Bubník @bubnikv, Vojtěch Král @vojtechkral
  2. #/|/
  3. #/|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
  4. #/|/
  5. #
  6. # This CMake project downloads, configures and builds Slic3r++ dependencies on Unix and Windows.
  7. #
  8. # When using this script, it's recommended to perform an out-of-source build using CMake.
  9. #
  10. # All the dependencies are installed in a `destdir` directory in the root of the build directory,
  11. # in a traditional Unix-style prefix structure. The destdir can be used directly by CMake
  12. # when building Slic3r - to do this, set the CMAKE_PREFIX_PATH to ${destdir}/usr/local.
  13. # Warning: On UNIX/Linux, you also need to set -DSlic3r_STATIC=1 when building Slic3r.
  14. #
  15. # For better clarity of console output, it's recommended to _not_ use a parallelized build
  16. # for the top-level command, ie. use `make -j 1` or `ninja -j 1` to force single-threaded top-level
  17. # build. This doesn't degrade performance as individual dependencies are built in parallel fashion
  18. # if supported by the dependency.
  19. #
  20. # On Windows, architecture (64 vs 32 bits) is judged based on the compiler variant.
  21. # To build dependencies for either 64 or 32 bit OS, use the respective compiler command line.
  22. #
  23. # WARNING: On UNIX platforms wxWidgets hardcode the destdir path into its `wx-conffig` utility,
  24. # therefore, unfortunatelly, the installation cannot be copied/moved elsewhere without re-installing wxWidgets.
  25. #
  26. cmake_minimum_required(VERSION 3.12)
  27. project(Slic3r-deps)
  28. # timestamp of the extracted content from archive set to the extraction date. OLD to set to the timestamp from the archive.
  29. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
  30. cmake_policy(SET CMP0135 NEW)
  31. endif ()
  32. # Redefine BUILD_SHARED_LIBS with default being OFF
  33. option(BUILD_SHARED_LIBS "Build shared libraries instead of static (experimental)" OFF)
  34. # List libraries to be excluded from build
  35. set(${PROJECT_NAME}_PACKAGE_EXCLUDES "" CACHE STRING "Exclude packages matching this regex pattern")
  36. # Support legacy parameter DESTDIR
  37. if (DESTDIR)
  38. set(${PROJECT_NAME}_DEP_INSTALL_PREFIX ${DESTDIR}/usr/local CACHE PATH "Destination directory" FORCE)
  39. endif ()
  40. # Support legacy parameter DEP_DOWNLOAD_DIR
  41. if (DEP_DOWNLOAD_DIR)
  42. set(${PROJECT_NAME}_DEP_DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR} CACHE PATH "Path for downloaded source packages." FORCE)
  43. endif ()
  44. # Slightly controversial
  45. set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake/modules)
  46. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
  47. cmake_policy(SET CMP0127 NEW)
  48. endif ()
  49. if (MSVC)
  50. option(DEP_DEBUG "Build in debug version of packages automatically" ON)
  51. endif ()
  52. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
  53. cmake_policy(SET CMP0135 NEW)
  54. endif ()
  55. include(${PROJECT_SOURCE_DIR}/../cmake/modules/AddCMakeProject.cmake)
  56. macro(list_projects result curdir)
  57. file(GLOB children RELATIVE ${curdir} ${curdir}/*)
  58. set(dirlist "")
  59. foreach(child ${children})
  60. if(IS_DIRECTORY ${curdir}/${child})
  61. string(REGEX MATCH "^\\+([a-zA-Z0-9]+)" is_package_dir ${child})
  62. if(is_package_dir AND EXISTS ${curdir}/${child}/${CMAKE_MATCH_1}.cmake)
  63. list(APPEND dirlist ${CMAKE_MATCH_1})
  64. endif()
  65. endif()
  66. endforeach()
  67. set(${result} ${dirlist})
  68. endmacro()
  69. function(dep_message mode msg)
  70. if (NOT DEP_MESSAGES_WRITTEN)
  71. message(${mode} "${msg}")
  72. endif()
  73. endfunction ()
  74. # Always ON options:
  75. if (MSVC)
  76. if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
  77. dep_message(STATUS "Detected 64-bit compiler => building 64-bit deps bundle")
  78. set(DEPS_BITS 64)
  79. elseif ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
  80. dep_message(STATUS "Detected 32-bit compiler => building 32-bit deps bundle")
  81. set(DEPS_BITS 32)
  82. else ()
  83. dep_message(FATAL_ERROR "Unable to detect architecture!")
  84. endif ()
  85. else ()
  86. set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON")
  87. endif ()
  88. if (APPLE)
  89. if (CMAKE_OSX_DEPLOYMENT_TARGET)
  90. set(DEP_OSX_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}")
  91. dep_message(STATUS "OS X Deployment Target: ${DEP_OSX_TARGET}")
  92. else ()
  93. # Attempt to infer the SDK version from the CMAKE_OSX_SYSROOT,
  94. # this is done because wxWidgets need the min version explicitly set
  95. string(REGEX MATCH "[0-9]+[.][0-9]+[.]sdk$" DEP_OSX_TARGET "${CMAKE_OSX_SYSROOT}")
  96. string(REGEX MATCH "^[0-9]+[.][0-9]+" DEP_OSX_TARGET "${DEP_OSX_TARGET}")
  97. if (NOT DEP_OSX_TARGET)
  98. message(FATAL_ERROR "Could not determine OS X SDK version. Please use -DCMAKE_OSX_DEPLOYMENT_TARGET=<version>")
  99. endif ()
  100. dep_message(STATUS "OS X Deployment Target (inferred from SDK): ${DEP_OSX_TARGET}")
  101. endif ()
  102. # This ensures dependencies don't use SDK features which are not available in the version specified by Deployment target
  103. # That can happen when one uses a recent SDK but specifies an older Deployment target
  104. set(DEP_WERRORS_SDK "-Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
  105. set(DEP_CMAKE_OPTS
  106. "-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
  107. "-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}"
  108. "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}"
  109. "-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}"
  110. "-DCMAKE_CXX_FLAGS=${DEP_WERRORS_SDK}"
  111. "-DCMAKE_C_FLAGS=${DEP_WERRORS_SDK}"
  112. "-DCMAKE_FIND_FRAMEWORK=LAST"
  113. "-DCMAKE_FIND_APPBUNDLE=LAST"
  114. )
  115. endif ()
  116. list_projects(FOUND_PACKAGES ${CMAKE_CURRENT_LIST_DIR})
  117. dep_message(STATUS "Found external package definitions: ${FOUND_PACKAGES}")
  118. # Current list of all required dependencies for PS (top level)
  119. set(REQUIRED_PACKAGES
  120. Boost
  121. Catch2
  122. Cereal
  123. CURL
  124. EXPAT
  125. NLopt
  126. GLEW
  127. TBB
  128. Qhull
  129. wxWidgets
  130. OpenVDB
  131. CGAL
  132. OCCT
  133. ZLIB
  134. LibBGCode
  135. )
  136. set(${PROJECT_NAME}_PLATFORM_PACKAGES "" CACHE STRING "Select packages which are provided by the platform" )
  137. set(SYSTEM_PROVIDED_PACKAGES OpenGL)
  138. if (UNIX)
  139. # On UNIX systems (including Apple) ZLIB should be available
  140. list(APPEND SYSTEM_PROVIDED_PACKAGES ZLIB)
  141. if (APPLE)
  142. # Deal with CURL on Apple (See issue #5984 on GH):
  143. # Mac SDK should include CURL from at least version 10.12
  144. list(APPEND SYSTEM_PROVIDED_PACKAGES CURL)
  145. endif ()
  146. endif ()
  147. list(APPEND SYSTEM_PROVIDED_PACKAGES ${${PROJECT_NAME}_PLATFORM_PACKAGES})
  148. list(REMOVE_DUPLICATES SYSTEM_PROVIDED_PACKAGES)
  149. include(CMakeDependentOption)
  150. option(${PROJECT_NAME}_SELECT_ALL "Choose all external projects to be built." ON)
  151. find_package(Git REQUIRED)
  152. # The default command line for patching. Only works for newer
  153. set(PATCH_CMD ${GIT_EXECUTABLE} apply --verbose --ignore-space-change --whitespace=fix)
  154. # all required package targets that have existing definitions will be gathered here
  155. set(DEPS_TO_BUILD "")
  156. set(_build_list "")
  157. set(_build_list_toplevel "")
  158. set(_checked_list "")
  159. # function to check if a package ought to be provided by the platform can really be found
  160. function (check_system_package pkg checked_list)
  161. if (NOT ${pkg} IN_LIST ${checked_list})
  162. find_package(${pkg})
  163. if (NOT ${pkg}_FOUND)
  164. dep_message(WARNING "No ${pkg} found in system altough marked as system provided. This might cause trouble building the dependencies on this platform")
  165. endif ()
  166. list(APPEND ${checked_list} ${pkg})
  167. set (${checked_list} ${${checked_list}} PARENT_SCOPE)
  168. endif ()
  169. endfunction()
  170. # Go through all the found package definition folders and filter them according to the provided cache options
  171. set(SUPPORTED_PACKAGES "")
  172. foreach (pkg ${FOUND_PACKAGES})
  173. cmake_dependent_option(${PROJECT_NAME}_SELECT_${pkg} "Select package ${pkg} to be built." OFF "NOT ${PROJECT_NAME}_SELECT_ALL" OFF)
  174. if (NOT ${PROJECT_NAME}_PACKAGE_EXCLUDES MATCHES ${pkg} AND (${PROJECT_NAME}_SELECT_ALL OR ${PROJECT_NAME}_SELECT_${pkg}))
  175. include(+${pkg}/${pkg}.cmake)
  176. list(APPEND SUPPORTED_PACKAGES ${pkg})
  177. if (${pkg} IN_LIST SYSTEM_PROVIDED_PACKAGES)
  178. check_system_package(${pkg} _checked_list)
  179. elseif (${pkg} IN_LIST REQUIRED_PACKAGES)
  180. list(APPEND DEPS_TO_BUILD ${pkg})
  181. endif ()
  182. endif ()
  183. endforeach()
  184. # Establish dependency graph
  185. foreach (pkg ${SUPPORTED_PACKAGES})
  186. if (${pkg} IN_LIST DEPS_TO_BUILD)
  187. list(APPEND _build_list dep_${pkg})
  188. list(APPEND _build_list_toplevel dep_${pkg})
  189. endif ()
  190. foreach(deppkg ${DEP_${pkg}_DEPENDS})
  191. if (${deppkg} IN_LIST SYSTEM_PROVIDED_PACKAGES)
  192. check_system_package(${deppkg} _checked_list)
  193. elseif(TARGET dep_${deppkg})
  194. dep_message(STATUS "Mapping dep_${deppkg} => dep_${pkg}")
  195. add_dependencies(dep_${pkg} dep_${deppkg})
  196. if (${pkg} IN_LIST REQUIRED_PACKAGES)
  197. list(APPEND _build_list dep_${deppkg})
  198. endif ()
  199. endif ()
  200. endforeach()
  201. endforeach()
  202. list(REMOVE_DUPLICATES _build_list)
  203. dep_message(STATUS "Building dep targets (${CMAKE_BUILD_TYPE}): ${_build_list}")
  204. add_custom_target(deps ALL DEPENDS ${_build_list_toplevel})
  205. # Support legacy option DEP_DEBUG on MSVC to build debug libraries in the same cmake run as for CMAKE_BUILD_TYPE:
  206. if (DEP_DEBUG AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
  207. # MSVC has this nice feature to not be able to link release mode libs to Debug mode
  208. # projects
  209. # Exclude the libraries which have no problem to link to Debug builds in
  210. # Release mode (mostly C libraries)
  211. set(DEP_DEBUG_EXCLUDES GMP MPFR OpenSSL NanoSVG TIFF JPEG ZLIB heatshrink)
  212. if (UNIX)
  213. # Making a separate debug build on Unix of wx is a nightmare
  214. list(APPEND DEP_DEBUG_EXCLUDES wxWidgets)
  215. endif ()
  216. # Create the list of targets needed in debug mode
  217. set(_build_list_dbg "")
  218. set(_build_list_filt ${_build_list})
  219. list(JOIN DEP_DEBUG_EXCLUDES "|" _excl_regexp)
  220. list(FILTER _build_list_filt EXCLUDE REGEX "${_excl_regexp}")
  221. foreach (t ${_build_list_filt})
  222. list(APPEND _build_list_dbg ${t}_debug)
  223. endforeach()
  224. # Create a subdirectory for the Debug build within the current binary dir:
  225. file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/_d)
  226. execute_process(
  227. COMMAND ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR} -G${CMAKE_GENERATOR}
  228. -DCMAKE_BUILD_TYPE=Debug
  229. -DDEP_WX_GTK3=${DEP_WX_GTK3}
  230. -D${PROJECT_NAME}_DEP_DOWNLOAD_DIR=${${PROJECT_NAME}_DEP_DOWNLOAD_DIR}
  231. -D${PROJECT_NAME}_DEP_INSTALL_PREFIX=${${PROJECT_NAME}_DEP_INSTALL_PREFIX}
  232. -D${PROJECT_NAME}_PACKAGE_EXCLUDES="${_excl_regexp}"
  233. -D${PROJECT_NAME}_SELECT_ALL=${${PROJECT_NAME}_SELECT_ALL}
  234. -D${PROJECT_NAME}_DEP_BUILD_VERBOSE=${${PROJECT_NAME}_DEP_BUILD_VERBOSE}
  235. -DCMAKE_DEBUG_POSTFIX=d
  236. #TODO: forward per-package selector variables
  237. -DDEP_MESSAGES_WRITTEN=ON
  238. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/_d
  239. OUTPUT_QUIET
  240. )
  241. dep_message(STATUS "Building dep targets (Debug): ${_build_list_dbg}")
  242. # Each lib will have a dep_<package>_debug target to build only the debug counterpart
  243. # Not part of ALL (problem with parallelization)
  244. foreach(pkgtgt ${_build_list_filt})
  245. add_custom_target(${pkgtgt}_debug
  246. COMMAND ${CMAKE_COMMAND} --build . --target ${pkgtgt}
  247. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/_d
  248. USES_TERMINAL
  249. )
  250. endforeach()
  251. # Can be used to build all the debug libs
  252. string(JOIN " " _build_list_filt_targets "${_build_list_filt}")
  253. add_custom_target(deps_debug ALL
  254. COMMAND ${CMAKE_COMMAND} --build . --target ${_build_list_filt_targets}
  255. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/_d
  256. USES_TERMINAL
  257. )
  258. # The Release must be built before, as there are libs in this debug session which need
  259. # the release versions of the excluded libs
  260. add_dependencies(deps_debug deps)
  261. endif ()
  262. set(DEP_MESSAGES_WRITTEN ON CACHE BOOL "")
  263. install(CODE "message(STATUS \"Built packages succesfully.\")")