469 lines
13 KiB
CMake
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()
|