Skip to content

Commit

Permalink
Refactor build system
Browse files Browse the repository at this point in the history
1. switch to cmake for better control of build
2. add compile-time static-analysis
3. add support for santization
  • Loading branch information
JayKickliter committed Jun 8, 2020
1 parent 3cc7531 commit bfee0de
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 142 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

ci:
runs-on: ubuntu-latest
container: madninja/builder-erlang:1
container: madninja/builder-erlang:2

steps:
- uses: actions/checkout@v2
Expand Down
102 changes: 102 additions & 0 deletions c_src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
##########################################################################
# Project Setup #
##########################################################################
cmake_minimum_required(VERSION 3.3)
project(ErlangErasure C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 99)

list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake)
include(ASan)

IF (APPLE)
set(CMAKE_MODULE_LINKER_FLAGS "-flat_namespace -undefined suppress")
set(CMAKE_MACOSX_RPATH 1)
ENDIF()

#
# Enable sanitization if environment variable is set
#
# Truth Table
#
# +----------------------+-------------------------+------------------+
# | SANITIZE_ERLANG_NIFS | SANITIZE_ERLANG_ERASURE | Enable santizer? |
# +----------------------+-------------------------+------------------+
# | undefined | undefined | 0 |
# | 1 | undefined | 1 |
# | don't care | 1 | 1 |
# | don't care | 0 | 0 |
# +----------------------+-------------------------+------------------+
#
if(DEFINED ENV{SANITIZE_ERLANG_ERASURE})
if($ENV{SANITIZE_ERLANG_ERASURE})
set(CMAKE_BUILD_TYPE ASan CACHE STRING "Choose the type of build." FORCE)
else()
unset(CMAKE_BUILD_TYPE CACHE)
endif()
elseif(DEFINED ENV{SANITIZE_ERLANG_NIFS})
if($ENV{SANITIZE_ERLANG_NIFS})
set(CMAKE_BUILD_TYPE ASan CACHE STRING "Choose the type of build." FORCE)
else()
unset(CMAKE_BUILD_TYPE CACHE)
endif($ENV{SANITIZE_ERLANG_NIFS})
endif()

#
# Set a default build type if none was specified
#
set(default_build_type "Release")

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
endif()


##########################################################################
# Static Analysis #
##########################################################################
if(CMAKE_VERSION VERSION_GREATER 3.9)
find_program(CPPCHECK
NAMES cppcheck
DOC "Path to cppcheck executable"
)
if(CPPCHECK)
message(STATUS "Found cppcheck: ${CPPCHECK}")
set(CMAKE_C_CPPCHECK ${CPPCHECK}
--enable=all
--inline-suppr
--inconclusive
--quiet
--std=c${CMAKE_C_STANDARD}
--suppress=missingInclude
--template=gcc
)
endif(CPPCHECK)
endif()

if(CMAKE_VERSION VERSION_GREATER 3.5)
find_program(CLANG_TIDY
NAMES clang-tidy
DOC "Path to clang-tidy executable"
)
if(CLANG_TIDY)
message(STATUS "Found clang-tidy: ${CLANG_TIDY}")
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY}")
endif(CLANG_TIDY)
endif()


##########################################################################
# NIF #
##########################################################################
find_package(Erlang REQUIRED)
find_package(Jerasure REQUIRED)
add_library(erasure MODULE erasure.c)
target_link_libraries(erasure
PRIVATE
Erlang::Erlang
Jerasure::Jerasure
)

install(TARGETS erasure DESTINATION ${CMAKE_SOURCE_DIR}/../priv)
78 changes: 0 additions & 78 deletions c_src/Makefile

This file was deleted.

8 changes: 8 additions & 0 deletions c_src/cmake/ASan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file provides a custom build type, `CMAKE_BUILD_TYPE_ASAN`

set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=address -fno-omit-frame-pointer -fno-common" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=address -fno-omit-frame-pointer -fno-common" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_ASAN "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=address" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_ASAN "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=address" CACHE STRING "" FORCE)

set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "ASan")
140 changes: 140 additions & 0 deletions c_src/cmake/FindErlang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
FindErlang
-------
Finds Erlang libraries.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``Erlang::Erlang``
Header only interface library suitible for compiling NIFs.
``Erlang::EI``
Erlang interface library.
``Erlang::ERTS``
Erlang runtime system library.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Erlang_FOUND``
True if the system has the Erlang library.
``Erlang_RUNTIME``
The path to the Erlang runtime.
``Erlang_COMPILE``
The path to the Erlang compiler.
``Erlang_EI_PATH``
The path to the Erlang erl_interface path.
``Erlang_ERTS_PATH``
The path to the Erlang erts path.
``Erlang_EI_INCLUDE_DIRS``
/include appended to Erlang_EI_PATH.
``Erlang_EI_LIBRARY_PATH``
/lib appended to Erlang_EI_PATH.
``Erlang_ERTS_INCLUDE_DIRS``
/include appended to Erlang_ERTS_PATH.
``Erlang_ERTS_LIBRARY_PATH``
/lib appended to Erlang_ERTS_PATH.
#]=======================================================================]
include(FindPackageHandleStandardArgs)

