Viewport: cannot select object by clicking on its instances
[blender.git] / build_files / cmake / macros.cmake
1 # ***** BEGIN GPL LICENSE BLOCK *****
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # The Original Code is Copyright (C) 2006, Blender Foundation
18 # All rights reserved.
19 # ***** END GPL LICENSE BLOCK *****
20
21 macro(list_insert_after
22   list_id item_check item_add
23   )
24   set(_index)
25   list(FIND "${list_id}" "${item_check}" _index)
26   if("${_index}" MATCHES "-1")
27     message(FATAL_ERROR "'${list_id}' doesn't contain '${item_check}'")
28   endif()
29   math(EXPR _index "${_index} + 1")
30   list(INSERT ${list_id} "${_index}" ${item_add})
31   unset(_index)
32 endmacro()
33
34 macro(list_insert_before
35   list_id item_check item_add
36   )
37   set(_index)
38   list(FIND "${list_id}" "${item_check}" _index)
39   if("${_index}" MATCHES "-1")
40     message(FATAL_ERROR "'${list_id}' doesn't contain '${item_check}'")
41   endif()
42   list(INSERT ${list_id} "${_index}" ${item_add})
43   unset(_index)
44 endmacro()
45
46 function(list_assert_duplicates
47   list_id
48   )
49
50   # message(STATUS "list data: ${list_id}")
51
52   list(LENGTH list_id _len_before)
53   list(REMOVE_DUPLICATES list_id)
54   list(LENGTH list_id _len_after)
55   # message(STATUS "list size ${_len_before} -> ${_len_after}")
56   if(NOT _len_before EQUAL _len_after)
57     message(FATAL_ERROR "duplicate found in list which should not contain duplicates: ${list_id}")
58   endif()
59   unset(_len_before)
60   unset(_len_after)
61 endfunction()
62
63 # Adds a native path separator to the end of the path:
64 #
65 # - 'example' -> 'example/'
66 # - '/example///' -> '/example/'
67 #
68 macro(path_ensure_trailing_slash
69   path_new path_input
70   )
71   file(TO_NATIVE_PATH "/" _path_sep)
72   string(REGEX REPLACE "[${_path_sep}]+$" "" ${path_new} ${path_input})
73   set(${path_new} "${${path_new}}${_path_sep}")
74   unset(_path_sep)
75 endmacro()
76
77 # foo_bar.spam --> foo_barMySuffix.spam
78 macro(file_suffix
79   file_name_new file_name file_suffix
80   )
81
82   get_filename_component(_file_name_PATH ${file_name} PATH)
83   get_filename_component(_file_name_NAME_WE ${file_name} NAME_WE)
84   get_filename_component(_file_name_EXT ${file_name} EXT)
85   set(${file_name_new} "${_file_name_PATH}/${_file_name_NAME_WE}${file_suffix}${_file_name_EXT}")
86
87   unset(_file_name_PATH)
88   unset(_file_name_NAME_WE)
89   unset(_file_name_EXT)
90 endmacro()
91
92 # useful for adding debug suffix to library lists:
93 # /somepath/foo.lib --> /somepath/foo_d.lib
94 macro(file_list_suffix
95   fp_list_new fp_list fn_suffix
96   )
97
98   # incase of empty list
99   set(_fp)
100   set(_fp_suffixed)
101
102   set(fp_list_new)
103
104   foreach(_fp ${fp_list})
105     file_suffix(_fp_suffixed "${_fp}" "${fn_suffix}")
106     list(APPEND "${fp_list_new}" "${_fp_suffixed}")
107   endforeach()
108
109   unset(_fp)
110   unset(_fp_suffixed)
111
112 endmacro()
113
114 if(UNIX AND NOT APPLE)
115   macro(find_package_static)
116     set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES})
117     set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
118     find_package(${ARGV})
119     set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back})
120     unset(_cmake_find_library_suffixes_back)
121   endmacro()
122
123   macro(find_library_static)
124     set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES})
125     set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
126     find_library(${ARGV})
127     set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back})
128     unset(_cmake_find_library_suffixes_back)
129   endmacro()
130 endif()
131
132 function(target_link_libraries_optimized
133   TARGET
134   LIBS
135   )
136
137   foreach(_LIB ${LIBS})
138     target_link_libraries(${TARGET} INTERFACE optimized "${_LIB}")
139   endforeach()
140 endfunction()
141
142 function(target_link_libraries_debug
143   TARGET
144   LIBS
145   )
146
147   foreach(_LIB ${LIBS})
148     target_link_libraries(${TARGET} INTERFACE debug "${_LIB}")
149   endforeach()
150 endfunction()
151
152 # Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
153 # use it instead of include_directories()
154 function(blender_include_dirs
155   includes
156   )
157
158   set(_ALL_INCS "")
159   foreach(_INC ${ARGV})
160     get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
161     list(APPEND _ALL_INCS ${_ABS_INC})
162     # for checking for invalid includes, disable for regular use
163     # if(NOT EXISTS "${_ABS_INC}/")
164     #   message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
165     # endif()
166   endforeach()
167   include_directories(${_ALL_INCS})
168 endfunction()
169
170 function(blender_include_dirs_sys
171   includes
172   )
173
174   set(_ALL_INCS "")
175   foreach(_INC ${ARGV})
176     get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
177     list(APPEND _ALL_INCS ${_ABS_INC})
178     # if(NOT EXISTS "${_ABS_INC}/")
179     #   message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
180     # endif()
181   endforeach()
182   include_directories(SYSTEM ${_ALL_INCS})
183 endfunction()
184
185 # Set include paths for header files included with "*.h" syntax.
186 # This enables auto-complete suggestions for user header files on Xcode.
187 # Build process is not affected since the include paths are the same
188 # as in HEADER_SEARCH_PATHS.
189 function(blender_user_header_search_paths
190   name
191   includes
192   )
193
194   if(XCODE)
195     set(_ALL_INCS "")
196     foreach(_INC ${includes})
197       get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
198       # _ALL_INCS is a space-separated string of file paths in quotes.
199       string(APPEND _ALL_INCS " \"${_ABS_INC}\"")
200     endforeach()
201     set_target_properties(${name} PROPERTIES XCODE_ATTRIBUTE_USER_HEADER_SEARCH_PATHS "${_ALL_INCS}")
202   endif()
203 endfunction()
204
205 function(blender_source_group
206   name
207   sources
208   )
209
210   # if enabled, use the sources directories as filters.
211   if(WINDOWS_USE_VISUAL_STUDIO_SOURCE_FOLDERS)
212     foreach(_SRC ${sources})
213       # remove ../'s
214       get_filename_component(_SRC_DIR ${_SRC} REALPATH)
215       get_filename_component(_SRC_DIR ${_SRC_DIR} DIRECTORY)
216       string(FIND ${_SRC_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/" _pos)
217       if(NOT _pos EQUAL -1)
218         string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" GROUP_ID ${_SRC_DIR})
219         string(REPLACE "/" "\\" GROUP_ID ${GROUP_ID})
220         source_group("${GROUP_ID}" FILES ${_SRC})
221       endif()
222       unset(_pos)
223     endforeach()
224   else()
225     # Group by location on disk
226     source_group("Source Files" FILES CMakeLists.txt)
227     foreach(_SRC ${sources})
228       get_filename_component(_SRC_EXT ${_SRC} EXT)
229       if((${_SRC_EXT} MATCHES ".h") OR
230          (${_SRC_EXT} MATCHES ".hpp") OR
231          (${_SRC_EXT} MATCHES ".hh"))
232
233         set(GROUP_ID "Header Files")
234       elseif(${_SRC_EXT} MATCHES ".glsl$")
235         set(GROUP_ID "Shaders")
236       else()
237         set(GROUP_ID "Source Files")
238       endif()
239       source_group("${GROUP_ID}" FILES ${_SRC})
240     endforeach()
241   endif()
242
243   # if enabled, set the FOLDER property for visual studio projects
244   if(WINDOWS_USE_VISUAL_STUDIO_PROJECT_FOLDERS)
245     get_filename_component(FolderDir ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
246     string(REPLACE ${CMAKE_SOURCE_DIR} "" FolderDir ${FolderDir})
247     set_target_properties(${name} PROPERTIES FOLDER ${FolderDir})
248   endif()
249 endfunction()
250
251
252 # Support per-target CMake flags
253 # Read from: CMAKE_C_FLAGS_**** (made upper case) when set.
254 #
255 # 'name' should always match the target name,
256 # use this macro before add_library or add_executable.
257 #
258 # Optionally takes an arg passed to set(), eg PARENT_SCOPE.
259 macro(add_cc_flags_custom_test
260   name
261   )
262
263   string(TOUPPER ${name} _name_upper)
264   if(DEFINED CMAKE_C_FLAGS_${_name_upper})
265     message(STATUS "Using custom CFLAGS: CMAKE_C_FLAGS_${_name_upper} in \"${CMAKE_CURRENT_SOURCE_DIR}\"")
266     string(APPEND CMAKE_C_FLAGS " ${CMAKE_C_FLAGS_${_name_upper}}" ${ARGV1})
267   endif()
268   if(DEFINED CMAKE_CXX_FLAGS_${_name_upper})
269     message(STATUS "Using custom CXXFLAGS: CMAKE_CXX_FLAGS_${_name_upper} in \"${CMAKE_CURRENT_SOURCE_DIR}\"")
270     string(APPEND CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS_${_name_upper}}" ${ARGV1})
271   endif()
272   unset(_name_upper)
273
274 endmacro()
275
276
277 # only MSVC uses SOURCE_GROUP
278 function(blender_add_lib__impl
279   name
280   sources
281   includes
282   includes_sys
283   library_deps
284   )
285
286   # message(STATUS "Configuring library ${name}")
287
288   # include_directories(${includes})
289   # include_directories(SYSTEM ${includes_sys})
290   blender_include_dirs("${includes}")
291   blender_include_dirs_sys("${includes_sys}")
292
293   add_library(${name} ${sources})
294
295   # On Windows certain libraries have two sets of binaries: one for debug builds and one for
296   # release builds. The root of this requirement goes into ABI, I believe, but that's outside
297   # of a scope of this comment.
298   #
299   # CMake have a native way of dealing with this, which is specifying what build type the
300   # libraries are provided for:
301   #
302   #   target_link_libraries(tagret optimized|debug|general <libraries>)
303   #
304   # The build type is to be provided as a separate argument to the function.
305   #
306   # CMake's variables for libraries will contain build type in such cases. For example:
307   #
308   #   set(FOO_LIBRARIES optimized libfoo.lib debug libfoo_d.lib)
309   #
310   # Complications starts with a single argument for library_deps: all the elements are being
311   # put to a list: "${FOO_LIBRARIES}" will become "optimized;libfoo.lib;debug;libfoo_d.lib".
312   # This makes it impossible to pass it as-is to target_link_libraries sine it will treat
313   # this argument as a list of libraries to be linked against, causing missing libraries
314   # for optimized.lib.
315   #
316   # What this code does it traverses library_deps and extracts information about whether
317   # library is to provided as general, debug or optimized. This is a little state machine which
318   # keeps track of which build type library is to provided for:
319   #
320   # - If "debug" or "optimized" word is found, the next element in the list is expected to be
321   #   a library which will be passed to target_link_libraries() under corresponding build type.
322   #
323   # - If there is no "debug" or "optimized" used library is specified for all build types.
324   #
325   # NOTE: If separated libraries for debug and release are needed every library is the list are
326   # to be prefixed explicitly.
327   #
328   #  Use: "optimized libfoo optimized libbar debug libfoo_d debug libbar_d"
329   #  NOT: "optimized libfoo libbar debug libfoo_d libbar_d"
330   if(NOT "${library_deps}" STREQUAL "")
331     set(next_library_mode "")
332     foreach(library ${library_deps})
333       string(TOLOWER "${library}" library_lower)
334       if(("${library_lower}" STREQUAL "optimized") OR
335          ("${library_lower}" STREQUAL "debug"))
336         set(next_library_mode "${library_lower}")
337       else()
338         if("${next_library_mode}" STREQUAL "optimized")
339           target_link_libraries(${name} INTERFACE optimized ${library})
340         elseif("${next_library_mode}" STREQUAL "debug")
341           target_link_libraries(${name} INTERFACE debug ${library})
342         else()
343           target_link_libraries(${name} INTERFACE ${library})
344         endif()
345         set(next_library_mode "")
346       endif()
347     endforeach()
348   endif()
349
350   # works fine without having the includes
351   # listed is helpful for IDE's (QtCreator/MSVC)
352   blender_source_group("${name}" "${sources}")
353   blender_user_header_search_paths("${name}" "${includes}")
354
355   list_assert_duplicates("${sources}")
356   list_assert_duplicates("${includes}")
357   # Not for system includes because they can resolve to the same path
358   # list_assert_duplicates("${includes_sys}")
359
360 endfunction()
361
362
363 function(blender_add_lib_nolist
364   name
365   sources
366   includes
367   includes_sys
368   library_deps
369   )
370
371   add_cc_flags_custom_test(${name} PARENT_SCOPE)
372
373   blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
374 endfunction()
375
376 function(blender_add_lib
377   name
378   sources
379   includes
380   includes_sys
381   library_deps
382   )
383
384   add_cc_flags_custom_test(${name} PARENT_SCOPE)
385
386   blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
387
388   set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
389 endfunction()
390
391 # Add tests for a Blender library, to be called in tandem with blender_add_lib().
392 # The tests will be part of the blender_test executable (see tests/gtests/runner).
393 function(blender_add_test_lib
394   name
395   sources
396   includes
397   includes_sys
398   library_deps
399   )
400
401   add_cc_flags_custom_test(${name} PARENT_SCOPE)
402
403   # Otherwise external projects will produce warnings that we cannot fix.
404   remove_strict_flags()
405
406   # This duplicates logic that's also in GTestTesting.cmake, macro BLENDER_SRC_GTEST_EX.
407   # TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
408   LIST(APPEND includes
409     ${CMAKE_SOURCE_DIR}/tests/gtests
410   )
411   LIST(APPEND includes_sys
412     ${GLOG_INCLUDE_DIRS}
413     ${GFLAGS_INCLUDE_DIRS}
414     ${CMAKE_SOURCE_DIR}/extern/gtest/include
415     ${CMAKE_SOURCE_DIR}/extern/gmock/include
416   )
417   add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
418   add_definitions(${GFLAGS_DEFINES})
419   add_definitions(${GLOG_DEFINES})
420
421   blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
422
423   set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
424 endfunction()
425
426
427 # Add tests for a Blender library, to be called in tandem with blender_add_lib().
428 # Test will be compiled into a ${name}_test executable.
429 #
430 # To be used for smaller isolated libraries, that do not have many dependencies.
431 # For libraries that do drag in many other Blender libraries and would create a
432 # very large executable, blender_add_test_lib() should be used instead.
433 function(blender_add_test_executable
434   name
435   sources
436   includes
437   includes_sys
438   library_deps
439   )
440
441   add_cc_flags_custom_test(${name} PARENT_SCOPE)
442
443   ## Otherwise external projects will produce warnings that we cannot fix.
444   remove_strict_flags()
445
446   include_directories(${includes})
447   include_directories(${includes_sys})
448   setup_libdirs()
449
450   BLENDER_SRC_GTEST_EX(
451     NAME ${name}
452     SRC "${sources}"
453     EXTRA_LIBS "${library_deps}"
454     SKIP_ADD_TEST
455   )
456
457   include(GTest)
458   set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
459     ${CMAKE_SOURCE_DIR}/build_files/cmake/Modules/GTestAddTests.cmake
460   )
461
462   gtest_discover_tests(${name}_test
463     DISCOVERY_MODE PRE_TEST
464     WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
465   )
466 endfunction()
467
468 # Ninja only: assign 'heavy pool' to some targets that are especially RAM-consuming to build.
469 function(setup_heavy_lib_pool)
470   if(WITH_NINJA_POOL_JOBS AND NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
471     if(WITH_CYCLES)
472       list(APPEND _HEAVY_LIBS "cycles_device" "cycles_kernel")
473     endif()
474     if(WITH_LIBMV)
475       list(APPEND _HEAVY_LIBS "extern_ceres" "bf_intern_libmv")
476     endif()
477     if(WITH_OPENVDB)
478       list(APPEND _HEAVY_LIBS "bf_intern_openvdb")
479     endif()
480
481     foreach(TARGET ${_HEAVY_LIBS})
482       if(TARGET ${TARGET})
483         set_property(TARGET ${TARGET} PROPERTY JOB_POOL_COMPILE compile_heavy_job_pool)
484       endif()
485     endforeach()
486   endif()
487 endfunction()
488
489 function(SETUP_LIBDIRS)
490
491   # NOTE: For all new libraries, use absolute library paths.
492   # This should eventually be phased out.
493   # APPLE plaform uses full paths for linking libraries, and avoids link_directories.
494   if(NOT MSVC AND NOT APPLE)
495     link_directories(${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${FREETYPE_LIBPATH})
496
497     if(WITH_PYTHON)  #  AND NOT WITH_PYTHON_MODULE  # WIN32 needs
498       link_directories(${PYTHON_LIBPATH})
499     endif()
500     if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
501       link_directories(${SDL_LIBPATH})
502     endif()
503     if(WITH_CODEC_FFMPEG)
504       link_directories(${FFMPEG_LIBPATH})
505     endif()
506     if(WITH_IMAGE_OPENEXR)
507       link_directories(${OPENEXR_LIBPATH})
508     endif()
509     if(WITH_IMAGE_TIFF)
510       link_directories(${TIFF_LIBPATH})
511     endif()
512     if(WITH_BOOST)
513       link_directories(${BOOST_LIBPATH})
514     endif()
515     if(WITH_OPENIMAGEIO)
516       link_directories(${OPENIMAGEIO_LIBPATH})
517     endif()
518     if(WITH_OPENIMAGEDENOISE)
519       link_directories(${OPENIMAGEDENOISE_LIBPATH})
520     endif()
521     if(WITH_OPENCOLORIO)
522       link_directories(${OPENCOLORIO_LIBPATH})
523     endif()
524     if(WITH_OPENVDB)
525       link_directories(${OPENVDB_LIBPATH})
526     endif()
527     if(WITH_OPENAL)
528       link_directories(${OPENAL_LIBPATH})
529     endif()
530     if(WITH_JACK AND NOT WITH_JACK_DYNLOAD)
531       link_directories(${JACK_LIBPATH})
532     endif()
533     if(WITH_CODEC_SNDFILE)
534       link_directories(${LIBSNDFILE_LIBPATH})
535     endif()
536     if(WITH_FFTW3)
537       link_directories(${FFTW3_LIBPATH})
538     endif()
539     if(WITH_OPENCOLLADA)
540       link_directories(${OPENCOLLADA_LIBPATH})
541       # # Never set
542       # link_directories(${PCRE_LIBPATH})
543       # link_directories(${EXPAT_LIBPATH})
544     endif()
545     if(WITH_LLVM)
546       link_directories(${LLVM_LIBPATH})
547     endif()
548
549     if(WITH_ALEMBIC)
550       link_directories(${ALEMBIC_LIBPATH})
551     endif()
552
553     if(WITH_GMP)
554       link_directories(${GMP_LIBPATH})
555     endif()
556
557     if(WITH_GHOST_WAYLAND)
558       link_directories(
559         ${wayland-client_LIBRARY_DIRS}
560         ${wayland-egl_LIBRARY_DIRS}
561         ${xkbcommon_LIBRARY_DIRS}
562         ${wayland-cursor_LIBRARY_DIRS})
563     endif()
564
565     if(WIN32 AND NOT UNIX)
566       link_directories(${PTHREADS_LIBPATH})
567     endif()
568   endif()
569 endfunction()
570
571 # Platform specific linker flags for targets.
572 function(setup_platform_linker_flags
573   target)
574   set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS}")
575   set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " ${PLATFORM_LINKFLAGS_RELEASE}")
576   set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " ${PLATFORM_LINKFLAGS_DEBUG}")
577 endfunction()
578
579 # Platform specific libraries for targets.
580 function(setup_platform_linker_libs
581   target
582   )
583   # jemalloc must be early in the list, to be before pthread (see T57998)
584   if(WITH_MEM_JEMALLOC)
585     target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
586   endif()
587
588   if(WIN32 AND NOT UNIX)
589     target_link_libraries(${target} ${PTHREADS_LIBRARIES})
590   endif()
591
592   # target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
593   target_link_libraries(${target} ${PLATFORM_LINKLIBS})
594 endfunction()
595
596 macro(TEST_SSE_SUPPORT
597   _sse_flags
598   _sse2_flags)
599
600   include(CheckCSourceRuns)
601
602   # message(STATUS "Detecting SSE support")
603   if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
604     set(${_sse_flags} "-msse")
605     set(${_sse2_flags} "-msse2")
606   elseif(MSVC)
607     # x86_64 has this auto enabled
608     if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
609       set(${_sse_flags} "")
610       set(${_sse2_flags} "")
611     else()
612       set(${_sse_flags} "/arch:SSE")
613       set(${_sse2_flags} "/arch:SSE2")
614     endif()
615   elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
616     set(${_sse_flags} "")  # icc defaults to -msse
617     set(${_sse2_flags} "")  # icc defaults to -msse2
618   else()
619     message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known")
620     set(${_sse_flags})
621     set(${_sse2_flags})
622   endif()
623
624   set(CMAKE_REQUIRED_FLAGS "${${_sse_flags}} ${${_sse2_flags}}")
625
626   if(NOT DEFINED SUPPORT_SSE_BUILD)
627     # result cached
628     check_c_source_runs("
629       #include <xmmintrin.h>
630       int main(void) { __m128 v = _mm_setzero_ps(); return 0; }"
631     SUPPORT_SSE_BUILD)
632
633     if(SUPPORT_SSE_BUILD)
634       message(STATUS "SSE Support: detected.")
635     else()
636       message(STATUS "SSE Support: missing.")
637     endif()
638   endif()
639
640   if(NOT DEFINED SUPPORT_SSE2_BUILD)
641     # result cached
642     check_c_source_runs("
643       #include <emmintrin.h>
644       int main(void) { __m128d v = _mm_setzero_pd(); return 0; }"
645     SUPPORT_SSE2_BUILD)
646
647     if(SUPPORT_SSE2_BUILD)
648       message(STATUS "SSE2 Support: detected.")
649     else()
650       message(STATUS "SSE2 Support: missing.")
651     endif()
652   endif()
653
654   unset(CMAKE_REQUIRED_FLAGS)
655 endmacro()
656
657 # Only print message if running CMake first time
658 macro(message_first_run)
659   if(FIRST_RUN)
660     message(${ARGV})
661   endif()
662 endmacro()
663
664 # when we have warnings as errors applied globally this
665 # needs to be removed for some external libs which we dont maintain.
666
667 # utility macro
668 macro(remove_cc_flag
669   _flag)
670
671   foreach(flag ${ARGV})
672     string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
673     string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
674     string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
675     string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
676     string(REGEX REPLACE ${flag} "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
677
678     string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
679     string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
680     string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
681     string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
682     string(REGEX REPLACE ${flag} "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
683   endforeach()
684   unset(flag)
685
686 endmacro()
687
688 macro(add_c_flag
689   flag)
690
691   string(APPEND CMAKE_C_FLAGS " ${flag}")
692   string(APPEND CMAKE_CXX_FLAGS " ${flag}")
693 endmacro()
694
695 macro(add_cxx_flag
696   flag)
697
698   string(APPEND CMAKE_CXX_FLAGS " ${flag}")
699 endmacro()
700
701 macro(remove_strict_flags)
702
703   if(CMAKE_COMPILER_IS_GNUCC)
704     remove_cc_flag(
705       "-Wstrict-prototypes"
706       "-Wmissing-prototypes"
707       "-Wmissing-declarations"
708       "-Wmissing-format-attribute"
709       "-Wunused-local-typedefs"
710       "-Wunused-macros"
711       "-Wunused-parameter"
712       "-Wwrite-strings"
713       "-Wredundant-decls"
714       "-Wundef"
715       "-Wshadow"
716       "-Wdouble-promotion"
717       "-Wold-style-definition"
718       "-Werror=[^ ]+"
719       "-Werror"
720     )
721
722     # negate flags implied by '-Wall'
723     add_c_flag("${C_REMOVE_STRICT_FLAGS}")
724     add_cxx_flag("${CXX_REMOVE_STRICT_FLAGS}")
725   endif()
726
727   if(CMAKE_C_COMPILER_ID MATCHES "Clang")
728     remove_cc_flag(
729       "-Wunused-parameter"
730       "-Wunused-variable"
731       "-Werror=[^ ]+"
732       "-Werror"
733     )
734
735     # negate flags implied by '-Wall'
736     add_c_flag("${C_REMOVE_STRICT_FLAGS}")
737     add_cxx_flag("${CXX_REMOVE_STRICT_FLAGS}")
738   endif()
739
740   if(MSVC)
741     remove_cc_flag(/w34189) # Restore warn C4189 (unused variable) back to w4
742   endif()
743
744 endmacro()
745
746 macro(remove_extra_strict_flags)
747   if(CMAKE_COMPILER_IS_GNUCC)
748     remove_cc_flag(
749       "-Wunused-parameter"
750     )
751   endif()
752
753   if(CMAKE_C_COMPILER_ID MATCHES "Clang")
754     remove_cc_flag(
755       "-Wunused-parameter"
756     )
757   endif()
758
759   if(MSVC)
760     # TODO
761   endif()
762 endmacro()
763
764 # note, we can only append flags on a single file so we need to negate the options.
765 # at the moment we cant shut up ffmpeg deprecations, so use this, but will
766 # probably add more removals here.
767 macro(remove_strict_c_flags_file
768   filenames)
769   foreach(_SOURCE ${ARGV})
770     if(CMAKE_COMPILER_IS_GNUCC OR
771        (CMAKE_C_COMPILER_ID MATCHES "Clang"))
772       set_source_files_properties(${_SOURCE}
773         PROPERTIES
774           COMPILE_FLAGS "${C_REMOVE_STRICT_FLAGS}"
775       )
776     endif()
777     if(MSVC)
778       # TODO
779     endif()
780   endforeach()
781   unset(_SOURCE)
782 endmacro()
783
784 macro(remove_strict_cxx_flags_file
785   filenames)
786   remove_strict_c_flags_file(${filenames} ${ARHV})
787   foreach(_SOURCE ${ARGV})
788     if(CMAKE_COMPILER_IS_GNUCC OR
789        (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
790       set_source_files_properties(${_SOURCE}
791         PROPERTIES
792           COMPILE_FLAGS "${CXX_REMOVE_STRICT_FLAGS}"
793       )
794     endif()
795     if(MSVC)
796       # TODO
797     endif()
798   endforeach()
799   unset(_SOURCE)
800 endmacro()
801
802 # External libs may need 'signed char' to be default.
803 macro(remove_cc_flag_unsigned_char)
804   if(CMAKE_COMPILER_IS_GNUCC OR
805      (CMAKE_C_COMPILER_ID MATCHES "Clang") OR
806      (CMAKE_C_COMPILER_ID MATCHES "Intel"))
807     remove_cc_flag("-funsigned-char")
808   elseif(MSVC)
809     remove_cc_flag("/J")
810   else()
811     message(WARNING
812       "Compiler '${CMAKE_C_COMPILER_ID}' failed to disable 'unsigned char' flag."
813       "Build files need updating."
814     )
815   endif()
816 endmacro()
817
818 function(ADD_CHECK_C_COMPILER_FLAG
819   _CFLAGS
820   _CACHE_VAR
821   _FLAG
822   )
823
824   include(CheckCCompilerFlag)
825
826   CHECK_C_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
827   if(${_CACHE_VAR})
828     # message(STATUS "Using CFLAG: ${_FLAG}")
829     set(${_CFLAGS} "${${_CFLAGS}} ${_FLAG}" PARENT_SCOPE)
830   else()
831     message(STATUS "Unsupported CFLAG: ${_FLAG}")
832   endif()
833 endfunction()
834
835 function(ADD_CHECK_CXX_COMPILER_FLAG
836   _CXXFLAGS
837   _CACHE_VAR
838   _FLAG
839   )
840
841   include(CheckCXXCompilerFlag)
842
843   CHECK_CXX_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
844   if(${_CACHE_VAR})
845     # message(STATUS "Using CXXFLAG: ${_FLAG}")
846     set(${_CXXFLAGS} "${${_CXXFLAGS}} ${_FLAG}" PARENT_SCOPE)
847   else()
848     message(STATUS "Unsupported CXXFLAG: ${_FLAG}")
849   endif()
850 endfunction()
851
852 function(get_blender_version)
853   # extracts header vars and defines them in the parent scope:
854   #
855   # - BLENDER_VERSION (major.minor)
856   # - BLENDER_VERSION_MAJOR
857   # - BLENDER_VERSION_MINOR
858   # - BLENDER_VERSION_PATCH
859   # - BLENDER_VERSION_CYCLE (alpha, beta, rc, release)
860
861   # So cmake depends on BKE_blender.h, beware of inf-loops!
862   CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h
863                  ${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender_version.h.done)
864
865   file(STRINGS ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h _contents REGEX "^#define[ \t]+BLENDER_.*$")
866
867   string(REGEX REPLACE ".*#define[ \t]+BLENDER_VERSION[ \t]+([0-9]+).*" "\\1" _out_version "${_contents}")
868   string(REGEX REPLACE ".*#define[ \t]+BLENDER_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" _out_version_patch "${_contents}")
869   string(REGEX REPLACE ".*#define[ \t]+BLENDER_VERSION_CYCLE[ \t]+([a-z]+).*" "\\1" _out_version_cycle "${_contents}")
870
871   if(NOT ${_out_version} MATCHES "[0-9]+")
872     message(FATAL_ERROR "Version parsing failed for BLENDER_VERSION")
873   endif()
874
875   if(NOT ${_out_version_patch} MATCHES "[0-9]+")
876     message(FATAL_ERROR "Version parsing failed for BLENDER_VERSION_PATCH")
877   endif()
878
879   if(NOT ${_out_version_cycle} MATCHES "[a-z]+")
880     message(FATAL_ERROR "Version parsing failed for BLENDER_VERSION_CYCLE")
881   endif()
882
883   math(EXPR _out_version_major "${_out_version} / 100")
884   math(EXPR _out_version_minor "${_out_version} % 100")
885
886   # output vars
887   set(BLENDER_VERSION "${_out_version_major}.${_out_version_minor}" PARENT_SCOPE)
888   set(BLENDER_VERSION_MAJOR "${_out_version_major}" PARENT_SCOPE)
889   set(BLENDER_VERSION_MINOR "${_out_version_minor}" PARENT_SCOPE)
890   set(BLENDER_VERSION_PATCH "${_out_version_patch}" PARENT_SCOPE)
891   set(BLENDER_VERSION_CYCLE "${_out_version_cycle}" PARENT_SCOPE)
892
893 endfunction()
894
895
896 # hacks to override initial project settings
897 # these macros must be called directly before/after project(Blender)
898 macro(blender_project_hack_pre)
899   # ------------------
900   # GCC -O3 HACK START
901   # needed because O3 can cause problems but
902   # allow the builder to set O3 manually after.
903   if(DEFINED CMAKE_C_FLAGS_RELEASE)
904     set(_reset_standard_cflags_rel OFF)
905   else()
906     set(_reset_standard_cflags_rel ON)
907   endif()
908   if(DEFINED CMAKE_CXX_FLAGS_RELEASE)
909     set(_reset_standard_cxxflags_rel OFF)
910   else()
911     set(_reset_standard_cxxflags_rel ON)
912   endif()
913 endmacro()
914
915
916 macro(blender_project_hack_post)
917   # ----------------
918   # GCC -O3 HACK END
919   if(_reset_standard_cflags_rel)
920     string(REGEX REPLACE "-O3" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
921     set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "" FORCE)
922     mark_as_advanced(CMAKE_C_FLAGS_RELEASE)
923   endif()
924
925   if(_reset_standard_cxxflags_rel)
926     string(REGEX REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
927     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "" FORCE)
928     mark_as_advanced(CMAKE_CXX_FLAGS_RELEASE)
929   endif()
930
931   unset(_reset_standard_cflags_rel)
932   unset(_reset_standard_cxxflags_rel)
933
934   # ------------------------------------------------------------------
935   # workaround for omission in cmake 2.8.4's GNU.cmake, fixed in 2.8.5
936   if(CMAKE_COMPILER_IS_GNUCC)
937     if(NOT DARWIN)
938       set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
939     endif()
940   endif()
941
942 endmacro()
943
944 # pair of macros to allow libraries to be specify files to install, but to
945 # only install them at the end so the directories don't get cleared with
946 # the files in them. used by cycles to install addon.
947 function(delayed_install
948   base
949   files
950   destination)
951
952   foreach(f ${files})
953     if(IS_ABSOLUTE ${f})
954       set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${f})
955     else()
956       set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f})
957     endif()
958     set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
959   endforeach()
960   unset(f)
961 endfunction()
962
963 # note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir
964 # does not get expanded in calling but is preserved
965 function(delayed_do_install
966   targetdir)
967
968   get_property(files GLOBAL PROPERTY DELAYED_INSTALL_FILES)
969   get_property(destinations GLOBAL PROPERTY DELAYED_INSTALL_DESTINATIONS)
970
971   if(files)
972     list(LENGTH files n)
973     math(EXPR n "${n}-1")
974
975     foreach(i RANGE ${n})
976       list(GET files ${i} f)
977       list(GET destinations ${i} d)
978       if(NOT IS_ABSOLUTE ${d})
979         install(FILES ${f} DESTINATION ${targetdir}/${d})
980       else()
981         install(FILES ${f} DESTINATION ${d})
982       endif()
983     endforeach()
984   endif()
985 endfunction()
986
987
988 function(data_to_c
989   file_from file_to
990   list_to_add
991   )
992
993   list(APPEND ${list_to_add} ${file_to})
994   set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
995
996   get_filename_component(_file_to_path ${file_to} PATH)
997
998   add_custom_command(
999     OUTPUT ${file_to}
1000     COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
1001     COMMAND "$<TARGET_FILE:datatoc>" ${file_from} ${file_to}
1002     DEPENDS ${file_from} datatoc)
1003
1004   set_source_files_properties(${file_to} PROPERTIES GENERATED TRUE)
1005 endfunction()
1006
1007
1008 # same as above but generates the var name and output automatic.
1009 function(data_to_c_simple
1010   file_from
1011   list_to_add
1012   )
1013
1014   # remove ../'s
1015   get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from}   REALPATH)
1016   get_filename_component(_file_to   ${CMAKE_CURRENT_BINARY_DIR}/${file_from}.c REALPATH)
1017
1018   list(APPEND ${list_to_add} ${_file_to})
1019   source_group(Generated FILES ${_file_to})
1020   list(APPEND ${list_to_add} ${file_from})
1021   set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
1022
1023   get_filename_component(_file_to_path ${_file_to} PATH)
1024
1025   add_custom_command(
1026     OUTPUT  ${_file_to}
1027     COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
1028     COMMAND "$<TARGET_FILE:datatoc>" ${_file_from} ${_file_to}
1029     DEPENDS ${_file_from} datatoc)
1030
1031   set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
1032 endfunction()
1033
1034 # Function for converting pixmap directory to a '.png' and then a '.c' file.
1035 function(data_to_c_simple_icons
1036   path_from icon_prefix icon_names
1037   list_to_add
1038   )
1039
1040   # Conversion steps
1041   #  path_from  ->  _file_from  ->  _file_to
1042   #  foo/*.dat  ->  foo.png     ->  foo.png.c
1043
1044   get_filename_component(_path_from_abs ${path_from} ABSOLUTE)
1045   # remove ../'s
1046   get_filename_component(_file_from ${CMAKE_CURRENT_BINARY_DIR}/${path_from}.png   REALPATH)
1047   get_filename_component(_file_to   ${CMAKE_CURRENT_BINARY_DIR}/${path_from}.png.c REALPATH)
1048
1049   list(APPEND ${list_to_add} ${_file_to})
1050   set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
1051
1052   get_filename_component(_file_to_path ${_file_to} PATH)
1053
1054   # Construct a list of absolute paths from input
1055   set(_icon_files)
1056   foreach(_var ${icon_names})
1057     list(APPEND _icon_files "${_path_from_abs}/${icon_prefix}${_var}.dat")
1058   endforeach()
1059
1060   add_custom_command(
1061     OUTPUT  ${_file_from} ${_file_to}
1062     COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
1063     # COMMAND python3 ${CMAKE_SOURCE_DIR}/source/blender/datatoc/datatoc_icon.py ${_path_from_abs} ${_file_from}
1064     COMMAND "$<TARGET_FILE:datatoc_icon>" ${_path_from_abs} ${_file_from}
1065     COMMAND "$<TARGET_FILE:datatoc>" ${_file_from} ${_file_to}
1066     DEPENDS
1067       ${_icon_files}
1068       datatoc_icon
1069       datatoc
1070       # could be an arg but for now we only create icons depending on UI_icons.h
1071       ${CMAKE_SOURCE_DIR}/source/blender/editors/include/UI_icons.h
1072     )
1073
1074   set_source_files_properties(${_file_from} ${_file_to} PROPERTIES GENERATED TRUE)
1075 endfunction()
1076
1077 # XXX Not used for now...
1078 function(svg_to_png
1079   file_from
1080   file_to
1081   dpi
1082   list_to_add
1083   )
1084
1085   # remove ../'s
1086   get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH)
1087   get_filename_component(_file_to   ${CMAKE_CURRENT_SOURCE_DIR}/${file_to}   REALPATH)
1088
1089   list(APPEND ${list_to_add} ${_file_to})
1090   set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
1091
1092   find_program(INKSCAPE_EXE inkscape)
1093   mark_as_advanced(INKSCAPE_EXE)
1094
1095   if(INKSCAPE_EXE)
1096     if(APPLE)
1097       # in OS X app bundle, the binary is a shim that doesn't take any
1098       # command line arguments, replace it with the actual binary
1099       string(REPLACE "MacOS/Inkscape" "Resources/bin/inkscape" INKSCAPE_REAL_EXE ${INKSCAPE_EXE})
1100       if(EXISTS "${INKSCAPE_REAL_EXE}")
1101         set(INKSCAPE_EXE ${INKSCAPE_REAL_EXE})
1102       endif()
1103     endif()
1104
1105     add_custom_command(
1106       OUTPUT  ${_file_to}
1107       COMMAND ${INKSCAPE_EXE} ${_file_from} --export-dpi=${dpi}  --without-gui --export-png=${_file_to}
1108       DEPENDS ${_file_from} ${INKSCAPE_EXE}
1109     )
1110   else()
1111     message(WARNING "Inkscape not found, could not re-generate ${_file_to} from ${_file_from}!")
1112   endif()
1113 endfunction()
1114
1115 function(msgfmt_simple
1116   file_from
1117   list_to_add
1118   )
1119
1120   # remove ../'s
1121   get_filename_component(_file_from_we ${file_from} NAME_WE)
1122
1123   get_filename_component(_file_from ${file_from} REALPATH)
1124   get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${_file_from_we}.mo REALPATH)
1125
1126   list(APPEND ${list_to_add} ${_file_to})
1127   set(${list_to_add} ${${list_to_add}} PARENT_SCOPE)
1128
1129   get_filename_component(_file_to_path ${_file_to} PATH)
1130
1131   add_custom_command(
1132     OUTPUT  ${_file_to}
1133     COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
1134     COMMAND "$<TARGET_FILE:msgfmt>" ${_file_from} ${_file_to}
1135     DEPENDS msgfmt ${_file_from})
1136
1137   set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
1138 endfunction()
1139
1140 function(find_python_package
1141   package
1142   )
1143
1144   string(TOUPPER ${package} _upper_package)
1145
1146   # set but invalid
1147   if((NOT ${PYTHON_${_upper_package}_PATH} STREQUAL "") AND
1148      (NOT ${PYTHON_${_upper_package}_PATH} MATCHES NOTFOUND))
1149 #       if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}/${package}")
1150 #           message(WARNING "PYTHON_${_upper_package}_PATH is invalid, ${package} not found in '${PYTHON_${_upper_package}_PATH}' "
1151 #                           "WITH_PYTHON_INSTALL_${_upper_package} option will be ignored when installing python")
1152 #           set(WITH_PYTHON_INSTALL${_upper_package} OFF)
1153 #       endif()
1154   # not set, so initialize
1155   else()
1156     string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
1157     list(GET _PY_VER_SPLIT 0 _PY_VER_MAJOR)
1158
1159     # re-cache
1160     unset(PYTHON_${_upper_package}_PATH CACHE)
1161     find_path(PYTHON_${_upper_package}_PATH
1162       NAMES
1163         ${package}
1164       HINTS
1165         "${PYTHON_LIBPATH}/"
1166         "${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
1167         "${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
1168       PATH_SUFFIXES
1169         site-packages
1170         dist-packages
1171         vendor-packages
1172        NO_DEFAULT_PATH
1173     )
1174
1175     if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}")
1176       message(WARNING
1177         "Python package '${package}' path could not be found in:\n"
1178         "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/${package}', "
1179         "'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/site-packages/${package}', "
1180         "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/dist-packages/${package}', "
1181         "'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/dist-packages/${package}', "
1182         "'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/vendor-packages/${package}', "
1183         "'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/vendor-packages/${package}', "
1184         "\n"
1185         "The 'WITH_PYTHON_INSTALL_${_upper_package}' option will be ignored when installing Python.\n"
1186         "The build will be usable, only add-ons that depend on this package won't be functional."
1187       )
1188       set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
1189     else()
1190       message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
1191     endif()
1192   endif()
1193 endfunction()
1194
1195 # like Python's 'print(dir())'
1196 function(print_all_vars)
1197   get_cmake_property(_vars VARIABLES)
1198   foreach(_var ${_vars})
1199     message("${_var}=${${_var}}")
1200   endforeach()
1201 endfunction()
1202
1203 macro(openmp_delayload
1204   projectname
1205   )
1206     if(MSVC)
1207       if(WITH_OPENMP)
1208         if(MSVC_CLANG)
1209           set(OPENMP_DLL_NAME "libomp")
1210         elseif(MSVC_VERSION EQUAL 1800)
1211           set(OPENMP_DLL_NAME "vcomp120")
1212         else()
1213           set(OPENMP_DLL_NAME "vcomp140")
1214         endif()
1215         set_property(TARGET ${projectname} APPEND_STRING  PROPERTY LINK_FLAGS_RELEASE " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
1216         set_property(TARGET ${projectname} APPEND_STRING  PROPERTY LINK_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL_NAME}d.dll delayimp.lib")
1217         set_property(TARGET ${projectname} APPEND_STRING  PROPERTY LINK_FLAGS_RELWITHDEBINFO " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
1218         set_property(TARGET ${projectname} APPEND_STRING  PROPERTY LINK_FLAGS_MINSIZEREL " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib")
1219       endif()
1220     endif()
1221 endmacro()
1222
1223 macro(blender_precompile_headers target cpp header)
1224   if(MSVC)
1225     # get the name for the pch output file
1226     get_filename_component(pchbase ${cpp} NAME_WE)
1227     set(pchfinal "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${pchbase}.pch")
1228
1229     # mark the cpp as the one outputting the pch
1230     set_property(SOURCE ${cpp} APPEND PROPERTY OBJECT_OUTPUTS "${pchfinal}")
1231
1232     # get all sources for the target
1233     get_target_property(sources ${target} SOURCES)
1234
1235     # make all sources depend on the pch to enforce the build order
1236     foreach(src ${sources})
1237       set_property(SOURCE ${src} APPEND PROPERTY OBJECT_DEPENDS "${pchfinal}")
1238     endforeach()
1239
1240     target_sources(${target} PRIVATE ${cpp} ${header})
1241     set_target_properties(${target} PROPERTIES COMPILE_FLAGS "/Yu${header} /Fp${pchfinal} /FI${header}")
1242     set_source_files_properties(${cpp} PROPERTIES COMPILE_FLAGS "/Yc${header} /Fp${pchfinal}")
1243   endif()
1244 endmacro()
1245
1246 macro(set_and_warn_dependency
1247   _dependency _setting _val)
1248   # when $_dependency is disabled, forces $_setting = $_val
1249   if(NOT ${${_dependency}} AND ${${_setting}})
1250     message(STATUS "'${_dependency}' is disabled: forcing 'set(${_setting} ${_val})'")
1251     set(${_setting} ${_val})
1252   endif()
1253 endmacro()
1254
1255 macro(without_system_libs_begin)
1256   set(CMAKE_IGNORE_PATH "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES};${CMAKE_SYSTEM_INCLUDE_PATH};${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES};${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}")
1257   if(APPLE)
1258     # Avoid searching for headers in frameworks (like Mono), and libraries in LIBDIR.
1259     set(CMAKE_FIND_FRAMEWORK NEVER)
1260   endif()
1261 endmacro()
1262
1263 macro(without_system_libs_end)
1264   unset(CMAKE_IGNORE_PATH)
1265   if(APPLE)
1266     # FIRST is the default.
1267     set(CMAKE_FIND_FRAMEWORK FIRST)
1268   endif()
1269 endmacro()