include(CheckCCompilerFlag) FUNCTION(MAKE_CACHE_INTERNAL VARIABLE) SET(${VARIABLE} ${${VARIABLE}} CACHE INTERNAL "Internal cache variable") ENDFUNCTION(MAKE_CACHE_INTERNAL) FUNCTION(ADD_IMPORTED_LIB NAME INCLUDES LIBS) ADD_LIBRARY(${NAME} INTERFACE) target_link_libraries(${NAME} INTERFACE "${LIBS}") target_include_directories(${NAME} SYSTEM INTERFACE "${INCLUDES}") ENDFUNCTION(ADD_IMPORTED_LIB) MACRO(PKG_CONFIG_LIB_RESOLVE NAME OUTVAR) SET(${OUTVAR} "") foreach(lib ${${NAME}_LIBRARIES}) find_library(${lib}_LIBRARY NAMES ${lib} HINTS ${${NAME}_LIBDIR} ${${NAME}_LIBRARY_DIRS} ) if (NOT ${${lib}_LIBRARY} MATCHES ".*NOTFOUND.*") SET(${OUTVAR} ${${OUTVAR}} ${${lib}_LIBRARY}) endif (NOT ${${lib}_LIBRARY} MATCHES ".*NOTFOUND.*") endforeach(lib) ENDMACRO(PKG_CONFIG_LIB_RESOLVE) # Copy from http://cmake.3232098.n2.nabble.com/RFC-cmake-analog-to-AC-SEARCH-LIBS-td7585423.html INCLUDE (CheckFunctionExists) INCLUDE (CheckLibraryExists) MACRO (CMAKE_SEARCH_LIBS v_func v_lib func) CHECK_FUNCTION_EXISTS (${func} ${v_func}) IF (NOT ${v_func}) FOREACH (lib ${ARGN}) CHECK_LIBRARY_EXISTS (${lib} ${func} "" "HAVE_${func}_IN_${lib}") IF (${HAVE_${func}_IN_${lib}}) SET (${v_func} TRUE) SET (${v_lib} "${lib}" CACHE INTERNAL "Library providing ${func}") BREAK() ENDIF (${HAVE_${func}_IN_${lib}}) ENDFOREACH (lib) ENDIF (NOT ${v_func}) ENDMACRO (CMAKE_SEARCH_LIBS) # End copy FUNCTION(EP_CHECK_FILE_EXISTS FILE OUTVAR TARGET NAME COMMAND WORKING_DIR) string (REPLACE ";" " " COMMAND_STR "${COMMAND}") IF(WIN32) # Do something special for windows... SET(COMMAND "cmd /C \"${COMMAND_STR}\"") ELSE(WIN32) SET(COMMAND "${COMMAND_STR}") ENDIF(WIN32) FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${NAME}" " IF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\") MESSAGE(\"'${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}' already exists, nothing to be done.\") ELSE(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\") execute_process(COMMAND ${COMMAND} WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${WORKING_DIR}\") ENDIF(EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${FILE}\") ") SET(${OUTVAR} "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${NAME} PARENT_SCOPE) ENDFUNCTION(EP_CHECK_FILE_EXISTS) MACRO(COPY_FILE_TO_TARGET _target _file) if (IS_DIRECTORY "${_file}") get_filename_component(_dirName "${_file}" NAME) if (PLATFORM_MAC AND ("${_file}" MATCHES ".framework$")) # This is stupid, but it preserves symlinks, unlike copy_directory_if_different. # Otherwise we end up creating duplicate files in the copied framework. ADD_CUSTOM_COMMAND( TARGET ${_target} POST_BUILD COMMAND rsync -rlq "${_file}" "$/${LIBRAY_DESTINATION}" COMMENT "copying '${_file}'..." VERBATIM ) else() ADD_CUSTOM_COMMAND( TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different "${_file}" "$/${LIBRAY_DESTINATION}/${_dirName}" COMMENT "copying '${_file}'..." VERBATIM ) endif() else() ADD_CUSTOM_COMMAND( TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_file}" "$/${LIBRAY_DESTINATION}/" COMMENT "copying '${_file}'..." VERBATIM ) endif() endmacro(COPY_FILE_TO_TARGET) MACRO(COPY_FILES_TO_TARGET _target) ADD_CUSTOM_COMMAND( TARGET ${_target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$/${LIBRAY_DESTINATION}/" COMMENT "Creating '$/${LIBRAY_DESTINATION}/'..." VERBATIM ) FOREACH(file IN LISTS TARGET_COPY_FILES) COPY_FILE_TO_TARGET("${_target}" "${file}") ENDFOREACH(file) ENDMACRO(COPY_FILES_TO_TARGET) macro(_clear_old_libraries_state) set(is_debug FALSE) set(is_optimized FALSE) endmacro(_clear_old_libraries_state) function(CONVERT_OLD_LIBRARIES) _clear_old_libraries_state() set(out_list) foreach(lib ${ARGV}) if ("${lib}" STREQUAL "debug") _clear_old_libraries_state() set(is_debug TRUE) elseif("${lib}" STREQUAL "optimized") _clear_old_libraries_state() set(is_optimized TRUE) elseif("${lib}" STREQUAL "general") _clear_old_libraries_state() else("${lib}" STREQUAL "debug") # Expecting normal library if(is_debug) list(APPEND out_list "$<$:${lib}>" "$<$:${lib}>") elseif(is_optimized) list(APPEND out_list "$<$:${lib}>") else(is_debug) list(APPEND out_list "${lib}") endif(is_debug) endif("${lib}" STREQUAL "debug") endforeach(lib) set(CONVERTED_LIBRARIES ${out_list} PARENT_SCOPE) endfunction(CONVERT_OLD_LIBRARIES) macro(set_policy policy value) if (POLICY ${policy}) cmake_policy(SET ${policy} ${value}) endif () endmacro(set_policy) macro(set_if_not_defined VAR VALUE) if (NOT DEFINED ${VAR}) set(${VAR} ${VALUE}) endif() endmacro(set_if_not_defined) function(set_precompiled_header _target _headerPath) if (COMMAND target_precompile_headers) target_compile_definitions(${_target} PRIVATE CMAKE_PCH) target_precompile_headers(${_target} PRIVATE "$<$:${_headerPath}>") else() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") target_compile_options(${_target} PRIVATE "$<$:-include${_headerPath}>") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") target_compile_options(${_target} PRIVATE "$<$:/FI ${_headerPath}>") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") target_compile_options(${_target} PRIVATE "$<$:-include${_headerPath}>") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") target_compile_options(${_target} PRIVATE "$<$:-include${_headerPath}>") ELSE() MESSAGE("Unknown compiler for global includes. This will probably break the build.") ENDIF() endif() endfunction() macro(add_target_copy_files) foreach(file ${ARGN}) if (IS_DIRECTORY "${file}") INSTALL(DIRECTORY ${file} DESTINATION ${LIBRAY_DESTINATION} ) else() INSTALL(FILES ${file} DESTINATION ${LIBRAY_DESTINATION} ) endif() SET(TARGET_COPY_FILES ${TARGET_COPY_FILES} ${file} CACHE INTERNAL "" FORCE) endforeach() endmacro(add_target_copy_files) function(detect_simd_instructions _out_var) if(CMAKE_CROSSCOMPILING) set(${_out_var} "" PARENT_SCOPE) else() message(STATUS "Detecting SIMD features of current CPU...") TRY_RUN(RUN_RESULT COMPILE_RESULT "${CMAKE_BINARY_DIR}/temp" "${CMAKE_SOURCE_DIR}/cmake/cpufeatures.cpp" RUN_OUTPUT_VARIABLE FEATURE_OUTPUT) IF(COMPILE_RESULT) MESSAGE(STATUS "Detected compatibility for the ${FEATURE_OUTPUT} feature set.") SET(${_out_var} ${FEATURE_OUTPUT} PARENT_SCOPE) ELSE(COMPILE_RESULT) MESSAGE("Compilation of CPU feature detector failed, please set the instruction set manually.") set(${_out_var} "" PARENT_SCOPE) ENDIF(COMPILE_RESULT) endif() endfunction() function (check_linker_flag _flag _out_var) SET(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}") CHECK_C_COMPILER_FLAG("" ${_out_var}) endfunction(check_linker_flag) # Suppresses warnings for the specified target function(suppress_warnings _target) if (MSVC) target_compile_options(${_target} PRIVATE "/W0") else() # Assume everything else uses GCC style options target_compile_options(${_target} PRIVATE "-w") endif() endfunction(suppress_warnings) # Suppresses warnings for the specified files function(suppress_file_warnings) if (MSVC) set_source_files_properties( ${ARGN} PROPERTIES COMPILE_FLAGS "/W0") else() # Assume everything else uses GCC style options set_source_files_properties( ${ARGN} PROPERTIES COMPILE_FLAGS "-w") endif() endfunction(suppress_file_warnings) function(list_target_dependencies _target _out_var) set(out_list) set(work_libs ${_target}) list(LENGTH work_libs libs_length) while(libs_length GREATER 0) list(GET work_libs 0 current) list(REMOVE_AT work_libs 0) list(APPEND out_list ${current}) get_target_property(current_libs ${current} INTERFACE_LINK_LIBRARIES) if(current_libs) foreach(lib ${current_libs}) if (TARGET ${lib}) list(APPEND work_libs ${lib}) endif (TARGET ${lib}) endforeach(lib) endif(current_libs) list(LENGTH work_libs libs_length) endwhile(libs_length GREATER 0) list(REMOVE_DUPLICATES out_list) set(${_out_var} ${out_list} PARENT_SCOPE) endfunction(list_target_dependencies) macro(add_file_folder FOLDER_NAME) string(MAKE_C_IDENTIFIER "${FOLDER_NAME}" VARIABLE_NAME) set(files_${VARIABLE_NAME} ${files_${VARIABLE_NAME}} ${ARGN}) string(REPLACE "/" "\\" FIXED_FOLDER_FILE "${FOLDER_NAME}") source_group("${FIXED_FOLDER_FILE}" FILES ${ARGN}) set(source_files ${source_files} ${ARGN}) endmacro(add_file_folder)