mirror of
https://github.com/Bareflank/hypervisor
synced 2026-08-17 06:23:04 -04:00
This patch adds support for unordered_map. Specifically it adds support for libm which is needed by unordered_map as it abuses the ceil function for integer rounding in it's hash function. Signed-off-by: “rianquinn” <“rianquinn@gmail.com”>
1338 lines
46 KiB
CMake
1338 lines
46 KiB
CMake
#
|
|
# Bareflank Hypervisor
|
|
# Copyright (C) 2015 Assured Information Security, Inc.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
include(ProcessorCount)
|
|
include(ExternalProject)
|
|
|
|
if(ENABLE_BUILD_TEST)
|
|
include(CTest)
|
|
enable_testing(true)
|
|
endif()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# colors
|
|
# ------------------------------------------------------------------------------
|
|
|
|
if(NOT WIN32)
|
|
string(ASCII 27 Esc)
|
|
set(ColorReset "${Esc}[m")
|
|
set(ColorBold "${Esc}[1m")
|
|
set(Red "${Esc}[31m")
|
|
set(Green "${Esc}[32m")
|
|
set(Yellow "${Esc}[33m")
|
|
set(Blue "${Esc}[34m")
|
|
set(Magenta "${Esc}[35m")
|
|
set(Cyan "${Esc}[36m")
|
|
set(White "${Esc}[37m")
|
|
set(BoldRed "${Esc}[1;31m")
|
|
set(BoldGreen "${Esc}[1;32m")
|
|
set(BoldYellow "${Esc}[1;33m")
|
|
set(BoldBlue "${Esc}[1;34m")
|
|
set(BoldMagenta "${Esc}[1;35m")
|
|
set(BoldCyan "${Esc}[1;36m")
|
|
set(BoldWhite "${Esc}[1;37m")
|
|
endif()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_config
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Add Config
|
|
#
|
|
# Add a configurable varibale to the CMake build. This function ensures each
|
|
# variable is properly set, and ensures it's properly visible in ccmake.
|
|
#
|
|
# @param ADVANCED Only show this variable in the advanced mode for ccmake
|
|
# @param SKIP_VALIDATION do not validate that the varibale is properly set
|
|
# @param CONFIG_NAME The name of the variable
|
|
# @param CONFIG_TYPE The variable's type: STRING, PATH, FILEPATH, BOOL
|
|
# @param DEFAULT_VAL The default value for the variable
|
|
# @param DESCRIPTION A description of the variable
|
|
# @param OPTIONS Possible values for the the variable. Only applies to STRING
|
|
# type variables.
|
|
#
|
|
macro(add_config)
|
|
set(options ADVANCED SKIP_VALIDATION)
|
|
set(oneVal CONFIG_NAME CONFIG_TYPE DEFAULT_VAL DESCRIPTION)
|
|
set(multiVal OPTIONS)
|
|
cmake_parse_arguments(ARG "${options}" "${oneVal}" "${multiVal}" ${ARGN})
|
|
|
|
if(ARG_CONFIG_TYPE STREQUAL "BOOL" AND NOT ARG_DEFAULT_VAL)
|
|
set(ARG_DEFAULT_VAL OFF)
|
|
endif()
|
|
|
|
if(NOT DEFINED ${ARG_CONFIG_NAME})
|
|
set(${ARG_CONFIG_NAME} ${ARG_DEFAULT_VAL} CACHE ${ARG_CONFIG_TYPE} ${ARG_DESCRIPTION})
|
|
else()
|
|
set(${ARG_CONFIG_NAME} ${${ARG_CONFIG_NAME}} CACHE ${ARG_CONFIG_TYPE} ${ARG_DESCRIPTION})
|
|
endif()
|
|
|
|
if(ARG_OPTIONS AND ARG_CONFIG_TYPE STREQUAL "STRING")
|
|
set_property(CACHE ${ARG_CONFIG_NAME} PROPERTY STRINGS ${ARG_OPTIONS})
|
|
endif()
|
|
|
|
if(NOT ARG_SKIP_VALIDATION)
|
|
if(ARG_OPTIONS AND ARG_CONFIG_TYPE STREQUAL "STRING")
|
|
if(NOT ARG_DEFAULT_VAL IN_LIST ARG_OPTIONS)
|
|
message(FATAL_ERROR "${ARG_CONFIG_NAME} invalid option \'${ARG_DEFAULT_VAL}\'")
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_CONFIG_TYPE STREQUAL "PATH")
|
|
if(NOT EXISTS "${ARG_DEFAULT_VAL}")
|
|
message(FATAL_ERROR "${ARG_CONFIG_NAME} path not found: ${ARG_DEFAULT_VAL}")
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_CONFIG_TYPE STREQUAL "FILEPATH")
|
|
if(NOT EXISTS "${ARG_DEFAULT_VAL}")
|
|
message(FATAL_ERROR "${ARG_CONFIG_NAME} file not found: ${ARG_DEFAULT_VAL}")
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_CONFIG_TYPE STREQUAL "BOOL")
|
|
if(NOT ARG_DEFAULT_VAL STREQUAL ON AND NOT ARG_DEFAULT_VAL STREQUAL OFF)
|
|
message(FATAL_ERROR "${ARG_CONFIG_NAME} must be set to ON or OFF")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_ADVANCED)
|
|
mark_as_advanced(${ARG_CONFIG_NAME})
|
|
endif()
|
|
endmacro(add_config)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# include_external_config
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
macro(include_external_config)
|
|
if(CONFIG)
|
|
foreach(c ${CONFIG})
|
|
if(EXISTS "${SOURCE_CONFIG_DIR}/${c}.cmake")
|
|
message(STATUS "Config: ${SOURCE_CONFIG_DIR}/${c}.cmake")
|
|
include(${SOURCE_CONFIG_DIR}/${c}.cmake)
|
|
continue()
|
|
endif()
|
|
if(NOT IS_ABSOLUTE "${c}")
|
|
get_filename_component(c "${BUILD_ROOT_DIR}/${c}" ABSOLUTE)
|
|
endif()
|
|
if(EXISTS "${c}")
|
|
message(STATUS "Config: ${c}")
|
|
include(${c})
|
|
continue()
|
|
endif()
|
|
|
|
message(FATAL_ERROR "File not found: ${c}")
|
|
endforeach(c)
|
|
elseif(EXISTS "${CMAKE_SOURCE_DIR}/../config.cmake")
|
|
get_filename_component(CONFIG "${CMAKE_SOURCE_DIR}/../config.cmake" ABSOLUTE)
|
|
message(STATUS "Config: ${CONFIG}")
|
|
include(${CONFIG})
|
|
endif()
|
|
endmacro(include_external_config)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# include_external_extensions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
macro(include_external_extensions)
|
|
foreach(e ${EXTENSION})
|
|
if(NOT IS_ABSOLUTE "${e}")
|
|
get_filename_component(e "${BUILD_ROOT_DIR}/${e}" ABSOLUTE)
|
|
endif()
|
|
if(EXISTS "${e}/CMakeLists.txt")
|
|
message(STATUS "Extension: ${e}")
|
|
include(${e}/CMakeLists.txt)
|
|
else()
|
|
message(FATAL_ERROR "Extension not found: ${e}")
|
|
endif()
|
|
endforeach(e)
|
|
endmacro(include_external_extensions)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# generate_flags
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Generate Flags
|
|
#
|
|
# Sets up CMAKE_C_FLAGS and CMAKE_CXX_FLAGS based on the provided flags and
|
|
# prefix value. Each time this is executed, CMAKE_XXX_FLAGS are overwritten
|
|
# and globally set. The add_subproject function performs this action on your
|
|
# behalf, and this function generally should not be used unless you are
|
|
# compiling a dependency, in which case, you will need to run this manually.
|
|
#
|
|
# @param PREFIX (macro arg) Defines which prefix the flags belong too. Valid
|
|
# values are: vmm, userspace, and test
|
|
# @param C_FLAGS Additional C flags to add to CMAKE_C_FLAGS
|
|
# @param CXX_FLAGS Additional CXX flags to add to CMAKE_CXX_FLAGS
|
|
#
|
|
function(generate_flags PREFIX)
|
|
set(options NOWARNINGS)
|
|
set(multiVal C_FLAGS CXX_FLAGS)
|
|
cmake_parse_arguments(ARG "${options}" "" "${multiVal}" ${ARGN})
|
|
|
|
list(APPEND _C_FLAGS ${ARG_C_FLAGS})
|
|
list(APPEND _CXX_FLAGS ${ARG_CXX_FLAGS})
|
|
|
|
if(PREFIX STREQUAL "vmm")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_VMM} ${BFFLAGS_VMM_C} ${C_FLAGS_VMM})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_VMM} ${BFFLAGS_VMM_CXX} ${CXX_FLAGS_VMM})
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "x86_64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_VMM_X86_64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_VMM_X86_64})
|
|
endif()
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "aarch64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_VMM_AARCH64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_VMM_AARCH64})
|
|
endif()
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_USERSPACE} ${BFFLAGS_USERSPACE_C} ${C_FLAGS_USERSPACE})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_USERSPACE} ${BFFLAGS_USERSPACE_CXX} ${CXX_FLAGS_USERSPACE})
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "x86_64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_USERSPACE_X86_64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_USERSPACE_X86_64})
|
|
endif()
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "aarch64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_USERSPACE_AARCH64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_USERSPACE_AARCH64})
|
|
endif()
|
|
elseif(PREFIX STREQUAL "test")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_TEST} ${BFFLAGS_TEST_C} ${C_FLAGS_TEST})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_TEST} ${BFFLAGS_TEST_CXX} ${CXX_FLAGS_TEST})
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "x86_64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_TEST_X86_64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_TEST_X86_64})
|
|
endif()
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "aarch64")
|
|
list(APPEND _C_FLAGS ${BFFLAGS_TEST_AARCH64})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_TEST_AARCH64})
|
|
endif()
|
|
if(ENABLE_ASAN)
|
|
list(APPEND _C_FLAGS ${BFFLAGS_ASAN})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_ASAN})
|
|
endif()
|
|
if(ENABLE_USAN)
|
|
list(APPEND _C_FLAGS ${BFFLAGS_USAN})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_USAN})
|
|
endif()
|
|
if(ENABLE_CODECOV)
|
|
list(APPEND _C_FLAGS ${BFFLAGS_CODECOV})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_CODECOV})
|
|
endif()
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
|
|
if(NOT ARG_NOWARNINGS)
|
|
if(ENABLE_COMPILER_WARNINGS)
|
|
list(APPEND _C_FLAGS ${BFFLAGS_WARNING_C})
|
|
list(APPEND _CXX_FLAGS ${BFFLAGS_WARNING_CXX})
|
|
endif()
|
|
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
if(NOT WIN32)
|
|
list(APPEND _C_FLAGS -Werror)
|
|
list(APPEND _CXX_FLAGS -Werror)
|
|
else()
|
|
list(APPEND _C_FLAGS /WX)
|
|
list(APPEND _CXX_FLAGS /WX)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
string(REPLACE ";" " " _C_FLAGS "${_C_FLAGS}")
|
|
string(REPLACE ";" " " _CXX_FLAGS "${_CXX_FLAGS}")
|
|
|
|
set(CMAKE_C_FLAGS ${_C_FLAGS} PARENT_SCOPE)
|
|
set(CMAKE_CXX_FLAGS ${_CXX_FLAGS} PARENT_SCOPE)
|
|
endfunction(generate_flags)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# include_dependency
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(include_dependency NAME)
|
|
include(${SOURCE_DEPENDS_DIR}/${NAME}.cmake)
|
|
endfunction(include_dependency)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# download_dependency
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Download Dependency
|
|
#
|
|
# Downloads a dependency from a URL. Dependencies can either be
|
|
# a tarball or a zip file. These downloaded files are placeed in the CACHE_DIR.
|
|
# If the provided MD5 hash does not match, the cached download is redownloaded.
|
|
#
|
|
# @param NAME the name of the dependency
|
|
# @param URL The URL for the dependency
|
|
# @param URL_MD5 The MD5 of the file being downloaded
|
|
# @param PREFIX An optional prefix. This is only needed if downloading the
|
|
# dependency is the only required step, in which case this function will
|
|
# create the custom target for dependency tracking.
|
|
#
|
|
function(download_dependency NAME)
|
|
set(oneVal URL URL_MD5 GIT_REPOSITORY GIT_TAG PREFIX)
|
|
cmake_parse_arguments(ARG "" "${oneVal}" "" ${ARGN})
|
|
|
|
set(SRC ${CACHE_DIR}/${NAME})
|
|
|
|
if(ARG_URL)
|
|
if(NOT ARG_URL_MD5)
|
|
message(FATAL_ERROR "Invalid URL MD5: ${ARG_URL_MD5}")
|
|
endif()
|
|
|
|
string(REGEX REPLACE "\\.[^.]*$" "" FILENAME ${ARG_URL})
|
|
string(REPLACE "${FILENAME}" "" EXT ${ARG_URL})
|
|
get_filename_component(LONG_EXT ${ARG_URL} EXT)
|
|
if(NOT LONG_EXT MATCHES "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
|
|
message(FATAL_ERROR "Unsupported file format: ${ARG_URL}")
|
|
endif()
|
|
|
|
if(LONG_EXT MATCHES ".tar.gz$")
|
|
set(EXT ".tar.gz")
|
|
endif()
|
|
|
|
if(LONG_EXT MATCHES ".tar.xz$")
|
|
set(EXT ".tar.xz")
|
|
endif()
|
|
|
|
if(LONG_EXT MATCHES ".tar.bz2$")
|
|
set(EXT ".tar.bz2")
|
|
endif()
|
|
|
|
set(TMP ${CACHE_DIR}/${NAME}_tmp)
|
|
set(TAR ${CACHE_DIR}/${NAME}${EXT})
|
|
|
|
# TODO
|
|
#
|
|
# If a dependency needs to be downloaded, currently, we remove the
|
|
# source directory which forces a recompile. We need to verify that
|
|
# when this happens, all of the targets that rely on this dependency
|
|
# are also recompiled / relinked.
|
|
#
|
|
|
|
foreach(ATTEMPT RANGE 1 5 1)
|
|
if(EXISTS "${TAR}")
|
|
message(STATUS " checking hash: ${ARG_URL_MD5}")
|
|
file(MD5 ${TAR} MD5)
|
|
if(NOT "${MD5}" STREQUAL "${ARG_URL_MD5}")
|
|
message(STATUS " ${Red}md5 mismatch: expecting ${ARG_URL_MD5}, got ${MD5}${ColorReset}")
|
|
file(REMOVE_RECURSE ${SRC})
|
|
file(REMOVE_RECURSE ${TMP})
|
|
file(REMOVE_RECURSE ${TAR})
|
|
file(REMOVE_RECURSE ${DEPENDS_DIR})
|
|
message(STATUS " checking hash: ${Yellow}complete, redownload required${ColorReset}")
|
|
else()
|
|
message(STATUS " checking hash: ${Green}complete${ColorReset}")
|
|
break()
|
|
endif()
|
|
endif()
|
|
|
|
if(ATTEMPT GREATER 1)
|
|
message(STATUS " attempt: ${ATTEMPT}")
|
|
endif()
|
|
|
|
message(STATUS " download file: ${ARG_URL} -> ${TAR}")
|
|
file(DOWNLOAD ${ARG_URL} ${TAR} STATUS DOWNLOAD_STATUS)
|
|
if(NOT DOWNLOAD_STATUS MATCHES "0;")
|
|
message(STATUS " ${Red}failed to download ${ARG_URL}${ColorReset}")
|
|
file(REMOVE_RECURSE ${TAR})
|
|
continue()
|
|
endif()
|
|
message(STATUS " download file: ${Green}complete${ColorReset}")
|
|
endforeach()
|
|
|
|
if(EXISTS ${TAR})
|
|
file(MD5 ${TAR} MD5)
|
|
if(NOT "${MD5}" STREQUAL "${ARG_URL_MD5}")
|
|
message(FATAL_ERROR "Failed to download ${ARG_URL} with md5 hash of ${ARG_URL_MD5}")
|
|
endif()
|
|
else()
|
|
message(FATAL_ERROR "Failed to download ${ARG_URL} with md5 hash of ${ARG_URL_MD5}")
|
|
endif()
|
|
|
|
if(NOT EXISTS "${SRC}")
|
|
file(REMOVE_RECURSE ${TMP})
|
|
file(REMOVE_RECURSE ${SRC})
|
|
file(MAKE_DIRECTORY ${TMP})
|
|
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E tar xfz ${TAR}
|
|
WORKING_DIRECTORY ${TMP}
|
|
)
|
|
|
|
file(GLOB CONTENTS "${TMP}/*")
|
|
|
|
list(LENGTH CONTENTS LEN)
|
|
if(NOT LEN EQUAL 1 OR NOT IS_DIRECTORY ${CONTENTS})
|
|
message(FATAL_ERROR "Invalid tarball: ${ARG_URL}")
|
|
endif()
|
|
|
|
get_filename_component(CONTENTS ${CONTENTS} ABSOLUTE)
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E rename ${CONTENTS} ${SRC}
|
|
)
|
|
|
|
file(REMOVE_RECURSE ${TMP})
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_GIT_REPOSITORY)
|
|
if(ARG_GIT_TAG)
|
|
set(ARG_GIT_TAG -b ${ARG_GIT_TAG})
|
|
endif()
|
|
if(NOT EXISTS "${SRC}")
|
|
execute_process(COMMAND git clone ${ARG_GIT_REPOSITORY} ${ARG_GIT_TAG} ${SRC})
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_PREFIX)
|
|
if(ARG_PREFIX STREQUAL "vmm")
|
|
add_custom_target(${NAME}_${VMM_PREFIX})
|
|
elseif(ARG_PREFIX STREQUAL "userspace")
|
|
add_custom_target(${NAME}_${USERSPACE_PREFIX})
|
|
elseif(ARG_PREFIX STREQUAL "test")
|
|
add_custom_target(${NAME}_${TEST_PREFIX})
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
endif()
|
|
endfunction(download_dependency)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_dependency
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Add Dependency
|
|
#
|
|
# Uses ExternalProject_Add to add the dependency to the build. All of the
|
|
# optional arguments are passed directly to ExternalProject_Add, so most of
|
|
# ExternalProject_Add's options are supported by this function.
|
|
#
|
|
# @param NAME the name of the dependency
|
|
# @param PREFIX the prefix this dependency belongs too. Valid values are:
|
|
# vmm, userspace and test.
|
|
#
|
|
function(add_dependency NAME PREFIX)
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(PREFIX ${VMM_PREFIX})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(PREFIX ${USERSPACE_PREFIX})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(PREFIX ${TEST_PREFIX})
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
|
|
if(EXISTS "${CACHE_DIR}/${NAME}/CMakeLists.txt")
|
|
list(APPEND ARGN
|
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PREFIXES_DIR}/${PREFIX}
|
|
CMAKE_ARGS -DCMAKE_INSTALL_MESSAGE=${CMAKE_INSTALL_MESSAGE}
|
|
CMAKE_ARGS -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}
|
|
)
|
|
if(NOT WIN32 AND NOT CMAKE_GENERATOR STREQUAL "Ninja")
|
|
list(APPEND ARGN
|
|
CMAKE_ARGS -DCMAKE_TARGET_MESSAGES=${CMAKE_TARGET_MESSAGES}
|
|
)
|
|
endif()
|
|
if(NOT WIN32)
|
|
list(APPEND ARGN
|
|
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
|
)
|
|
endif()
|
|
else()
|
|
list(APPEND ARGN
|
|
LOG_CONFIGURE 1
|
|
LOG_BUILD 1
|
|
LOG_INSTALL 1
|
|
)
|
|
endif()
|
|
|
|
add_custom_command(
|
|
TARGET clean-all
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DEPENDS_DIR}/${NAME}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET clean-depends
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DEPENDS_DIR}/${NAME}
|
|
)
|
|
|
|
# TODO
|
|
#
|
|
# As a post install step, we need to touch a file that states that the
|
|
# dependency has been compiled. If this is the case, we would then only
|
|
# run the install step, skipping the compile step. This should allow us
|
|
# to move the depends directory outside of the build tree and safely use
|
|
# it for future compilations.
|
|
#
|
|
|
|
ExternalProject_Add(
|
|
${NAME}_${PREFIX}
|
|
${ARGN}
|
|
PREFIX ${DEPENDS_DIR}/${NAME}/${PREFIX}
|
|
STAMP_DIR ${DEPENDS_DIR}/${NAME}/${PREFIX}/stamp
|
|
TMP_DIR ${DEPENDS_DIR}/${NAME}/${PREFIX}/tmp
|
|
BINARY_DIR ${DEPENDS_DIR}/${NAME}/${PREFIX}/build
|
|
SOURCE_DIR ${CACHE_DIR}/${NAME}
|
|
)
|
|
|
|
ExternalProject_Add_Step(
|
|
${NAME}_${PREFIX}
|
|
${NAME}_${PREFIX}_cleanup
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DEPENDS_DIR}/${NAME}/${PREFIX}/src
|
|
DEPENDEES configure
|
|
)
|
|
endfunction(add_dependency)
|
|
|
|
# Add Dependency Step
|
|
#
|
|
# Uses ExternalProject_Add_Step to add an additional step to external project
|
|
# add after "install" is executed by ExternalProject_Add. Only one additional
|
|
# step is supported. Like add_dependency, add_dependency_step passes all
|
|
# optional parameters to ExternalProject_Add_Step, so most options are
|
|
# supported.
|
|
#
|
|
# @param NAME the name of the dependency
|
|
# @param PREFIX the prefix this dependency belongs too. Valid values are:
|
|
# vmm, userspace and test.
|
|
#
|
|
function(add_dependency_step NAME PREFIX)
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(PREFIX ${VMM_PREFIX})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(PREFIX ${USERSPACE_PREFIX})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(PREFIX ${TEST_PREFIX})
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
|
|
ExternalProject_Add_Step(
|
|
${NAME}_${PREFIX}
|
|
step_${NAME}_${PREFIX}
|
|
${ARGN}
|
|
DEPENDEES install
|
|
)
|
|
endfunction(add_dependency_step)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_targets
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(add_format_targets NAME PREFIX SOURCE_DIR)
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(PREFIX ${VMM_PREFIX})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(PREFIX ${USERSPACE_PREFIX})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(PREFIX ${TEST_PREFIX})
|
|
endif()
|
|
|
|
if(NOT EXISTS "${SOURCE_DIR}")
|
|
return()
|
|
endif()
|
|
|
|
add_custom_command(
|
|
TARGET format
|
|
COMMAND ${ASTYLE_SCRIPT} ${USERSPACE_PREFIX_PATH}/bin/astyle diff ${SOURCE_DIR}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET format-all
|
|
COMMAND ${ASTYLE_SCRIPT} ${USERSPACE_PREFIX_PATH}/bin/astyle all ${SOURCE_DIR}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET format-${NAME}_${PREFIX}
|
|
COMMAND ${ASTYLE_SCRIPT} ${USERSPACE_PREFIX_PATH}/bin/astyle diff ${SOURCE_DIR}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET format-${NAME}_${PREFIX}-all
|
|
COMMAND ${ASTYLE_SCRIPT} ${USERSPACE_PREFIX_PATH}/bin/astyle all ${SOURCE_DIR}
|
|
)
|
|
endfunction(add_format_targets)
|
|
|
|
# Private
|
|
#
|
|
function(add_targets NAME PREFIX SOURCE_DIR)
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(FULLPREFIX ${VMM_PREFIX})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(FULLPREFIX ${USERSPACE_PREFIX})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(FULLPREFIX ${TEST_PREFIX})
|
|
elseif(PREFIX STREQUAL "none")
|
|
set(FULLPREFIX ${PREFIX})
|
|
endif()
|
|
|
|
if(NOT PREFIX STREQUAL "none")
|
|
add_custom_target(
|
|
clean-${NAME}_${FULLPREFIX}
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET clean-all
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET clean-subprojects
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}
|
|
)
|
|
|
|
add_custom_target(
|
|
rebuild-${NAME}_${FULLPREFIX}
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}
|
|
COMMAND ${CMAKE_COMMAND} --build . --target ${NAME}_${FULLPREFIX}
|
|
)
|
|
endif()
|
|
|
|
if(ENABLE_FORMAT)
|
|
add_custom_target(format-${NAME}_${FULLPREFIX})
|
|
add_custom_target(format-${NAME}_${FULLPREFIX}-all)
|
|
add_format_targets(${NAME} ${PREFIX} ${SOURCE_DIR})
|
|
endif()
|
|
|
|
if(PREFIX STREQUAL "test")
|
|
string(TOUPPER "TIDY_EXCLUSION_${NAME}" TIDY_EXCLUSION)
|
|
|
|
add_custom_command(
|
|
TARGET unittest
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
ctest --output-on-failure
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET test
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
ctest --output-on-failure
|
|
)
|
|
|
|
add_custom_target(
|
|
test-${NAME}_${FULLPREFIX}
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
ctest --output-on-failure
|
|
)
|
|
|
|
if(ENABLE_TIDY)
|
|
add_custom_command(
|
|
TARGET tidy
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
${TIDY_SCRIPT} diff ${SOURCE_DIR} ${${TIDY_EXCLUSION}}
|
|
)
|
|
|
|
add_custom_command(
|
|
TARGET tidy-all
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
${TIDY_SCRIPT} all ${SOURCE_DIR} ${${TIDY_EXCLUSION}}
|
|
)
|
|
|
|
add_custom_target(
|
|
tidy-${NAME}_${FULLPREFIX}
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
${TIDY_SCRIPT} diff ${SOURCE_DIR} ${${TIDY_EXCLUSION}}
|
|
)
|
|
|
|
add_custom_target(
|
|
tidy-${NAME}_${FULLPREFIX}-all
|
|
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/${NAME}/${FULLPREFIX}/build
|
|
${TIDY_SCRIPT} all ${SOURCE_DIR} ${${TIDY_EXCLUSION}}
|
|
)
|
|
endif()
|
|
endif()
|
|
endfunction(add_targets)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# right_justify
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(right_justify text width output)
|
|
set(str "")
|
|
string(LENGTH "${text}" text_len)
|
|
foreach(i RANGE ${text_len} ${width})
|
|
set(str " ${str}")
|
|
endforeach(i)
|
|
set(${output} ${str} PARENT_SCOPE)
|
|
endfunction(right_justify)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_custom_target_category
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(add_custom_target_category TEXT)
|
|
if(NOT WIN32)
|
|
add_custom_command(
|
|
TARGET info
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color " "
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --green "${TEXT}:"
|
|
)
|
|
endif()
|
|
endfunction(add_custom_target_category)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_custom_target_info
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(add_custom_target_info)
|
|
if(NOT WIN32)
|
|
set(oneVal TARGET COMMENT)
|
|
cmake_parse_arguments(ARG "" "${oneVal}" "" ${ARGN})
|
|
|
|
if(NOT_ARG_TARGET)
|
|
right_justify("${BUILD_COMMAND}" 20 JUSTIFY_STR)
|
|
add_custom_command(
|
|
TARGET info
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --yellow --no-newline " ${BUILD_COMMAND}"
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --no-newline "${JUSTIFY_STR}- "
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --white "${ARG_COMMENT}"
|
|
)
|
|
else()
|
|
right_justify("${BUILD_COMMAND} ${ARG_TARGET}" 20 JUSTIFY_STR)
|
|
add_custom_command(
|
|
TARGET info
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --yellow --no-newline " ${BUILD_COMMAND} ${ARG_TARGET}"
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --no-newline "${JUSTIFY_STR}- "
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --white "${ARG_COMMENT}"
|
|
)
|
|
endif()
|
|
endif()
|
|
endfunction(add_custom_target_info)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_subproject
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Add Sub Project
|
|
#
|
|
# Adds a Bareflank specific project to the build. Unlike dependencies,
|
|
# sub projects are checked for changes. This function is not only used
|
|
# internally by the main build system, but can also be used by extensions
|
|
# for adding additional logic to the hypervisor.
|
|
#
|
|
# @param NOBUILD Include the sub project, but don't build the code. This is
|
|
# mainly used to register targets for a given sub project, and the prefix
|
|
# is usually "none".
|
|
# @param NOINSTALL Skip the install step for the sub project
|
|
# @param
|
|
#
|
|
#
|
|
function(add_subproject NAME PREFIX)
|
|
set(options NOBUILD NOINSTALL)
|
|
set(oneVal SOURCE_DIR TOOLCHAIN)
|
|
set(multiVal C_FLAGS CXX_FLAGS DEPENDS)
|
|
cmake_parse_arguments(ARG "${options}" "${oneVal}" "${multiVal}" ${ARGN})
|
|
|
|
if(PREFIX STREQUAL "vmm" AND NOT ENABLE_BUILD_VMM AND NOT ENABLE_BUILD_TEST)
|
|
return()
|
|
endif()
|
|
|
|
if(PREFIX STREQUAL "userspace" AND NOT ENABLE_BUILD_USERSPACE)
|
|
return()
|
|
endif()
|
|
|
|
if(PREFIX STREQUAL "test" AND NOT ENABLE_BUILD_TEST)
|
|
return()
|
|
endif()
|
|
|
|
if(ARG_SOURCE_DIR)
|
|
set(SOURCE_DIR ${ARG_SOURCE_DIR})
|
|
else()
|
|
if(PREFIX STREQUAL "test")
|
|
set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/${NAME}/tests)
|
|
else()
|
|
set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/${NAME}/src)
|
|
endif()
|
|
endif()
|
|
|
|
add_targets(${NAME} ${PREFIX} ${SOURCE_DIR})
|
|
|
|
if(ENABLE_FORMAT)
|
|
if(NOT ARG_SOURCE_DIR AND NOT PREFIX STREQUAL "test")
|
|
add_format_targets(${NAME} ${PREFIX} ${CMAKE_CURRENT_LIST_DIR}/${NAME}/include)
|
|
endif()
|
|
endif()
|
|
|
|
if(ARG_NOBUILD)
|
|
return()
|
|
endif()
|
|
|
|
if(NOT ARG_TOOLCHAIN)
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(TOOLCHAIN ${VMM_TOOLCHAIN_PATH})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(TOOLCHAIN ${USERSPACE_TOOLCHAIN_PATH})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(TOOLCHAIN ${TEST_TOOLCHAIN_PATH})
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
else()
|
|
set(TOOLCHAIN ${ARG_TOOLCHAIN})
|
|
endif()
|
|
|
|
generate_flags(
|
|
${PREFIX}
|
|
C_FLAGS ${ARG_C_FLAGS}
|
|
CXX_FLAGS ${ARG_CXX_FLAGS}
|
|
)
|
|
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(PREFIX ${VMM_PREFIX})
|
|
elseif(PREFIX STREQUAL "userspace")
|
|
set(PREFIX ${USERSPACE_PREFIX})
|
|
elseif(PREFIX STREQUAL "test")
|
|
set(PREFIX ${TEST_PREFIX})
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${PREFIX}")
|
|
endif()
|
|
|
|
set(DEPENDS "")
|
|
foreach(d ${ARG_DEPENDS})
|
|
list(APPEND DEPENDS "${d}_${PREFIX}")
|
|
endforeach(d)
|
|
|
|
get_cmake_property(_vars CACHE_VARIABLES)
|
|
foreach (_var ${_vars})
|
|
STRING(REGEX MATCH "^CMAKE" is_cmake_var ${_var})
|
|
if(NOT is_cmake_var)
|
|
list(APPEND CMAKE_ARGS -D${_var}=${${_var}})
|
|
endif()
|
|
endforeach()
|
|
|
|
if(ENABLE_BUILD_TEST)
|
|
list(APPEND CMAKE_ARGS -DCMAKE_EXPORT_COMPILE_COMMANDS=ON)
|
|
endif()
|
|
|
|
list(APPEND CMAKE_ARGS
|
|
-DCMAKE_INSTALL_PREFIX=${PREFIXES_DIR}/${PREFIX}
|
|
-DCMAKE_INSTALL_MESSAGE=${CMAKE_INSTALL_MESSAGE}
|
|
-DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}
|
|
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN}
|
|
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
|
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
|
)
|
|
|
|
if(NOT WIN32 AND NOT CMAKE_GENERATOR STREQUAL "Ninja")
|
|
list(APPEND CMAKE_ARGS
|
|
-DCMAKE_TARGET_MESSAGES=${CMAKE_TARGET_MESSAGES}
|
|
)
|
|
endif()
|
|
if(NOT WIN32)
|
|
list(APPEND CMAKE_ARGS
|
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
|
)
|
|
endif()
|
|
|
|
if(ARG_NOINSTALL)
|
|
list(APPEND EPA_ARGS
|
|
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "-- Install step ignored"
|
|
)
|
|
endif()
|
|
|
|
ExternalProject_Add(
|
|
${NAME}_${PREFIX}
|
|
${EPA_ARGS}
|
|
PREFIX ${CMAKE_BINARY_DIR}/${NAME}/${PREFIX}
|
|
STAMP_DIR ${CMAKE_BINARY_DIR}/${NAME}/${PREFIX}/stamp
|
|
TMP_DIR ${CMAKE_BINARY_DIR}/${NAME}/${PREFIX}/tmp
|
|
BINARY_DIR ${CMAKE_BINARY_DIR}/${NAME}/${PREFIX}/build
|
|
SOURCE_DIR ${SOURCE_DIR}
|
|
CMAKE_ARGS ${CMAKE_ARGS}
|
|
DEPENDS ${DEPENDS}
|
|
UPDATE_COMMAND ${CMAKE_COMMAND} -E echo "-- checking for updates"
|
|
)
|
|
|
|
ExternalProject_Add_Step(
|
|
${NAME}_${PREFIX}
|
|
${NAME}_${PREFIX}_cleanup
|
|
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/${NAME}/${PREFIX}/src
|
|
DEPENDEES configure
|
|
)
|
|
endfunction(add_subproject)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Extensions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
function(vmm_extension NAME)
|
|
list(APPEND ARGN
|
|
DEPENDS bfvmm bfintrinsics
|
|
)
|
|
|
|
add_subproject(
|
|
${NAME} vmm
|
|
${ARGN}
|
|
)
|
|
endfunction(vmm_extension)
|
|
|
|
function(userspace_extension NAME)
|
|
add_subproject(
|
|
${NAME} userspace
|
|
)
|
|
endfunction(userspace_extension)
|
|
|
|
function(test_extension NAME)
|
|
add_subproject(
|
|
${NAME} test
|
|
${ARGN}
|
|
)
|
|
endfunction(test_extension)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# init_project
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
macro(enable_asm)
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "x86_64")
|
|
find_program(NASM_BIN nasm)
|
|
|
|
if(NOT NASM_BIN)
|
|
set(NASM_BIN "c:\\Program Files\\NASM\\nasm.exe")
|
|
if(NOT EXISTS ${NASM_BIN})
|
|
message(FATAL_ERROR "Unable to find nasm, or nasm is not installed")
|
|
endif()
|
|
endif()
|
|
|
|
execute_process(COMMAND ${NASM_BIN} -v OUTPUT_VARIABLE NASM_ID OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
set(CMAKE_ASM_NASM_COMPILER_ID ${NASM_ID})
|
|
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(CMAKE_ASM_NASM_OBJECT_FORMAT "elf64")
|
|
endif()
|
|
enable_language(ASM_NASM)
|
|
|
|
set(CMAKE_ASM_NASM_FLAGS "-d ${ABITYPE}")
|
|
set(CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY TRUE)
|
|
set(CMAKE_ASM_NASM_CREATE_STATIC_LIBRARY TRUE)
|
|
endif()
|
|
if(${BUILD_TARGET_ARCH} STREQUAL "aarch64")
|
|
message(WARNING "unimplemented")
|
|
endif()
|
|
endmacro(enable_asm)
|
|
|
|
# Init Project
|
|
#
|
|
# Initializes a sub project or extension. This function should be used right
|
|
# after running project(), and enables ASM, sets up include and library
|
|
# folders and addition flags.
|
|
#
|
|
# @param TIDY_EXCLUSIONS Exclusions for Clang Tidy
|
|
# @param C_FLAGS Additonal flags to add to CMAKE_C_FLAGS
|
|
# @param CXX_FLAGS Additonal flags to add to CMAKE_CXX_FLAGS
|
|
# @param INCLUDES Additional includes
|
|
#
|
|
macro(init_project)
|
|
set(multiVal C_FLAGS CXX_FLAGS INCLUDES)
|
|
cmake_parse_arguments(ARG "" "" "${multiVal}" ${ARGN})
|
|
|
|
if(CMAKE_INSTALL_PREFIX STREQUAL "${VMM_PREFIX_PATH}")
|
|
set(PREFIX "vmm")
|
|
elseif(CMAKE_INSTALL_PREFIX STREQUAL "${USERSPACE_PREFIX_PATH}")
|
|
set(PREFIX "userspace")
|
|
elseif(CMAKE_INSTALL_PREFIX STREQUAL "${TEST_PREFIX_PATH}")
|
|
set(PREFIX "test")
|
|
else()
|
|
message(FATAL_ERROR "Invalid prefix: ${CMAKE_INSTALL_PREFIX}")
|
|
endif()
|
|
message(STATUS "Prefix: ${CMAKE_INSTALL_PREFIX}")
|
|
|
|
if(PREFIX STREQUAL "vmm")
|
|
set(CMAKE_SKIP_RPATH TRUE)
|
|
endif()
|
|
|
|
if(PREFIX STREQUAL "test")
|
|
set(ENABLE_MOCKING ON)
|
|
set(CMAKE_BUILD_TYPE "Debug")
|
|
set(BUILD_STATIC_LIBS ON)
|
|
set(BUILD_SHARED_LIBS OFF)
|
|
endif()
|
|
|
|
enable_asm()
|
|
|
|
list(APPEND CMAKE_C_FLAGS ${ARG_C_FLAGS})
|
|
list(APPEND CMAKE_CXX_FLAGS ${ARG_CXX_FLAGS})
|
|
|
|
string(REPLACE ";" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
|
string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
|
|
include_directories(
|
|
${ARG_INCLUDES}
|
|
${SOURCE_BFSDK_DIR}/include
|
|
${SOURCE_BFELF_LOADER_DIR}/include
|
|
${SOURCE_BFINTRINSICS_DIR}/include
|
|
${CMAKE_CURRENT_LIST_DIR}
|
|
${CMAKE_CURRENT_LIST_DIR}/include
|
|
)
|
|
|
|
if(NOT PREFIX STREQUAL "vmm")
|
|
include_directories(
|
|
SYSTEM ${CMAKE_INSTALL_PREFIX}/include
|
|
)
|
|
endif()
|
|
|
|
link_directories(
|
|
${CMAKE_INSTALL_PREFIX}/lib
|
|
)
|
|
|
|
get_cmake_property(_vars CACHE_VARIABLES)
|
|
foreach (_var ${_vars})
|
|
set(${_var} ${${_var}})
|
|
endforeach()
|
|
endmacro(init_project)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# validate_build / invalid_config
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(validate_build)
|
|
if(BUILD_VALIDATOR_ERROR)
|
|
message(FATAL_ERROR "Build validation failed")
|
|
endif()
|
|
endfunction(validate_build)
|
|
|
|
# Invalidate Config
|
|
#
|
|
# Use this function to invalidate the configuration of the build. Unlike
|
|
# message(FATAL_ERROR), this function will queue up errors, and exit when
|
|
# the build is validated ensuring all errors are reported at once.
|
|
#
|
|
# @param MSG the message to report on error
|
|
#
|
|
macro(invalid_config MSG)
|
|
message(SEND_ERROR "${MSG}")
|
|
set(BUILD_VALIDATOR_ERROR ON)
|
|
endmacro(invalid_config)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_xxx_library
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Add Shared Library
|
|
#
|
|
# Creates a shared library, sets the appropriate defintions and dependencies
|
|
# and installs the library into the prefix
|
|
#
|
|
# @param NAME The name of the library. "_shared" is added for you
|
|
# @param ALWAYS Always compile this library regardless of BUILD_SHARED_LIBS
|
|
# @param SOURCES The source files for the library
|
|
# @param DEFINES The definitions to add to the library
|
|
# @param DEPENDS The dependency for the library. "_shared" is added for you
|
|
#
|
|
function(add_shared_library NAME)
|
|
set(options ALWAYS)
|
|
set(multiVal SOURCES DEFINES DEPENDS)
|
|
cmake_parse_arguments(ARG "${options}" "" "${multiVal}" ${ARGN})
|
|
|
|
if(NOT ARG_SOURCES)
|
|
return()
|
|
endif()
|
|
|
|
if(BUILD_SHARED_LIBS OR ARG_ALWAYS)
|
|
if(NOT ARG_SOURCES)
|
|
message(FATAL_ERROR "SOURCES must be defined when creating a library")
|
|
endif()
|
|
|
|
set(DEPENDS "")
|
|
foreach(d ${ARG_DEPENDS})
|
|
list(APPEND DEPENDS "${d}_shared")
|
|
endforeach(d)
|
|
|
|
add_library(${NAME}_shared SHARED ${ARG_SOURCES})
|
|
set_target_properties(${NAME}_shared PROPERTIES LINKER_LANGUAGE C)
|
|
target_compile_definitions(${NAME}_shared PRIVATE ${ARG_DEFINES})
|
|
target_link_libraries(${NAME}_shared ${DEPENDS})
|
|
install(TARGETS ${NAME}_shared DESTINATION lib)
|
|
endif()
|
|
endfunction(add_shared_library)
|
|
|
|
# Add Static Library
|
|
#
|
|
# Creates a static library, sets the appropriate defintions and dependencies
|
|
# and installs the library into the prefix
|
|
#
|
|
# @param NAME The name of the library. "_static" is added for you
|
|
# @param ALWAYS Always compile this library regardless of BUILD_STATIC_LIBS
|
|
# @param SOURCES The source files for the library
|
|
# @param DEFINES The definitions to add to the library
|
|
#
|
|
function(add_static_library NAME)
|
|
set(options ALWAYS)
|
|
set(multiVal SOURCES DEFINES)
|
|
cmake_parse_arguments(ARG "${options}" "" "${multiVal}" ${ARGN})
|
|
|
|
if(NOT ARG_SOURCES)
|
|
return()
|
|
endif()
|
|
|
|
if(BUILD_STATIC_LIBS OR ARG_ALWAYS)
|
|
if(NOT ARG_SOURCES)
|
|
message(FATAL_ERROR "SOURCES must be defined when creating a library")
|
|
endif()
|
|
|
|
add_library(${NAME}_static STATIC ${ARG_SOURCES})
|
|
set_target_properties(${NAME}_static PROPERTIES LINKER_LANGUAGE C)
|
|
target_compile_definitions(${NAME}_static PRIVATE ${ARG_DEFINES})
|
|
install(TARGETS ${NAME}_static DESTINATION lib)
|
|
endif()
|
|
endfunction(add_static_library)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# add_vmm
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Add VMM Executable
|
|
#
|
|
# Creates a VMM executable. Specifically, this takes a set of sources,
|
|
# compiles them, and then links the result to the provided libraries and
|
|
# installs the result into the VMM prefix.
|
|
#
|
|
# @param NOVMMLIBS Do not include the bfvmm libraries.
|
|
# @param LIBRARIES Additional libraries to link the new executable against.
|
|
# @param SOURCES Sources to compile for the executable. If this is left blank,
|
|
# a null.cpp file will be compiled for you.
|
|
# @param DEFINES Additional definitions to add to the executable
|
|
#
|
|
function(add_vmm_executable NAME)
|
|
set(options NOVMMLIBS)
|
|
set(multiVal LIBRARIES SOURCES DEFINES)
|
|
cmake_parse_arguments(ARG "${options}" "" "${multiVal}" ${ARGN})
|
|
|
|
if(NOT ARG_SOURCES)
|
|
if(NOT EXISTS ${CMAKE_BINARY_DIR}/null.cpp)
|
|
file(WRITE
|
|
${CMAKE_BINARY_DIR}/null.cpp ""
|
|
)
|
|
endif()
|
|
set(ARG_SOURCES ${CMAKE_BINARY_DIR}/null.cpp)
|
|
endif()
|
|
|
|
if(BUILD_SHARED_LIBS)
|
|
add_executable(${NAME}_shared ${ARG_SOURCES})
|
|
target_compile_definitions(${NAME}_shared PRIVATE ${ARG_DEFINES})
|
|
|
|
set(LIBRARIES "")
|
|
foreach(d ${ARG_LIBRARIES})
|
|
list(APPEND LIBRARIES "${CMAKE_INSTALL_PREFIX}/lib/lib${d}_shared.so")
|
|
endforeach(d)
|
|
|
|
if(NOT ARG_NOVMMLIBS)
|
|
list(APPEND LIBRARIES
|
|
--whole-archive ${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_entry_static.a --no-whole-archive
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_vcpu_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_hve_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_memory_manager_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_debug_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfintrinsics_shared.so
|
|
)
|
|
endif()
|
|
|
|
list(APPEND LIBRARIES
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc++.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc++abi.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfpthread_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfunwind_shared.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc.so
|
|
${CMAKE_INSTALL_PREFIX}/lib/libm.so
|
|
--whole-archive ${CMAKE_INSTALL_PREFIX}/lib/libbfcrt_static.a --no-whole-archive
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfsyscall_shared.so
|
|
)
|
|
|
|
target_link_libraries(${NAME}_shared ${LIBRARIES})
|
|
install(TARGETS ${NAME}_shared DESTINATION bin)
|
|
endif()
|
|
|
|
if(BUILD_STATIC_LIBS)
|
|
add_executable(${NAME}_static ${ARG_SOURCES})
|
|
target_compile_definitions(${NAME}_static PRIVATE ${ARG_DEFINES})
|
|
|
|
set(LIBRARIES "")
|
|
foreach(d ${ARG_LIBRARIES})
|
|
list(APPEND LIBRARIES "${CMAKE_INSTALL_PREFIX}/lib/lib${d}_static.a")
|
|
endforeach(d)
|
|
|
|
if(NOT ARG_NOVMMLIBS)
|
|
list(APPEND LIBRARIES
|
|
--whole-archive ${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_entry_static.a --no-whole-archive
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_vcpu_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_hve_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_memory_manager_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfvmm_debug_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfintrinsics_static.a
|
|
)
|
|
endif()
|
|
|
|
list(APPEND LIBRARIES
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc++.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc++abi.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfpthread_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfunwind_static.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libc.a
|
|
${CMAKE_INSTALL_PREFIX}/lib/libm.a
|
|
--whole-archive ${CMAKE_INSTALL_PREFIX}/lib/libbfcrt_static.a --no-whole-archive
|
|
${CMAKE_INSTALL_PREFIX}/lib/libbfsyscall_static.a
|
|
)
|
|
|
|
target_link_libraries(${NAME}_static ${LIBRARIES})
|
|
install(TARGETS ${NAME}_static DESTINATION bin)
|
|
endif()
|
|
endfunction(add_vmm_executable)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# set_bfm_vmm
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Set BFM VMM
|
|
#
|
|
# Sets the VMM that BFM will use when running "make load" or "make quick". This
|
|
# does not hard code the VMM into BFM. BFM must either be given the VMM to
|
|
# load, or an enviroment variable must be set.
|
|
#
|
|
# @param NAME The name of the VMM to load
|
|
# @param DEFAULT If the VMM has not yet been set, this default value will be
|
|
# used instead. This should not be used by extensions
|
|
#
|
|
macro(set_bfm_vmm NAME)
|
|
set(options DEFAULT)
|
|
cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
|
|
|
|
if(NOT ARG_DEFAULT OR (ARG_DEFAULT AND NOT BFM_VMM))
|
|
if(BUILD_SHARED_LIBS)
|
|
set(BFM_VMM "${NAME}_shared")
|
|
endif()
|
|
|
|
if(BUILD_STATIC_LIBS)
|
|
set(BFM_VMM "${NAME}_static")
|
|
endif()
|
|
endif()
|
|
endmacro(set_bfm_vmm)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# do_test
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Do Test
|
|
#
|
|
# Adds a unit test.
|
|
#
|
|
# @param FILENAME the file name of the test. Must start with "test_"
|
|
# @param DEFINES Additional definitions for the test
|
|
# @param DEPENDS Additional dependencies for the test. "_static" is added
|
|
# for you
|
|
# @param SOURCES The source files to use for the test. If this is not defined,
|
|
# the file used is ${FILENAME}.cpp. This is only needed if the test file
|
|
# is not in the same directory, allowing you to pass a source file with
|
|
# a directory. Nomrally FILENAME should still match the filename being
|
|
# used.
|
|
#
|
|
function(do_test FILENAME)
|
|
set(multiVal DEFINES DEPENDS SOURCES)
|
|
cmake_parse_arguments(ARG "" "" "${multiVal}" ${ARGN})
|
|
|
|
set(DEPENDS "")
|
|
foreach(d ${ARG_DEPENDS})
|
|
list(APPEND DEPENDS "${d}_static")
|
|
endforeach(d)
|
|
|
|
if(NOT ARG_SOURCES)
|
|
set(ARG_SOURCES "${FILENAME}.cpp")
|
|
endif()
|
|
|
|
string(REPLACE "test_" "" NAME "${FILENAME}")
|
|
|
|
add_executable(test_${NAME} ${ARG_SOURCES})
|
|
target_link_libraries(test_${NAME} ${DEPENDS} test_catch)
|
|
target_compile_definitions(test_${NAME} PRIVATE ${ARG_DEFINES})
|
|
add_test(test_${NAME} test_${NAME})
|
|
if(CYGWIN OR WIN32)
|
|
target_link_libraries(test_${NAME} setupapi)
|
|
endif()
|
|
endfunction(do_test)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# print_xxx
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private
|
|
#
|
|
function(print_banner)
|
|
message(STATUS "${BoldMagenta} ___ __ _ _ ${ColorReset}")
|
|
message(STATUS "${BoldMagenta} | _ ) __ _ _ _ ___ / _| |__ _ _ _ | |__${ColorReset}")
|
|
message(STATUS "${BoldMagenta} | _ \\/ _` | '_/ -_) _| / _` | ' \\| / /${ColorReset}")
|
|
message(STATUS "${BoldMagenta} |___/\\__,_|_| \\___|_| |_\\__,_|_||_|_\\_\\${ColorReset}")
|
|
message(STATUS "")
|
|
message(STATUS "${Green} Please give us a star on: ${White}https://github.com/Bareflank/hypervisor${ColorReset}")
|
|
message(STATUS "")
|
|
endfunction(print_banner)
|
|
|
|
# Private
|
|
#
|
|
function(print_usage)
|
|
message(STATUS "${Green} Bareflank is ready to build, usage:${ColorReset}")
|
|
message(STATUS "${Yellow} ${BUILD_COMMAND}${ColorReset}")
|
|
message(STATUS "")
|
|
|
|
if(NOT WIN32)
|
|
message(STATUS "${Green} For more build options:${ColorReset}")
|
|
message(STATUS "${Yellow} ${BUILD_COMMAND} info${ColorReset}")
|
|
message(STATUS "")
|
|
else()
|
|
message(STATUS "${Green} Additional build options:${ColorReset}")
|
|
message(STATUS "${Yellow} cmake --build . --target test${ColorReset}")
|
|
message(STATUS "${Yellow} cmake --build . --target clean-all${ColorReset}")
|
|
message(STATUS "")
|
|
endif()
|
|
endfunction(print_usage)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Helpers
|
|
# ------------------------------------------------------------------------------
|
|
|
|
function(git_dir_script)
|
|
if(NOT UNIX)
|
|
return()
|
|
endif()
|
|
if(NOT EXISTS "${BUILD_ROOT_DIR}/setup_git_dir.sh")
|
|
file(APPEND "${BUILD_ROOT_DIR}/setup_git_dir.sh" "export GIT_WORK_TREE=${SOURCE_ROOT_DIR}\n")
|
|
file(APPEND "${BUILD_ROOT_DIR}/setup_git_dir.sh" "export GIT_DIR=${SOURCE_ROOT_DIR}/.git\n")
|
|
execute_process(COMMAND chmod +x ${BUILD_ROOT_DIR}/setup_git_dir.sh)
|
|
endif()
|
|
endfunction()
|