blob: 62c2bd0d33811306e2dab47ad0a8184e85f49746 [file] [log] [blame]
# **********************************************************
# Copyright (c) 2011-2023 Google, Inc. All rights reserved.
# Copyright (c) 2009-2010 VMware, Inc. All rights reserved.
# **********************************************************
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of VMware, Inc. nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# Test suite script for DynamoRIO split into common pieces for re-use
# by tools.
# Usage:
# 1) In tool test suite script, set the project name, src dir,
# whether to run tests, and include the pre file:
# set(CTEST_PROJECT_NAME "DynamoRIO")
# set(cpack_project_name "DynamoRIO")
# set(run_tests ON)
# include("${PATH_TO_DR_EXPORTS}/cmake/runsuite_common_pre.cmake")
# 2) Do any custom argument processing and setting of base_cache
# or other vars. Can also do argument processing prior to
# the pre include.
# 3) Define function (error_string str outvar)
# It should set ${outvar} in PARENT_SCOPE to the set
# of specific errors found in ${str}.
# 4) Define the build_package boolean and include the post script:
# set(build_package ON)
# include("${PATH_TO_DR_EXPORTS}/cmake/runsuite_common_post.cmake")
# Also define build_source_package to build the package_source
# CPack target (only for non-Visual Studio generators).
#
# extra_ctest_args can also be defined to pass extra args to ctest_test(),
# such as INCLUDE_LABEL.
# ARCH_IS_X86 is defined for running x86 specific tests.
# Unfinished features in i#66 (now under i#121):
# * have a list of known failures and label w/ " (known: i#XX)"
cmake_minimum_required(VERSION 3.7)
set(cmake_ver_string
"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_RELEASE_VERSION}")
if (COMMAND cmake_policy)
# avoid warnings on include()
cmake_policy(VERSION 3.7)
endif()
# arguments are a ;-separated list (must escape as \; from ctest_run_script())
set(arg_nightly OFF) # whether to report the results
set(arg_site "") # site to report results for (for nightly reported runs)
set(arg_include "") # cmake file to include up front
set(arg_preload "") # cmake file to include prior to each 32-bit build
set(arg_preload64 "") # cmake file to include prior to each 64-bit build
set(arg_ssh OFF) # running over cygwin ssh: disable pdbs
set(arg_use_nmake OFF)# use nmake instead of visual studio
set(arg_use_msbuild OFF) # use msbuild instead of devenv for visual studio
if (UNIX)
set(arg_use_make ON) # use unix make
else (UNIX)
set(arg_use_make OFF) # use unix make instead of visual studio
endif (UNIX)
set(arg_use_ninja OFF) # use ninja
set(arg_generator "") # specify precise cmake generator (minus any "Win64")
set(arg_long OFF) # whether to run the long suite
set(arg_already_built OFF) # for testing w/ already-built suite
set(arg_exclude "") # regex of tests to exclude
set(arg_verbose OFF) # extra output
set(arg_32_only OFF) # do not include 64-bit
set(arg_64_only OFF) # do not include 64-bit
set(arg_build_only OFF) # do not run tests
foreach (arg ${CTEST_SCRIPT_ARG})
if (${arg} STREQUAL "nightly")
set(arg_nightly ON)
endif (${arg} STREQUAL "nightly")
if (${arg} MATCHES "^site=")
string(REGEX REPLACE "^site=" "" arg_site "${arg}")
endif (${arg} MATCHES "^site=")
if (${arg} MATCHES "^include=")
string(REGEX REPLACE "^include=" "" arg_include "${arg}")
endif (${arg} MATCHES "^include=")
if (${arg} MATCHES "^preload=")
string(REGEX REPLACE "^preload=" "" arg_preload "${arg}")
endif (${arg} MATCHES "^preload=")
if (${arg} MATCHES "^preload64=")
string(REGEX REPLACE "^preload64=" "" arg_preload64 "${arg}")
endif (${arg} MATCHES "^preload64=")
if (${arg} STREQUAL "ssh")
set(arg_ssh ON)
endif (${arg} STREQUAL "ssh")
if (${arg} STREQUAL "use_nmake")
set(arg_use_nmake ON)
endif ()
if (${arg} STREQUAL "use_msbuild")
set(arg_use_msbuild ON)
endif ()
if (${arg} STREQUAL "use_make")
set(arg_use_make ON)
endif ()
if (${arg} STREQUAL "use_ninja")
set(arg_use_ninja ON)
endif ()
if (${arg} STREQUAL "verbose")
set(arg_verbose ON)
endif ()
if (${arg} MATCHES "^generator=")
string(REGEX REPLACE "^generator=" "" arg_generator "${arg}")
endif ()
if (${arg} STREQUAL "long")
set(arg_long ON)
endif (${arg} STREQUAL "long")
if (${arg} STREQUAL "already_built")
set(arg_already_built ON)
endif (${arg} STREQUAL "already_built")
if (${arg} MATCHES "^exclude=")
# not parallel to include=. this excludes individual tests.
string(REGEX REPLACE "^exclude=" "" arg_exclude "${arg}")
endif (${arg} MATCHES "^exclude=")
if (${arg} MATCHES "^32_only")
set(arg_32_only ON)
endif ()
if (${arg} MATCHES "^64_only")
set(arg_64_only ON)
endif ()
if (${arg} MATCHES "^build_only")
set(arg_build_only ON)
endif ()
endforeach (arg)
# Returns a list of environment variable names to set in ${env_names}.
# For each "name" in the list, sets a variable "name_env_value" in the caller's
# scope containing the value to be set.
#
# We'd like to export this via utils_exposed.cmake but it is difficult to
# import it here from somewhere else.
# Our manual INCLUDEFILE expansion would require all users to point to a
# generated file somewhere, which requires updating all users including
# Dr. Memory which today points directly at the embedded submodule sources.
# Some of these uses have no build dir where a generated file could live.
# Using include() is difficult for a file that is itself included, because
# cmake won't search our same directory, and CTEST_SCRIPT_DIRECTORY is the
# includer's directory, so we can't easily have side-by-side files.
# For now we keep it here, and have the current only other use in
# tests/CMakeLists.txt include() this file.
function (_DR_set_VS_bitwidth_env_vars is64 env_names)
# Convert env vars to run proper compiler.
# Note that this is fragile and won't work with non-standard
# directory layouts: we assume standard VS or SDK.
# XXX: would be nice to have case-insensitive regex flag!
# For now hardcoding VC, Bin, amd64
set(must_change_path OFF)
if (is64)
list(APPEND names_list "ASM")
set(ASM_env_value "ml64" PARENT_SCOPE)
if (NOT "$ENV{LIB}" MATCHES "[Aa][Mm][Dd]64" AND
NOT "$ENV{LIB}" MATCHES "[Xx]64")
set(must_change_path ON)
# Note that we can't set ENV{PATH} as the output var of the replace:
# it has to be its own set().
#
# VS2017 has bin/HostX{86,64}/x{86,64}/
string(REGEX REPLACE "((^|;)[^;]*)HostX86([/\\\\])x86" "\\1HostX64\\3x64"
newpath "$ENV{PATH}")
# i#1421: VS2013 needs base VC/bin on the path (for cross-compiler
# used by cmake) so we duplicate and put amd64 first. Older VS needs
# Common7/IDE instead which should already be elsewhere on path.
string(REGEX REPLACE "((^|;)[^;]*)VC([/\\\\])([Bb][Ii][Nn])"
"\\1VC\\3\\4\\3amd64;\\1VC\\3\\4"
newpath "${newpath}")
# VS2008's SDKs/Windows/v{6.0A,7.0} uses "x64" instead of "amd64"
string(REGEX REPLACE "([/\\\\]v[^/\\\\]*)([/\\\\])([Bb][Ii][Nn])"
"\\1\\2\\3\\2x64"
newpath "${newpath}")
if (arg_verbose)
message("Env setup: setting PATH to ${newpath}")
endif ()
# VS2017 does not append so we replace first.
string(REGEX REPLACE "([/\\\\])x86" "\\1x64" newlib "$ENV{lib}")
# Now try to support pre-VS2017.
string(REGEX REPLACE "([/\\\\])([Ll][Ii][Bb])([^/\\\\])" "\\1\\2\\1amd64\\3"
newlib "${newlib}")
# VS2008's SDKs/Windows/v{6.0A,7.0} uses "x64" instead of "amd64": grrr
string(REGEX REPLACE
"([/\\\\]v[^/\\\\]*[/\\\\][Ll][Ii][Bb][/\\\\])[Aa][Mm][Dd]64"
"\\1x64"
newlib "${newlib}")
# Win8 SDK uses um/x86 and um/x64 after "Lib/win{8,v6.3}/"
string(REGEX REPLACE
"([Ll][Ii][Bb])[/\\\\]amd64([/\\\\][Ww][Ii][Nn][v0-9.]+[/\\\\]um[/\\\\])x86"
"\\1\\2x64" newlib "${newlib}")
if (arg_verbose)
message("Env setup: setting LIB to ${newlib}")
endif ()
string(REGEX REPLACE "([/\\\\])([Ll][Ii][Bb][/\\\\])[Xx]86" "\\1\\2"
newlibpath "$ENV{LIBPATH}")
string(REGEX REPLACE "([/\\\\])([Ll][Ii][Bb])" "\\1\\2\\1amd64"
newlibpath "${newlibpath}")
if (arg_verbose)
message("Env setup: setting LIBPATH to ${newlibpath}")
endif ()
endif ()
else (is64)
list(APPEND ${env_names} "ASM")
set(ASM_env_value "ml" PARENT_SCOPE)
if ("$ENV{LIB}" MATCHES "[Aa][Mm][Dd]64" OR
"$ENV{LIB}" MATCHES "[Xx]64")
set(must_change_path ON)
# VS2017 has bin/HostX{86,64}/x{86,64}/
string(REGEX REPLACE "((^|;)[^;]*)HostX64([/\\\\])x64" "\\1HostX86\\3x86"
newpath "$ENV{PATH}")
# Remove the duplicate we added (see i#1421 comment above).
string(REGEX REPLACE "((^|;)[^;]*)VC[/\\\\][Bb][Ii][Nn][/\\\\][Aa][Mm][Dd]64"
"" newpath "${newpath}")
if (arg_verbose)
message("Env setup: setting PATH to ${newpath}")
endif ()
string(REGEX REPLACE "([Ll][Ii][Bb])[/\\\\][Aa][Mm][Dd]64" "\\1"
newlib "$ENV{LIB}")
string(REGEX REPLACE "([Ll][Ii][Bb][/\\\\])[Xx]64" "\\1x86"
newlib "${newlib}")
# Win8 SDK uses um/x86 and um/x64
string(REGEX REPLACE "([/\\\\]um[/\\\\])x64" "\\1x86" newlib "${newlib}")
string(REGEX REPLACE "([/\\\\]ucrt[/\\\\])x64" "\\1x86" newlib "${newlib}")
if (arg_verbose)
message("Env setup: setting LIB to ${newlib}")
endif ()
string(REGEX REPLACE "([Ll][Ii][Bb])[/\\\\][Aa][Mm][Dd]64" "\\1"
newlibpath "$ENV{LIBPATH}")
string(REGEX REPLACE "([Ll][Ii][Bb][/\\\\])[Xx]64" "\\1x86"
newlibpath "${newlibpath}")
if (arg_verbose)
message("Env setup: setting LIBPATH to ${newlibpath}")
endif ()
endif ()
endif (is64)
if (must_change_path)
list(APPEND names_list "PATH")
set(PATH_env_value "${newpath}" PARENT_SCOPE)
list(APPEND names_list "LIB")
set(LIB_env_value "${newlib}" PARENT_SCOPE)
list(APPEND names_list "LIBPATH")
set(LIBPATH_env_value "${newlibpath}" PARENT_SCOPE)
endif ()
set(${env_names} ${names_list} PARENT_SCOPE)
endfunction ()
# allow setting the base cache variables via an include file
set(base_cache "")
if (arg_include)
message("including ${arg_include}")
include(${arg_include})
endif (arg_include)
if (arg_ssh)
# avoid problems creating pdbs as cygwin ssh user (i#310)
set(base_cache "${base_cache}
GENERATE_PDBS:BOOL=OFF")
endif (arg_ssh)
# Make it clear that single-bitwidth packages only contain that bitwidth
# (and provide unique names for CI deployment).
if (NOT "${base_cache}" MATCHES "PACKAGE_PLATFORM")
if (arg_64_only)
set(base_cache "${base_cache}
PACKAGE_PLATFORM:STRING=x86_64-")
elseif (arg_32_only)
set(base_cache "${base_cache}
PACKAGE_PLATFORM:STRING=i386-")
endif ()
endif ()
if (arg_use_make)
find_program(MAKE_COMMAND make DOC "make command")
if (NOT MAKE_COMMAND)
message(FATAL_ERROR "make requested but make not found")
endif (NOT MAKE_COMMAND)
endif (arg_use_make)
if (arg_use_ninja)
find_program(NINJA_COMMAND ninja DOC "ninja command")
if (NOT NINJA_COMMAND)
message(FATAL_ERROR "ninja requested but ninja not found")
endif (NOT NINJA_COMMAND)
endif (arg_use_ninja)
if (arg_long)
set(TEST_LONG ON)
else (arg_long)
set(TEST_LONG OFF)
endif (arg_long)
if (WIN32)
find_program(CYGPATH cygpath)
if (CYGPATH)
set(have_cygwin ON)
else (CYGPATH)
set(have_cygwin OFF)
endif (CYGPATH)
endif (WIN32)
get_filename_component(BINARY_BASE "." ABSOLUTE)
if (arg_nightly)
# i#11: nightly run
# Caller should have set CTEST_SITE via site= arg
if (arg_site)
set(CTEST_SITE "${arg_site}")
else (arg_site)
message(FATAL_ERROR "must set sitename via site= arg")
endif (arg_site)
set(CTEST_DASHBOARD_ROOT "${BINARY_BASE}")
# We assume a manual check out was done, and that CTest can just do "update".
# If we want a fresh checkout we can set CTEST_BACKUP_AND_RESTORE
# and CTEST_CHECKOUT_COMMAND but the update should be fine.
find_program(CTEST_UPDATE_COMMAND git DOC "source code update command")
set(SUITE_TYPE Nightly)
set(DO_UPDATE ON)
set(DO_SUBMIT ON)
set(SUBMIT_LOCAL OFF)
else (arg_nightly)
# a local run, not a nightly
set(SUITE_TYPE Experimental)
set(DO_UPDATE OFF)
set(DO_SUBMIT ON)
set(SUBMIT_LOCAL ON)
# CTest does "scp file ${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}" so for
# local copy w/o needing sshd on localhost we arrange to have : in the
# absolute filepath. Note that I would prefer having the results inside
# each build dir, but having : in the build dir name complicates
# LD_LIBRARY_PATH.
if (WIN32)
# Colon not allowed in name so use drive
string(REGEX MATCHALL "^[A-Za-z]" drive "${BINARY_BASE}")
string(REGEX REPLACE "^[A-Za-z]:" "" nondrive "${BINARY_BASE}")
set(CTEST_DROP_SITE "${drive}")
set(CTEST_DROP_LOCATION "${nondrive}/xmlresults")
set(RESULTS_DIR "${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}")
else (WIN32)
set(CTEST_DROP_SITE "${BINARY_BASE}/xml")
set(CTEST_DROP_LOCATION "results")
set(RESULTS_DIR "${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}")
endif (WIN32)
if (EXISTS "${RESULTS_DIR}")
file(REMOVE_RECURSE "${RESULTS_DIR}")
endif (EXISTS "${RESULTS_DIR}")
file(MAKE_DIRECTORY "${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}")
endif (arg_nightly)
# Find the number of CPUs on the current system.
# Cribbed from http://www.kitware.com/blog/home/post/63
if(NOT DEFINED PROCESSOR_COUNT)
# Unknown:
set(PROCESSOR_COUNT 4) # Guess
# Linux:
set(cpuinfo_file "/proc/cpuinfo")
if(EXISTS "${cpuinfo_file}")
file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
list(LENGTH procs PROCESSOR_COUNT)
endif()
# Mac:
if(APPLE)
find_program(cmd_sys_pro "system_profiler")
if(cmd_sys_pro)
execute_process(COMMAND ${cmd_sys_pro} SPHardwareDataType OUTPUT_VARIABLE info)
string(REGEX REPLACE "^.*Total Number [Oo]f Cores: ([0-9]+).*$" "\\1"
PROCESSOR_COUNT "${info}")
endif()
endif()
# Windows:
if(WIN32)
if ($ENV{NUMBER_OF_PROCESSORS})
set(PROCESSOR_COUNT "$ENV{NUMBER_OF_PROCESSORS}")
endif ()
endif()
endif()
math(EXPR PARALLEL_COUNT_BUILD "${PROCESSOR_COUNT} + 2")
# Typically no benefit and sometimes detrimental to exceed core count here
math(EXPR PARALLEL_COUNT_TEST "${PROCESSOR_COUNT}")
# CTest goes and does our builds and then wants to configure
# and build again and complains there's no top-level setting of
# CTEST_BINARY_DIRECTORY:
# "CMake Error: Some required settings in the configuration file were missing:"
# but we don't want to do another build so we just ignore the error.
set(CTEST_CMAKE_COMMAND "${CMAKE_EXECUTABLE_NAME}")
# outer file should set CTEST_PROJECT_NAME
set(CTEST_COMMAND "${CTEST_EXECUTABLE_NAME}")
# Raise the default of 50 to avoid warnings blocking the detection of
# build failures (i#1137):
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS 200)
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 200)
# Detect if the arch is x86
if (NOT DEFINED ARCH_IS_X86)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64)")
set(ARCH_IS_X86 OFF)
else ()
set(ARCH_IS_X86 ON)
endif ()
endif ()
# Detect if the kernel is ia32 or x64. If the kernel is ia32, there's no sense
# in trying to run any x64 code. On Windows, the x64 toolchain is built as x64
# code, so we can't even build. On Linux, it's possible to have an ia32
# toolchain that targets x64, but we don't currently support it.
if (NOT DEFINED KERNEL_IS_X64) # Allow variable override.
if (WIN32)
# Check both PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432 in case CMake
# was built x64.
if ("$ENV{PROCESSOR_ARCHITECTURE}" MATCHES "AMD64" OR
"$ENV{PROCESSOR_ARCHITEW6432}" MATCHES "AMD64")
set(KERNEL_IS_X64 ON)
else ()
set(KERNEL_IS_X64 OFF)
endif ()
else ()
# uname -m is what the kernel supports.
execute_process(COMMAND uname -m
OUTPUT_VARIABLE machine
RESULT_VARIABLE cmd_result)
# If for some reason uname fails (not on PATH), assume the kernel is x64
# anyway.
if (cmd_result OR "${machine}" MATCHES "x86_64|aarch64|arm64")
set(KERNEL_IS_X64 ON)
else ()
set(KERNEL_IS_X64 OFF)
endif ()
endif ()
endif ()
if (NOT KERNEL_IS_X64)
message("WARNING: Kernel is not x64, skipping x64 builds")
endif ()
if (arg_use_ninja)
set(CTEST_CMAKE_GENERATOR "Ninja")
elseif (arg_use_make)
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
find_program(MAKE_COMMAND make DOC "make command")
if (have_cygwin)
# seeing errors building in parallel: pdb collision?
# can't repro w/ VERBOSE=1
set(CTEST_BUILD_COMMAND_BASE "${MAKE_COMMAND} -j2")
else (have_cygwin)
set(CTEST_BUILD_COMMAND_BASE "${MAKE_COMMAND} -j${PARALLEL_COUNT_BUILD}")
endif (have_cygwin)
elseif (arg_use_nmake)
set(CTEST_CMAKE_GENERATOR "NMake Makefiles")
else ()
if (arg_generator)
set(vs_generator ${arg_generator})
else ()
set(vs_generator "NOTFOUND")
get_filename_component(current_directory_path "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${current_directory_path}/lookup_visualstudio.cmake)
get_visualstudio_info(vs_dir vs_version vs_generator)
if (NOT vs_generator)
message(FATAL_ERROR "Cannot determine Visual Studio version")
endif ()
endif ()
message(STATUS "Using ${vs_generator} generators")
if (arg_use_msbuild)
find_program(MSBUILD_PROGRAM msbuild)
if (MSBUILD_PROGRAM)
set(base_cache "${base_cache}
CMAKE_MAKE_PROGRAM:FILEPATH=${MSBUILD_PROGRAM}")
# Unfortunately we have to provide all the args (setting CMAKE_MAKE_PROGRAM
# doesn't do it for ctest builds). We want ALL_BUILD.vcproj for pre-VS2010
# and ALL_BUILD.vcxproj for VS2010.
if (vs_generator MATCHES "Visual Studio 1.")
set(proj_file "ALL_BUILD.vcxproj")
else ()
set(proj_file "ALL_BUILD.vcproj")
endif ()
# Request parallel build on all available cores (sequential by default: i#800)
# via "/m".
# Configuration will be adjusted per build below.
set(CTEST_BUILD_COMMAND
"${MSBUILD_PROGRAM} ${proj_file} /p:Configuration=REPLACE_CONFIG /m")
else (MSBUILD_PROGRAM)
message("WARNING: cannot find msbuild; disabling")
set(arg_use_msbuild OFF)
endif (MSBUILD_PROGRAM)
endif (arg_use_msbuild)
endif ()
function(get_default_config config builddir)
file(READ "${builddir}/CMakeCache.txt" cache)
string(REGEX MATCH "CMAKE_CONFIGURATION_TYPES:STRING=([^\n]*)" cache "${cache}")
string(REGEX REPLACE "CMAKE_CONFIGURATION_TYPES:STRING=([^;]*)" "\\1"
cache "${cache}")
set(${config} ${cache} PARENT_SCOPE)
endfunction(get_default_config)
# Sets two vars in PARENT_SCOPE:
# + returns the build dir in "last_build_dir"
# + for each build for which add_to_package is true:
# - returns the build dir in "last_package_build_dir"
# - adds to "cpack_projects" for project "${cpack_project_name}"
# (set by outer file)
function(testbuild_ex name is64 initial_cache test_only_in_long
add_to_package build_args)
set(CTEST_BUILD_NAME "${name}")
# Skip x64 builds on a true ia32 machine.
if (is64 AND NOT KERNEL_IS_X64)
return()
endif ()
if (is64 AND arg_32_only)
return()
endif ()
if (NOT is64 AND arg_64_only)
return()
endif ()
# Skip 32-bit builds on an AArch64 machine.
if (NOT is64 AND CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
return()
endif ()
if (NOT arg_use_nmake AND NOT arg_use_make AND NOT arg_use_ninja)
# we need a separate generator for 64-bit as well as the PATH
# env var changes below (since we run cl directly)
if (is64)
set(CTEST_CMAKE_GENERATOR "${vs_generator} Win64")
else (is64)
set(CTEST_CMAKE_GENERATOR "${vs_generator}")
endif (is64)
# we need to set this for the package build using the last build
set(CTEST_CMAKE_GENERATOR "${CTEST_CMAKE_GENERATOR}" PARENT_SCOPE)
endif ()
set(CTEST_BINARY_DIRECTORY "${BINARY_BASE}/build_${CTEST_BUILD_NAME}")
set(last_build_dir "${CTEST_BINARY_DIRECTORY}" PARENT_SCOPE)
if (NOT arg_already_built)
# Support other VC installations than VS2005 via pre-build include file.
# Preserve path so include file can simply prepend each time.
set(pre_path "$ENV{PATH}")
set(pre_lib "$ENV{LIB}")
if (is64)
set(preload_file "${arg_preload64}")
else (is64)
set(preload_file "${arg_preload}")
endif (is64)
if (preload_file)
# Command-style CTest (i.e., using ctest_configure(), etc.) does
# not support giving args to CTEST_CMAKE_COMMAND so we are forced
# to do an include() instead of -C
include("${preload_file}")
endif (preload_file)
if (WIN32)
# i#111: Disabling progress and status messages can speed the Windows build
# up by up to 50%. I filed CMake bug 8726 on this and this variable will be
# in the 2.8 release; going ahead and setting now.
# For Linux these messages make little perf difference, and can help
# diagnose errors or watch progress.
# The messages only apply to Makefile generators, not Visual Studio.
if (NOT "${CTEST_CMAKE_GENERATOR}" MATCHES "Visual Studio")
set(os_specific_defines "CMAKE_RULE_MESSAGES:BOOL=OFF")
endif ()
else (WIN32)
set(os_specific_defines "")
endif (WIN32)
set(CTEST_INITIAL_CACHE "${initial_cache}
TEST_SUITE:BOOL=ON
${os_specific_defines}
${base_cache}
")
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "${CTEST_INITIAL_CACHE}")
if (WIN32)
# If other compilers also on path ensure we pick cl
set(ENV{CC} "cl")
set(ENV{CXX} "cl")
# Convert env vars to run proper compiler.
_DR_set_VS_bitwidth_env_vars(${is64} env_names)
foreach (env ${env_names})
set(ENV{${env}} "${${env}_env_value}")
endforeach ()
else (WIN32)
if (ARCH_IS_X86)
if (is64)
set(ENV{CFLAGS} "-m64")
set(ENV{CXXFLAGS} "-m64")
else (is64)
set(ENV{CFLAGS} "-m32")
set(ENV{CXXFLAGS} "-m32")
endif (is64)
endif (ARCH_IS_X86)
endif (WIN32)
else (NOT arg_already_built)
# remove the Last* files from the prior run
file(GLOB lastrun ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/Last*)
if (lastrun)
file(REMOVE ${lastrun})
endif (lastrun)
endif (NOT arg_already_built)
ctest_start(${SUITE_TYPE})
if (NOT arg_already_built)
if (DO_UPDATE)
ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}")
endif (DO_UPDATE)
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE config_success)
if (config_success EQUAL 0)
# support "make install"
if (DEFINED CTEST_BUILD_COMMAND_BASE)
set(CTEST_BUILD_COMMAND "${CTEST_BUILD_COMMAND_BASE} ${build_args}")
else () # else use default
if ("${CTEST_CMAKE_GENERATOR}" MATCHES "Visual Studio")
# workaround for cmake bug #11830 where assumes "Debug" is
# the default config
get_default_config(defconfig "${CTEST_BINARY_DIRECTORY}")
set(CTEST_BUILD_CONFIGURATION "${defconfig}")
message("building default config \"${defconfig}\"")
if (NOT "${build_args}" STREQUAL "" OR
NOT "${extra_build_args}" STREQUAL "")
set(CTEST_BUILD_FLAGS "-- ${extra_build_args} ${build_args}")
endif ()
if (arg_use_msbuild)
string(REPLACE "REPLACE_CONFIG" "${defconfig}" CTEST_BUILD_COMMAND
"${CTEST_BUILD_COMMAND}")
endif (arg_use_msbuild)
else ()
set(CTEST_BUILD_FLAGS "${build_args}")
endif ()
message("building with args \"${CTEST_BUILD_FLAGS}\"")
endif ()
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE build_success)
else (config_success EQUAL 0)
set(build_success -1)
if (optional_cross_compile)
# XXX: for platforms requiring special hardware such as ARM, this global indicates
# an optional cross-compilation, for use on more common platforms like x86 Unix
# (would use a parameter instead of a global, except for backward compatibility)
file(GLOB last_config ${CTEST_BINARY_DIRECTORY}/Testing/*/*.xml)
if (last_config)
file(REMOVE ${last_config})
endif (last_config)
set(DO_SUBMIT OFF)
message("Warning: optional cross-compilation \"${name}\" is not available"
"--skipping")
set(add_to_package OFF)
file(WRITE ${CTEST_BINARY_DIRECTORY}/Testing/missing-cross-compile "${name}")
endif (optional_cross_compile)
endif (config_success EQUAL 0)
else (NOT arg_already_built)
set(build_success 0)
endif (NOT arg_already_built)
if (build_success EQUAL 0 AND run_tests AND NOT arg_build_only)
if (NOT test_only_in_long OR ${TEST_LONG})
# to run a subset of tests add an INCLUDE regexp to ctest_test. e.g.:
# INCLUDE broadfun
if (NOT "${arg_exclude}" STREQUAL "")
set(ctest_test_args ${ctest_test_args} EXCLUDE ${arg_exclude})
endif (NOT "${arg_exclude}" STREQUAL "")
set(ctest_test_args ${ctest_test_args} ${extra_ctest_args})
if ("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.17")
# CMake 3.17 supports retrying failed tests. We avoid flaky tests on
# particular platforms failing the whole suite by trying multiple times.
set(ctest_test_args ${ctest_test_args} "REPEAT" "UNTIL_PASS:3")
endif ()
if (WIN32 AND TEST_LONG)
# FIXME i#265: on Windows we can't run multiple instances of
# the same app b/c of global reg key conflicts: should support
# env vars and not require registry
set(RUN_PARALLEL OFF)
else ()
set(RUN_PARALLEL ON)
endif ()
if (RUN_PARALLEL)
# i#111: run tests in parallel, supported on CTest 2.8.0+
# Note that adding -j to CMAKE_COMMAND does not work, though invoking
# this script with -j does work, but we want parallel by default.
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
PARALLEL_LEVEL ${PARALLEL_COUNT_TEST} ${ctest_test_args})
else (RUN_PARALLEL)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" ${ctest_test_args})
endif (RUN_PARALLEL)
endif (NOT test_only_in_long OR ${TEST_LONG})
endif (build_success EQUAL 0 AND run_tests AND NOT arg_build_only)
if (DO_SUBMIT)
if (CTEST_DROP_METHOD MATCHES "http")
# include any notes via set(CTEST_NOTES_FILES )?
ctest_submit()
else ()
# We used to use the "scp" (could also have used "cp") drop method
# to copy these xml files out for us, but cmake 3.14 dropped that.
# Thus we copy them ourselves.
file(GLOB xml_files "${CTEST_BINARY_DIRECTORY}/Testing/*/*.xml")
set(prefix "___${CTEST_BUILD_NAME}___${SUITE_TYPE}___XML___")
foreach (xml ${xml_files})
get_filename_component(base "${xml}" NAME)
# Avoid confusion with a later package build in the same dir by
# renaming instead of copying.
file(RENAME "${xml}"
"${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}/${prefix}${base}")
message("Moving ${xml} to "
"${CTEST_DROP_SITE}:${CTEST_DROP_LOCATION}/${prefix}${base}")
endforeach ()
endif ()
endif (DO_SUBMIT)
if (NOT arg_already_built)
set(ENV{PATH} "${pre_path}")
set(ENV{LIB} "${pre_lib}")
endif (NOT arg_already_built)
if (add_to_package)
# support having the suite test building the full package
# FIXME: perhaps should replace package.cmake w/ invocation of runsuite.cmake
# w/ certain params, since they're pretty similar at this point?
# communicate w/ caller
set(last_package_build_dir "${CTEST_BINARY_DIRECTORY}" PARENT_SCOPE)
if (CTEST_BINARY_DIRECTORY MATCHES "debug")
# prepend rather than append to get debug first, so we take release
# files preferentially in case of overlap
set(cpack_projects
"\"${CTEST_BINARY_DIRECTORY};${cpack_project_name};ALL;/\"\n ${cpack_projects}"
PARENT_SCOPE)
else ()
set(cpack_projects
"${cpack_projects}\n \"${CTEST_BINARY_DIRECTORY};${cpack_project_name};ALL;/\""
PARENT_SCOPE)
endif ()
if ("${CTEST_CMAKE_GENERATOR}" MATCHES "Visual Studio")
# i#390: workaround for cpack limitation where cpack is run w/
# one config and each build's install rules check only for their
# own config. we change each config check to "TRUE OR <check>".
file(READ "${CTEST_BINARY_DIRECTORY}/cmake_install.cmake" str)
# grab first-level includes
string(REGEX MATCHALL "INCLUDE\\\(\"[^\"]+\"" includes "${str}")
string(REGEX REPLACE "INCLUDE\\\(\"([^\"]+)\"" "\\1" includes "${includes}")
# grab second-level includes
set(includes2nd )
foreach (config ${includes})
file(READ "${config}" str)
string(REGEX MATCHALL "INCLUDE\\\(\"[^\"]+\"" newincs "${str}")
string(REGEX REPLACE "INCLUDE\\\(\"([^\"]+)\"" "\\1" newincs "${newincs}")
set(includes2nd ${includes2nd} ${newincs})
endforeach (config)
# now process each
foreach (config "${CTEST_BINARY_DIRECTORY}/cmake_install.cmake"
${includes} ${includes2nd})
file(READ "${config}" str)
string(REGEX REPLACE "IF\\\((\"\\\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES)"
"IF(TRUE OR \\1" str "${str}")
# set CMP0012 policy to treat TRUE as literal
file(WRITE "${config}" "cmake_policy(VERSION 2.8)\n${str}")
endforeach (config)
endif ()
endif (add_to_package)
endfunction(testbuild_ex)
function(testbuild name is64 initial_cache)
# by default run all tests and do not include in package
testbuild_ex(${name} ${is64} ${initial_cache} OFF OFF "")
# propagate
set(last_build_dir "${last_build_dir}" PARENT_SCOPE)
set(last_package_build_dir "${last_package_build_dir}" PARENT_SCOPE)
set(cpack_projects "${cpack_projects}" PARENT_SCOPE)
endfunction(testbuild)