diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0eacbbe0..ea126914 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -12,6 +12,7 @@ jobs: github.event.pull_request.head.repo.full_name != github.repository strategy: matrix: + os: [ubuntu-24.04, macos-latest] BUILDTYPE: [Debug, Release] LIBLUA: - "5.4" @@ -19,6 +20,15 @@ jobs: - "5.2" - "5.1" - "luajit-v2.1" + exclude: + - os: macos-latest + LIBLUA: "5.4" + - os: macos-latest + LIBLUA: "5.3" + - os: macos-latest + LIBLUA: "5.2" + - os: macos-latest + LIBLUA: "5.1" include: - BUILDTYPE: Debug CMAKEFLAGS: -DCMAKE_BUILD_TYPE=Debug @@ -36,24 +46,47 @@ jobs: PACKAGES: libluajit-5.1-dev libluajit-5.1-2 luajit FLAVORFLAGS: -DLUAJIT_FRIENDLY_MODE=ON -DENABLE_LUAJIT=ON fail-fast: false - runs-on: ubuntu-24.04 + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - name: Disable processing triggers for man-db + if: runner.os == 'Linux' run: sudo apt-get remove --purge man-db - - name: Setup common packages + - name: Setup Linux packages + if: runner.os == 'Linux' run: sudo apt install -y clang-15 libclang-common-15-dev ${{ matrix.PACKAGES }} - - name: Running CMake + - name: Setup macOS packages + if: runner.os == 'macOS' + run: brew install llvm luajit cmake ninja + + - name: Running CMake (Linux) + if: runner.os == 'Linux' run: > cmake -S . -B build -G Ninja -DENABLE_TESTING=ON -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 ${{ matrix.CMAKEFLAGS }} ${{ matrix.FLAVORFLAGS }} + - name: Running CMake (macOS) + if: runner.os == 'macOS' + run: > + cmake -S . -B build -G Ninja + -DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang + -DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++ + -DLUA_INCLUDE_DIR=/opt/homebrew/include/luajit-2.1 + -DLUA_LIBRARIES=/opt/homebrew/lib/libluajit-5.1.dylib + -DLLVM_DIR=/opt/homebrew/opt/llvm/ + -DCMAKE_PREFIX_PATH=/opt/homebrew/Cellar/llvm/20.1.8/lib/cmake/llvm/ + ${{ matrix.CMAKEFLAGS }} + + - name: Setup tmate session + if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 + - name: Building - run: cmake --build build --parallel $(nproc) + run: cmake --build build --parallel - name: Testing run: cmake --build build --target test diff --git a/CHANGELOG.md b/CHANGELOG.md index 373488b9..543f9653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support Address and UndefinedBehaviour sanitizers. - Support LuaJIT metrics. - Support OSS Fuzz environment (#73). +- Support for building on macOS ARM64. ### Changed diff --git a/cmake/BuildLibSanitizers.cmake b/cmake/BuildLibSanitizers.cmake index 99baa6cd..50df41e2 100644 --- a/cmake/BuildLibSanitizers.cmake +++ b/cmake/BuildLibSanitizers.cmake @@ -31,28 +31,43 @@ macro(GEN_BUILD_TARGET name libsanitizer_path libfuzzer_path DEPENDS copy_libs_${name} ) + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(LINK_COMMAND ${CMAKE_C_COMPILER} -Wl,-force_load,${libfuzzer_name} + -Wl,-force_load,${libsanitizer_name} -lstdc++ -lc++ -lpthread + -dynamiclib -o ${sanitizer_dso_name}) + else() + set(LINK_COMMAND ${CMAKE_C_COMPILER} -Wl,--whole-archive ${libfuzzer_name} + ${libsanitizer_name} -Wl,--no-whole-archive -lstdc++ -lpthread -ldl + -shared -o ${sanitizer_dso_name}) + endif() add_custom_target(build_dso_${name} ALL COMMENT "Build sanitizer library ${name}" - COMMAND ${CMAKE_C_COMPILER} -Wl,--whole-archive ${libfuzzer_name} - ${libsanitizer_name} -Wl,--no-whole-archive -lstdc++ -lpthread -ldl - -shared -o ${sanitizer_dso_name} + COMMAND ${LINK_COMMAND} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} BYPRODUCTS ${sanitizer_dso_name} - DEPENDS strip_lib_${name} ) + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") + add_dependencies(build_dso_${name} strip_lib_${name}) + else() + add_dependencies(build_dso_${name} copy_libs_${name}) + endif() endmacro() -list(APPEND LIBCLANG_ASAN_STRIP - asan_preinit.cc.o - asan_preinit.cpp.o -) -list(APPEND LIBCLANG_UBSAN_STRIP - ubsan_init_standalone_preinit.cc.o - ubsan_init_standalone_preinit.cpp.o -) +set(LIBCLANG_ASAN_STRIP "") +set(LIBCLANG_UBSAN_STRIP "") +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND LIBCLANG_ASAN_STRIP + asan_preinit.cc.o + asan_preinit.cpp.o + ) + list(APPEND LIBCLANG_UBSAN_STRIP + ubsan_init_standalone_preinit.cc.o + ubsan_init_standalone_preinit.cpp.o + ) +endif() -set(ASAN_DSO "libfuzzer_with_asan.so") -set(UBSAN_DSO "libfuzzer_with_ubsan.so") +set(ASAN_DSO "libfuzzer_with_asan${CMAKE_SHARED_LIBRARY_SUFFIX}") +set(UBSAN_DSO "libfuzzer_with_ubsan${CMAKE_SHARED_LIBRARY_SUFFIX}") GEN_BUILD_TARGET("asan" ${LIBCLANG_ASAN_LIB} diff --git a/cmake/SetClangRTLib.cmake b/cmake/SetClangRTLib.cmake index 0ab150fe..09782e9d 100644 --- a/cmake/SetClangRTLib.cmake +++ b/cmake/SetClangRTLib.cmake @@ -2,7 +2,11 @@ function(SetHwArchString outvar) if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(hw_arch "i386") elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(hw_arch "x86_64") + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") + set(hw_arch "arm64") + else() + set(hw_arch "x86_64") + endif() else () message(FATAL_ERROR "Unsupported architecture.") endif () diff --git a/luzer/CMakeLists.txt b/luzer/CMakeLists.txt index 5ed24753..ee5fc8dd 100644 --- a/luzer/CMakeLists.txt +++ b/luzer/CMakeLists.txt @@ -12,11 +12,14 @@ endif() set(LIBCLANG_ASAN_NAME "libclang_rt.asan-${ARCH}.a") set(LIBCLANG_UBSAN_NAME "libclang_rt.ubsan_standalone-${ARCH}.a") -# Sanitizers libraries in the OSS Fuzz environment have different -# names. +# Sanitizers libraries in the OSS Fuzz environment and macOS have +# different names. if (DEFINED ENV{OSS_FUZZ}) set(LIBCLANG_ASAN_NAME "libclang_rt.asan.a") set(LIBCLANG_UBSAN_NAME "libclang_rt.ubsan_standalone.a") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(LIBCLANG_ASAN_NAME "libclang_rt.asan_abi_osx.a") + set(LIBCLANG_UBSAN_NAME "libclang_rt.ubsan_minimal_osx.a") endif() SetClangLibPath(${LIBCLANG_ASAN_NAME} LIBCLANG_ASAN_LIB) SetClangLibPath(${LIBCLANG_UBSAN_NAME} LIBCLANG_UBSAN_LIB) @@ -35,14 +38,17 @@ add_compile_options( -fPIC -pedantic -Wall - -Werror -Wextra -Wno-unused-parameter -Wpedantic ) -if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND + NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_compile_options(-D_FORTIFY_SOURCE=2) endif() +if(ENABLE_TESTING) + # add_compile_options(-Werror) +endif() set(LUZER_SOURCES luzer.c compat.c @@ -90,7 +96,7 @@ install( TARGETS luzer_impl LIBRARY DESTINATION "${CMAKE_LIBDIR}/" - RENAME luzer.so + RENAME luzer${CMAKE_SHARED_LIBRARY_SUFFIX} ) install( diff --git a/luzer/luzer.c b/luzer/luzer.c index 734e02d8..f116b30d 100644 --- a/luzer/luzer.c +++ b/luzer/luzer.c @@ -20,7 +20,11 @@ #include #include #include +#ifdef __linux__ #include +#else +#include +#endif #include "fuzzed_data_provider.h" #include "counters.h" diff --git a/luzer/tests/CMakeLists.txt b/luzer/tests/CMakeLists.txt index 3be95190..5f02f65d 100644 --- a/luzer/tests/CMakeLists.txt +++ b/luzer/tests/CMakeLists.txt @@ -2,7 +2,7 @@ include(MakeLuaPath) make_lua_path(LUA_CPATH PATHS - ${PROJECT_BINARY_DIR}/luzer/?.so + ${PROJECT_BINARY_DIR}/luzer/?${CMAKE_SHARED_LIBRARY_SUFFIX} ) make_lua_path(LUA_PATH @@ -282,25 +282,25 @@ list(APPEND TEST_ENV ) if (LUA_HAS_JIT) generate_ffi_test(luzer_ffi - "${TEST_ENV};FFI_LIB_NAME=testlib.so" + "${TEST_ENV};FFI_LIB_NAME=testlib${CMAKE_SHARED_LIBRARY_SUFFIX}" "Done 10 runs in 0 second" ) # XXX: Memory leak in FDP is expected, should be fixed in [1]. # 1. https://github.com/ligurio/luzer/issues/52 generate_ffi_test(luzer_ffi_asan - "${TEST_ENV};LD_PRELOAD=${ASAN_DSO_PATH};FFI_LIB_NAME=testlib_asan.so" + "${TEST_ENV};LD_PRELOAD=${ASAN_DSO_PATH};FFI_LIB_NAME=testlib_asan${CMAKE_SHARED_LIBRARY_SUFFIX}" "LeakSanitizer: detected memory leaks" ) generate_ffi_test(luzer_ffi_ubsan - "${TEST_ENV};LD_PRELOAD=${UBSAN_DSO_PATH};FFI_LIB_NAME=testlib_ubsan.so" + "${TEST_ENV};LD_PRELOAD=${UBSAN_DSO_PATH};FFI_LIB_NAME=testlib_ubsan${CMAKE_SHARED_LIBRARY_SUFFIX}" "Done 10 runs in 0 second" ) generate_ffi_test(luzer_ffi_asan_heap_overflow - "${TEST_ENV};LD_PRELOAD=${ASAN_DSO_PATH};FFI_LIB_NAME=testlib_asan.so;ERR_INJECTION=HEAP_BUFFER_OVERFLOW" + "${TEST_ENV};LD_PRELOAD=${ASAN_DSO_PATH};FFI_LIB_NAME=testlib_asan${CMAKE_SHARED_LIBRARY_SUFFIX};ERR_INJECTION=HEAP_BUFFER_OVERFLOW" "AddressSanitizer: heap-buffer-overflow" ) generate_ffi_test(luzer_ffi_ubsan_null_pointer_deref - "${TEST_ENV};LD_PRELOAD=${UBSAN_DSO_PATH};FFI_LIB_NAME=testlib_ubsan.so;ERR_INJECTION=NULL_POINTER_DEREF" + "${TEST_ENV};LD_PRELOAD=${UBSAN_DSO_PATH};FFI_LIB_NAME=testlib_ubsan${CMAKE_SHARED_LIBRARY_SUFFIX};ERR_INJECTION=NULL_POINTER_DEREF" "runtime error: load of null pointer of type" ) endif()