wasm-bpf/runtime/cpp/CMakeLists.txt

469 lines
13 KiB
CMake

cmake_minimum_required(VERSION 3.15)
#
# Project details
#
project(
wasm-bpf
VERSION 0.1.0
LANGUAGES CXX C
)
#
# Set project options
#
include(cmake/StandardSettings.cmake)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
message(STATUS "Started CMake for ${PROJECT_NAME} v${PROJECT_VERSION}...\n")
if (UNIX)
add_compile_options("$<$<CONFIG:DEBUG>:-D_DEBUG>") #this will allow to use same _DEBUG macro available in both Linux as well as Windows - MSCV environment. Easy to put Debug specific code.
endif (UNIX)
#
# Setup alternative names
#
if(${PROJECT_NAME}_USE_ALT_NAMES)
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE)
else()
set(PROJECT_NAME_LOWERCASE ${PROJECT_NAME})
set(PROJECT_NAME_UPPERCASE ${PROJECT_NAME})
endif()
#
# Prevent building in the source directory
#
if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n")
endif()
#
# Enable package managers
#
# include(cmake/Conan.cmake)
# include(cmake/Vcpkg.cmake)
#
# Create library, setup header and source files
#
# Find all headers and implementation files
include(cmake/SourcesAndHeaders.cmake)
if(${PROJECT_NAME}_BUILD_EXECUTABLE)
add_executable(${PROJECT_NAME} ${exe_sources})
add_library(${PROJECT_NAME}_LIB ${headers} ${sources})
if(${PROJECT_NAME}_VERBOSE_OUTPUT)
verbose_message("Found the following sources:")
foreach(source IN LISTS exe_sources)
verbose_message("* ${source}")
endforeach()
endif()
if(${PROJECT_NAME}_ENABLE_UNIT_TESTING)
# add_library(${PROJECT_NAME}_LIB ${headers} ${sources})
if(${PROJECT_NAME}_VERBOSE_OUTPUT)
verbose_message("Found the following headers:")
foreach(header IN LISTS headers)
verbose_message("* ${header}")
endforeach()
endif()
endif()
elseif(${PROJECT_NAME}_BUILD_HEADERS_ONLY)
add_library(${PROJECT_NAME} INTERFACE)
if(${PROJECT_NAME}_VERBOSE_OUTPUT)
verbose_message("Found the following headers:")
foreach(header IN LIST headers)
verbose_message("* ${header}")
endforeach()
endif()
else()
add_library(
${PROJECT_NAME}
${headers}
${sources}
)
if(${PROJECT_NAME}_VERBOSE_OUTPUT)
verbose_message("Found the following sources:")
foreach(source IN LISTS sources)
verbose_message("* ${source}")
endforeach()
verbose_message("Found the following headers:")
foreach(header IN LISTS headers)
verbose_message("* ${header}")
endforeach()
endif()
endif()
set_target_properties(
${PROJECT_NAME}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}"
)
if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING)
set_target_properties(
${PROJECT_NAME}_LIB
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
OUTPUT_NAME ${PROJECT_NAME}
)
endif()
message(STATUS "Added all header and implementation files.\n")
#
# Set the project standard and warnings
#
if(${PROJECT_NAME}_BUILD_HEADERS_ONLY)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
else()
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING)
target_compile_features(${PROJECT_NAME}_LIB PUBLIC cxx_std_17)
endif()
endif()
include(cmake/CompilerWarnings.cmake)
set_project_warnings(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 17)
verbose_message("Applied compiler warnings. Using standard ${CMAKE_CXX_STANDARD}.\n")
#
# Model project dependencies
#
# For Windows, it is necessary to link with the MultiThreaded library.
# Depending on how the rest of the project's dependencies are linked, it might be necessary
# to change the line to statically link with the library.
#
# This is done as follows:
#
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
#
# On Linux and Mac this variable is ignored. If any issues rise from it, try commenting it out
# and letting CMake decide how to link with it.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
verbose_message("Successfully added all dependencies and linked against them.")
set(THIRD_PARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party)
# Tell cmake where to find BpfObject module
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
if (DEFINED LIBBPF_SOURCE_DIR)
verbose_message("Use libbpf source from ${LIBBPF_SOURCE_DIR}")
else()
set(LIBBPF_SOURCE_DIR ${THIRD_PARTY_DIR}/bpftool/libbpf/src)
endif()
# Build vendored libbpf
include(ExternalProject)
ExternalProject_Add(libbpf
PREFIX libbpf
SOURCE_DIR ${LIBBPF_SOURCE_DIR}
CONFIGURE_COMMAND ""
BUILD_COMMAND make
BUILD_STATIC_ONLY=1
OBJDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf
DESTDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf
INCLUDEDIR=
LIBDIR=
UAPIDIR=
install
BUILD_IN_SOURCE TRUE
INSTALL_COMMAND ""
STEP_TARGETS build
)
# Set BpfObject input parameters -- note this is usually not necessary unless
# you're in a highly vendored environment (like libbpf-bootstrap)
set(BPFOBJECT_BPFTOOL_EXE ${THIRD_PARTY_DIR}/bpftool/src/bpftool)
set(BPFOBJECT_VMLINUX_H ${THIRD_PARTY_DIR}/vmlinux/vmlinux.h)
set(LIBBPF_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/libbpf)
set(LIBBPF_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a)
find_package(BpfObject REQUIRED)
add_dependencies(${PROJECT_NAME} libbpf-build)
target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBBPF_LIBRARIES} -lelf -lz)
if(${PROJECT_NAME}_ENABLE_UNIT_TESTING)
target_link_libraries(
${PROJECT_NAME}_LIB
PUBLIC ${LIBBPF_LIBRARIES} -lelf -lz
)
endif()
# For Windows, it is necessary to link with the MultiThreaded library.
# Depending on how the rest of the project's dependencies are linked, it might be necessary
# to change the line to statically link with the library.
#
# This is done as follows:
#
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
#
# On Linux and Mac this variable is ignored. If any issues rise from it, try commenting it out
# and letting CMake decide how to link with it.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
verbose_message("Successfully added all dependencies and linked against them.")
set (WAMR_BUILD_PLATFORM "linux")
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_LIBC_BUILTIN 1)
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/wasm-micro-runtime)
if (NOT MSVC)
set (WAMR_BUILD_LIBC_WASI 1)
endif ()
if (NOT MSVC)
# linker flags
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
endif ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
endif ()
endif ()
# WAMR features switch
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "mips")
set (WAMR_BUILD_TARGET "MIPS")
elseif (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(ppc644|ppc64le)")
message(SEND_ERROR "Target platform 'POWERPC' not yet supported")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
else ()
message(SEND_ERROR "Unsupported build target platform!")
endif ()
endif ()
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
set_target_properties (${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
if (APPLE)
target_link_libraries (${PROJECT_NAME} PRIVATE vmlib -lm -ldl -lpthread)
else ()
target_link_libraries (${PROJECT_NAME} PRIVATE vmlib -lm -ldl -lpthread -lrt)
endif ()
#
# Set the build/user include directories
#
include_directories(INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/libbpf/include/uapi)
include_directories(SYSTEM INTERFACE ${third_party_headers})
include_directories(SYSTEM INTERFACE ${LIBBPF_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/bpftools)
# Allow usage of header files in the `src` directory, but only for utilities
if(${PROJECT_NAME}_BUILD_HEADERS_ONLY)
target_include_directories(
${PROJECT_NAME}
INTERFACE
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
else()
target_include_directories(
${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING)
target_include_directories(
${PROJECT_NAME}_LIB
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
endif()
endif()
message(STATUS "Finished setting up include directories.")
#
# Provide alias to library for
#
if(${PROJECT_NAME}_BUILD_EXECUTABLE)
add_executable(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
else()
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
endif()
verbose_message("Project is now aliased as ${PROJECT_NAME}::${PROJECT_NAME}.\n")
#
# Format the project using the `clang-format` target (i.e: cmake --build build --target clang-format)
#
add_clang_format_target()
#
# Install library for easy downstream inclusion
#
include(GNUInstallDirs)
install(
TARGETS
${PROJECT_NAME}
vmlib
EXPORT
${PROJECT_NAME}Targets
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION
${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION
${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION
include
PUBLIC_HEADER DESTINATION
include
)
install(
EXPORT
${PROJECT_NAME}Targets
FILE
${PROJECT_NAME}Targets.cmake
NAMESPACE
${PROJECT_NAME}::
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
#
# Add version header
#
configure_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/version.hpp.in
include/${PROJECT_NAME_LOWERCASE}/version.hpp
@ONLY
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME_LOWERCASE}/version.hpp
DESTINATION
include/${PROJECT_NAME_LOWERCASE}
)
#
# Install the `include` directory
#
install(
DIRECTORY
include/${PROJECT_NAME_LOWERCASE}
DESTINATION
include
)
verbose_message("Install targets successfully built. Install with `cmake --build <build_directory> --target install --config <build_config>`.")
#
# Quick `ConfigVersion.cmake` creation
#
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${PROJECT_NAME}ConfigVersion.cmake
VERSION
${PROJECT_VERSION}
COMPATIBILITY
SameMajorVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
#
# Generate export header if specified
#
if(${PROJECT_NAME}_GENERATE_EXPORT_HEADER)
include(GenerateExportHeader)
generate_export_header(${PROJECT_NAME})
install(
FILES
${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWERCASE}_export.h
DESTINATION
include
)
message(STATUS "Generated the export header `${PROJECT_NAME_LOWERCASE}_export.h` and installed it.")
endif()
message(STATUS "Finished building requirements for installing the package.\n")
#
# Unit testing setup
#
if(${PROJECT_NAME}_ENABLE_UNIT_TESTING)
enable_testing()
message(STATUS "Build unit tests for the project. Tests should always be found in the test folder\n")
add_subdirectory(test)
endif()