include(ProcessorCount) find_package(Git REQUIRED) enable_testing() # Tests samples # ============= set(SAMPLES_GIT_URL "https://github.com/lief-project/samples.git" CACHE STRING "URL to tests samples") set(SAMPLES_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/lief-samples") set(SAMPLES_TAG master) ExternalProject_Add(lief_samples PREFIX ${SAMPLES_PREFIX} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" GIT_REPOSITORY ${SAMPLES_GIT_URL} GIT_SHALLOW 1 GIT_TAG ${SAMPLES_TAG} UPDATE_COMMAND ${GIT_EXECUTABLE} pull ) ExternalProject_Get_Property(lief_samples source_dir) set(LIEF_SAMPLES_DIRECTORY "${source_dir}" CACHE INTERNAL "Path to LIEF samples") message(STATUS "Samples directory: ${LIEF_SAMPLES_DIRECTORY}") # Tests options # ============= if (NOT LIEF_ELF OR NOT LIEF_PE OR NOT LIEF_MACHO) message(FATAL_ERROR "Tests require all LIEF's modules activated" ) endif() set(LIEF_EXAMPLES_DIRECTORY "${PROJECT_SOURCE_DIR}/examples") set(LIEF_EXAMPLES_BINARY_DIR "${PROJECT_BINARY_DIR}/examples") #set(LIEF_SAMPLES_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/samples") if (MSVC) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/utils.py.in" "${PROJECT_BINARY_DIR}/api/python/utils.py" @ONLY) else() configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/utils.py.in" "${PROJECT_BINARY_DIR}/api/python/utils.py" @ONLY) endif() add_definitions(-DPATH_TO_CONFIG="${CMAKE_CURRENT_BINARY_DIR}") add_definitions(-DPATH_TO_SAMPLES="${LIEF_SAMPLES_DIRECTORY}") # Catch # ===== set(CATCH_VERSION 2.2.3) set(CATCH_SHA256 SHA256=46606cb0eae047a4a5f70f0794244d26c51f72e695b52f4f11c54ea1d1421360) set(CATCH_URL "${THIRD_PARTY_DIRECTORY}/Catch2-${CATCH_VERSION}.zip" CACHE STRING "URL to the Catch repo") ExternalProject_Add(catch PREFIX ${CATCH_PREFIX} URL ${CATCH_URL} URL_HASH ${CATCH_SHA256} TIMEOUT 10 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" LOG_DOWNLOAD ON ) ExternalProject_Get_Property(catch source_dir) set(CATCH_INCLUDE_DIR "${source_dir}" CACHE INTERNAL "Path to include folder for Catch") # Code covergage # ============== if(LIEF_COVERAGE) find_program(GCOV_PATH gcov) find_program(LCOV_PATH lcov) find_program(GENHTML_PATH genhtml) find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests) set(output_name "lief_coverage") set(coverage_info "${CMAKE_BINARY_DIR}/${output_name}.info") set(coverage_cleaned "${coverage_info}.cleaned") add_custom_target(lief_coverage # Cleanup lcov ${LCOV_PATH} --zerocounters --directory . # Run tests COMMAND make check-lief #COMMAND ctest -R test_iterators # Capturing lcov counters and generating report COMMAND ${LCOV_PATH} --directory . --capture --output-file ${coverage_info} COMMAND ${LCOV_PATH} --remove ${coverage_info} 'utf8/*' 'filesystem/*' 'libjson/*' 'tests/*' '/usr/*' 'pybind11/*' '*mbedtls*' rang_cpp_color/* easyloggingpp/* -output-file ${coverage_cleaned} COMMAND ${GENHTML_PATH} -o ${output_name} ${coverage_cleaned} #COMMAND ${CMAKE_COMMAND} -E remove ${coverage_info} ${coverage_cleaned} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) endif() # Fuzzing # ======= if(UNIX AND NOT APPLE) set(MELKOR_VERSION 1d62ccc) # From the fork: https://github.com/romainthomas/elf_fuzzer set(MELKOR_SHA256 SHA256=2653d4ec1dca51621757e6946f4af18fcd100f905183a4692b68ad0cd65392ba) set(MELKOR_URL "${THIRD_PARTY_DIRECTORY}/Melkor_ELF_Fuzzer-${MELKOR_VERSION}.zip" CACHE STRING "URL to the Melkor package") set(MELKOR_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/Melkor") set(MELKOR_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/Melkor") ExternalProject_Add(MELKOR PREFIX ${MELKOR_PREFIX} URL ${MELKOR_URL} URL_HASH ${MELKOR_SHA256} INSTALL_DIR ${MELKOR_INSTALL_DIR} UPDATE_COMMAND "" CONFIGURE_COMMAND "" INSTALL_COMMAND "" BUILD_COMMAND make clean && make BUILD_IN_SOURCE ON) ExternalProject_get_property(MELKOR SOURCE_DIR) set(MELKOR_BINARY "${SOURCE_DIR}/melkor") message(STATUS "${MELKOR_BINARY}") endif() # Tests # ===== add_executable(test_iterators "${CMAKE_CURRENT_SOURCE_DIR}/test_iterators.cpp") if (MSVC) target_compile_options(test_iterators PUBLIC /FIiso646.h) set_property(TARGET test_iterators PROPERTY LINK_FLAGS /NODEFAULTLIB:MSVCRT) endif() set_target_properties( test_iterators PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) target_include_directories(test_iterators PUBLIC $ ${CATCH_INCLUDE_DIR}) if (LIEF_COVERAGE) target_compile_options(test_iterators PRIVATE -g -O0 --coverage -fprofile-arcs -ftest-coverage) target_link_libraries(test_iterators gcov) endif() add_dependencies(test_iterators catch LIB_LIEF) target_link_libraries(test_iterators LIB_LIEF) add_test(test_iterators ${CMAKE_CURRENT_BINARY_DIR}/test_iterators) # Python # ====== if(WIN32) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/run_python_test.bat.in" "${CMAKE_CURRENT_BINARY_DIR}/run_python_test.bat" @ONLY) endif() macro(ADD_PYTHON_TEST name command) if(UNIX) add_test(${name} "bash" "-c" "PYTHONPATH=\"${PROJECT_BINARY_DIR}/api/python:${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\" ${command} ${ARGN}") endif() if(WIN32) add_test(${name} "${PROJECT_BINARY_DIR}/tests/run_python_test.bat" "${command}" "${ARGN}") endif() endmacro() if (LIEF_PYTHON_API) set(PYTHON_TESTS_ENABLED OFF) get_target_property(PYTHON_VERSION pyLIEF PYTHON_VERSION) find_package(PythonInterp ${PYTHON_VERSION}) message(STATUS "Python executable: ${PYTHON_EXECUTABLE}") if (PYTHONINTERP_FOUND) set(PYTHON_TESTS_ENABLED ON) endif() if (PYTHON_TESTS_ENABLED) # nm # -- ADD_PYTHON_TEST(EXAMPLE_PYTHON_nm_elf ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/nm.py \ ${LIEF_SAMPLES_DIRECTORY}/MachO/MachO64_x86-64_binary_ls.bin") ADD_PYTHON_TEST(EXAMPLE_PYTHON_nm_pe ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/nm.py \ ${LIEF_SAMPLES_DIRECTORY}/PE/PE32_x86_binary_winhello-mingw.exe") ADD_PYTHON_TEST(EXAMPLE_PYTHON_nm_macho ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/nm.py \ ${LIEF_SAMPLES_DIRECTORY}/ELF/ELF32_ARM_binary_ls.bin") # Abstract # -------- ADD_PYTHON_TEST(EXAMPLE_PYTHON_abstract_reader_pe ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/abstract_reader.py \ ${LIEF_SAMPLES_DIRECTORY}/PE/PE32_x86_binary_cmd-upx.exe") ADD_PYTHON_TEST(EXAMPLE_PYTHON_abstract_reader_elf ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/abstract_reader.py \ ${LIEF_SAMPLES_DIRECTORY}/ELF/ELF32_ARM_binary_ls.bin") ADD_PYTHON_TEST(EXAMPLE_PYTHON_abstract_reader_macho ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/abstract_reader.py \ ${LIEF_SAMPLES_DIRECTORY}/MachO/MachO64_x86-64_binary_id.bin") ADD_PYTHON_TEST(EXAMPLE_PYTHON_abstract_json ${PYTHON_EXECUTABLE} "${LIEF_EXAMPLES_DIRECTORY}/python/abstract_json.py \ ${LIEF_SAMPLES_DIRECTORY}/ELF/ELF64_x86-64_binary_ls.bin") ADD_PYTHON_TEST(UNITTEST_PYTHON_abstract ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/abstract/abstract_tests.py") endif() endif() add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/elf") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/vdex") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/art") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/dex") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/oat") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/pe") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/macho") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/api") # /!\ Bad Hack /!\ add_dependencies(LIB_LIEF lief_samples) ProcessorCount(N) if(N EQUAL 0) set(N 1) endif() if (CMAKE_CONFIGURATION_TYPES) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --output-on-failure --build-config "$") else() add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --output-on-failure) endif() if (CMAKE_CONFIGURATION_TYPES) add_custom_target(check-lief COMMAND ${CMAKE_CTEST_COMMAND} --parallel 1 --output-on-failure --build-config "$" DEPENDS lief_samples) else() add_custom_target(check-lief COMMAND ${CMAKE_CTEST_COMMAND} --parallel 1 --output-on-failure DEPENDS lief_samples) endif()