SET(Erlang_BIN_PATH
$ENV{ERLANG_HOME}/bin
/opt/bin
/sw/bin
/usr/bin
/usr/local/bin
/opt/local/bin
)

FIND_PROGRAM(Erlang_RUNTIME
NAMES erl
PATHS ${Erlang_BIN_PATH}
)

FIND_PROGRAM(Erlang_COMPILE
NAMES erlc
PATHS ${Erlang_BIN_PATH}
)

EXECUTE_PROCESS(
COMMAND erl -noshell -eval "io:format(\"~s\", [code:lib_dir()])" -s erlang halt
OUTPUT_VARIABLE Erlang_OTP_LIB_DIR
)

EXECUTE_PROCESS(
COMMAND erl -noshell -eval "io:format(\"~s\", [code:root_dir()])" -s erlang halt
OUTPUT_VARIABLE Erlang_OTP_ROOT_DIR
)

EXECUTE_PROCESS(
COMMAND erl -noshell -eval "io:format(\"~s\",[filename:basename(code:lib_dir('erl_interface'))])" -s erlang halt
OUTPUT_VARIABLE Erlang_EI_DIR
)

EXECUTE_PROCESS(
COMMAND erl -noshell -eval "io:format(\"~s\",[filename:basename(code:lib_dir('erts'))])" -s erlang halt
OUTPUT_VARIABLE Erlang_ERTS_DIR
)

SET(Erlang_EI_PATH ${Erlang_OTP_LIB_DIR}/${Erlang_EI_DIR})
SET(Erlang_EI_INCLUDE_DIRS ${Erlang_OTP_LIB_DIR}/${Erlang_EI_DIR}/include)
SET(Erlang_EI_LIBRARY_PATH ${Erlang_OTP_LIB_DIR}/${Erlang_EI_DIR}/lib)

SET(Erlang_ERTS_PATH ${Erlang_OTP_ROOT_DIR}/${Erlang_ERTS_DIR})
SET(Erlang_ERTS_INCLUDE_DIRS ${Erlang_OTP_ROOT_DIR}/${Erlang_ERTS_DIR}/include)
SET(Erlang_ERTS_LIBRARY_PATH ${Erlang_OTP_ROOT_DIR}/${Erlang_ERTS_DIR}/lib)

FIND_PACKAGE_HANDLE_STANDARD_ARGS(
Erlang
DEFAULT_MSG
Erlang_RUNTIME
Erlang_COMPILE
Erlang_OTP_LIB_DIR
Erlang_OTP_ROOT_DIR
Erlang_EI_DIR
Erlang_ERTS_DIR
)

if(Erlang_FOUND)
if(NOT TARGET Erlang::Erlang)
add_library(Erlang::Erlang INTERFACE IMPORTED)
set_target_properties(Erlang::Erlang
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${Erlang_OTP_ROOT_DIR}/usr/include
)
endif()

if(NOT TARGET Erlang::ERTS)
add_library(Erlang::ERTS STATIC IMPORTED)
set_target_properties(Erlang::ERTS
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${Erlang_ERTS_INCLUDE_DIRS}
IMPORTED_LOCATION ${Erlang_ERTS_LIBRARY_PATH}/liberts.a
)
endif()

if(NOT TARGET Erlang::EI)
add_library(erlang_ei STATIC IMPORTED)
set_property(TARGET erlang_ei PROPERTY
IMPORTED_LOCATION ${Erlang_EI_LIBRARY_PATH}/libei.a
)
add_library(Erlang::EI INTERFACE IMPORTED)
set_property(TARGET Erlang::EI PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${Erlang_EI_INCLUDE_DIRS}
)
set_property(TARGET Erlang::EI PROPERTY
INTERFACE_LINK_LIBRARIES erlang_ei
)
endif()
endif(Erlang_FOUND)
33 changes: 33 additions & 0 deletions c_src/cmake/FindGFComplete.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
include(ExternalProject)

# get an uppercase version of the build type, for extracting build_type specific flags
if(CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_UC)
endif()

ExternalProject_Add(gf-complete
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gf-complete
GIT_REPOSITORY https://github.com/ceph/gf-complete.git
GIT_TAG a6862d10c9db467148f20eef2c6445ac9afd94d8
UPDATE_COMMAND ""
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND autoreconf --install > /dev/null 2>&1 || autoreconf &&
./configure
--prefix=${CMAKE_CURRENT_BINARY_DIR}
--with-pic
--disable-shared
$ENV{CONFIGURE_ARGS}
CC=${CMAKE_C_COMPILER}
CFLAGS=${CMAKE_C_FLAGS_${BUILD_TYPE_UC}}
BUILD_COMMAND make -j
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/lib/libgf_complete.a
INSTALL_COMMAND make install
)

add_library(GFComplete::GFComplete STATIC IMPORTED)
set_target_properties(GFComplete::GFComplete
PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/libgf_complete.a
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/include
)
add_dependencies(GFComplete::GFComplete gf-complete)
Loading

0 comments on commit bfee0de

Please sign in to comment.