diff --git a/CMake/32bit.cmake b/CMake/32bit.cmake deleted file mode 100644 index 4b88ca3cc..000000000 --- a/CMake/32bit.cmake +++ /dev/null @@ -1,25 +0,0 @@ -message(STATUS "Using 32-bit toolchain") - -set(CMAKE_CXX_FLAGS -m32 CACHE STRING "") - -# Affects pkg-config -set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) -# Used by pkg-config on Debian -set(CMAKE_LIBRARY_ARCHITECTURE i386-linux-gnu) -# Silly hack required to get the pkg-config path code to activate -list(APPEND CMAKE_PREFIX_PATH /usr) - -# Find where 32-bit CMake modules are stored -find_path(DIR NAMES cmake PATHS /usr/lib32 /usr/lib/i386-linux-gnu NO_DEFAULT_PATH) - -if(DIR) - message(STATUS "Using 32-bit libraries from ${DIR}") - # Read CMake modules from 32-bit packages - set(CMAKE_FIND_ROOT_PATH ${DIR}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# 32-bit NASM -set(CMAKE_ASM_NASM_OBJECT_FORMAT elf) diff --git a/CMake/CodeCoverage.cmake b/CMake/CodeCoverage.cmake deleted file mode 100644 index b17bc05b3..000000000 --- a/CMake/CodeCoverage.cmake +++ /dev/null @@ -1,303 +0,0 @@ -# Copyright (c) 2012 - 2017, Lars Bilke -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# CHANGES: -# -# 2012-01-31, Lars Bilke -# - Enable Code Coverage -# -# 2013-09-17, Joakim Söderberg -# - Added support for Clang. -# - Some additional usage instructions. -# -# 2016-02-03, Lars Bilke -# - Refactored functions to use named parameters -# -# 2017-06-02, Lars Bilke -# - Merged with modified version from github.com/ufz/ogs -# -# -# USAGE: -# -# 1. Copy this file into your cmake modules path. -# -# 2. Add the following line to your CMakeLists.txt: -# include(CodeCoverage) -# -# 3. Append necessary compiler flags: -# APPEND_COVERAGE_COMPILER_FLAGS() -# -# 4. If you need to exclude additional directories from the report, specify them -# using the COVERAGE_LCOV_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE_LCOV. -# Example: -# set(COVERAGE_LCOV_EXCLUDES 'dir1/*' 'dir2/*') -# -# 5. Use the functions described below to create a custom make target which -# runs your test executable and produces a code coverage report. -# -# 6. Build a Debug build: -# cmake -DCMAKE_BUILD_TYPE=Debug .. -# make -# make my_coverage_target -# - -include(CMakeParseArguments) - -# Check prereqs -find_program( GCOV_PATH gcov ) -find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl) -find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat ) -find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) -find_program( SIMPLE_PYTHON_EXECUTABLE python ) - -if(NOT GCOV_PATH) - message(WARNING "gcov not found") - return() -endif() # NOT GCOV_PATH - -if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") - if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3) - message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") - endif() -elseif(NOT CMAKE_COMPILER_IS_GNUCXX) - message(WARNING "Compiler is not GNU gcc") - return() -endif() - -set(COVERAGE_COMPILER_FLAGS --coverage -fprofile-arcs -ftest-coverage - CACHE INTERNAL "") - -set(CMAKE_CXX_FLAGS_COVERAGE - ${COVERAGE_COMPILER_FLAGS} - CACHE STRING "Flags used by the C++ compiler during coverage builds." - FORCE ) -set(CMAKE_C_FLAGS_COVERAGE - ${COVERAGE_COMPILER_FLAGS} - CACHE STRING "Flags used by the C compiler during coverage builds." - FORCE ) -set(CMAKE_EXE_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used for linking binaries during coverage builds." - FORCE ) -set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used by the shared libraries linker during coverage builds." - FORCE ) - -mark_as_advanced( - CMAKE_CXX_FLAGS_COVERAGE - CMAKE_C_FLAGS_COVERAGE - CMAKE_EXE_LINKER_FLAGS_COVERAGE - CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) - -if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") -endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug" - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# SETUP_TARGET_FOR_COVERAGE_LCOV( -# NAME testrunner_coverage # New target name -# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES testrunner # Dependencies to build first -# ) -function(SETUP_TARGET_FOR_COVERAGE_LCOV) - - set(options NONE) - set(oneValueArgs NAME) - set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT LCOV_PATH) - message(FATAL_ERROR "lcov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() # NOT GENHTML_PATH - - # Setup target - add_custom_target(${Coverage_NAME} - - # Cleanup lcov - COMMAND ${LCOV_PATH} --gcov-tool ${GCOV_PATH} -directory . --zerocounters - # Create baseline to make sure untouched files show up in the report - COMMAND ${LCOV_PATH} --gcov-tool ${GCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base - - # Run tests - COMMAND ${Coverage_EXECUTABLE} - - # Capturing lcov counters and generating report - COMMAND ${LCOV_PATH} --gcov-tool ${GCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info - # add baseline counters - COMMAND ${LCOV_PATH} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total - COMMAND ${LCOV_PATH} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_LCOV_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned - COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned - COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned - - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." - ) - - # Show where to find the lcov info report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info." - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) - -endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# SETUP_TARGET_FOR_COVERAGE_GCOVR_XML( -# NAME ctest_coverage # New target name -# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES executable_target # Dependencies to build first -# ) -function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML) - - set(options NONE) - set(oneValueArgs NAME) - set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT SIMPLE_PYTHON_EXECUTABLE) - message(FATAL_ERROR "python not found! Aborting...") - endif() # NOT SIMPLE_PYTHON_EXECUTABLE - - if(NOT GCOVR_PATH) - message(FATAL_ERROR "gcovr not found! Aborting...") - endif() # NOT GCOVR_PATH - - # Combine excludes to several -e arguments - set(GCOVR_EXCLUDES "") - foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES}) - list(APPEND GCOVR_EXCLUDES "-e") - list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") - endforeach() - - add_custom_target(${Coverage_NAME} - # Run tests - ${Coverage_EXECUTABLE} - - # Running gcovr - COMMAND ${GCOVR_PATH} --xml - -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES} - --object-directory=${PROJECT_BINARY_DIR} - -o ${Coverage_NAME}.xml - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - COMMENT "Running gcovr to produce Cobertura code coverage report." - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml." - ) - -endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_XML - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML( -# NAME ctest_coverage # New target name -# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES executable_target # Dependencies to build first -# ) -function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML) - - set(options NONE) - set(oneValueArgs NAME) - set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT SIMPLE_PYTHON_EXECUTABLE) - message(WARNING "python not found! Aborting...") - return() - endif() # NOT SIMPLE_PYTHON_EXECUTABLE - - if(NOT GCOVR_PATH) - message(WARNING "gcovr not found! Aborting...") - return() - endif() # NOT GCOVR_PATH - - # Combine excludes to several -e arguments - set(GCOVR_EXCLUDES "") - foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES}) - list(APPEND GCOVR_EXCLUDES "-e") - list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") - endforeach() - - add_custom_target(${Coverage_NAME} - # Run tests - ${Coverage_EXECUTABLE} - - # Create folder - COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME} - - # Running gcovr - COMMAND ${GCOVR_PATH} --html --html-details - --delete - -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES} - --object-directory=${PROJECT_BINARY_DIR} - -o ${Coverage_NAME}/index.html - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - COMMENT "Running gcovr to produce HTML code coverage report." - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) - -endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML - -function(APPEND_COVERAGE_COMPILER_FLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) - message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") -endfunction() # APPEND_COVERAGE_COMPILER_FLAGS diff --git a/CMake/absolute.cmake b/CMake/absolute.cmake deleted file mode 100644 index 5edff2894..000000000 --- a/CMake/absolute.cmake +++ /dev/null @@ -1,26 +0,0 @@ -set(ORIGINAL_EXE "${CMAKE_SOURCE_DIR}/Diablo.exe") - -if(EXISTS "${ORIGINAL_EXE}") - message(STATUS "Using EXE at ${ORIGINAL_EXE}") - - file(MD5 ${ORIGINAL_EXE} MD5SUM) - if(NOT MD5SUM STREQUAL "da62d5cd8bd71a0b66e6d4ef7a111233") - message(FATAL_ERROR "MD5 of EXE is not correct (${MD5SUM})") - endif() - - enable_language(ASM_NASM) - - set(HARNESS_ASM "${CMAKE_SOURCE_DIR}/Absolute/harness.asm") - - # This can not be an OBJECT library since those can not have link flags on older versions of cmake - add_library(harness STATIC ${HARNESS_ASM}) - target_compile_options(harness PRIVATE -f elf -DEXE=\"${ORIGINAL_EXE}\") - - target_compile_options(harness INTERFACE -fno-pie -fno-pic) - target_compile_definitions(harness INTERFACE -DNO_GLOBALS) - target_link_libraries(harness INTERFACE - -L${CMAKE_SOURCE_DIR}/Absolute -Tdefault.ld - ) -else() - message(STATUS "Original .exe not found at ${ORIGINAL_EXE}") -endif() diff --git a/CMake/sanitize.cmake b/CMake/sanitize.cmake deleted file mode 100644 index 2cde7b136..000000000 --- a/CMake/sanitize.cmake +++ /dev/null @@ -1,18 +0,0 @@ -include(CheckCXXCompilerFlag) -include(CMakePushCheckState) - -set(SANITIZE_OPTIONS -fsanitize=null -fsanitize=return) -# TODO: use "-fsanitize=object-size" -# "-fsanitize=bounds" not enabled because the code often generates temporary pointers out-of-bounds of arrays - -# Note: The compiler must always support recovery because the decompiled code is not ASAN-clean -set(SANITIZE_ADDRESS_FLAGS -fsanitize=address -fsanitize-recover=address) - -cmake_push_check_state() -set(CMAKE_REQUIRED_LIBRARIES ${SANITIZE_ADDRESS_FLAGS}) -check_cxx_compiler_flag("${SANITIZE_ADDRESS_FLAGS}" HAS_SANITIZE_ADDRESS) -cmake_pop_check_state() - -if(HAS_SANITIZE_ADDRESS) - list(APPEND SANITIZE_OPTIONS ${SANITIZE_ADDRESS_FLAGS}) -endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index ecbbbf865..33adf0dd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,30 +10,21 @@ endif() include(CMake/out_of_tree.cmake) -# This *must* be included before calling `project()`, due to setting early compiler flags. -include(CMake/32bit.cmake) - set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -project(devil-miniwin +project(devilutionX VERSION 0.0.1 LANGUAGES C CXX ) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${devilutionX_SOURCE_DIR}/CMake") -if(NOT CMAKE_SIZEOF_VOID_P EQUAL 4) - message(WARNING "sizeof(void*) == ${CMAKE_SIZEOF_VOID_P}.") - message(FATAL_ERROR [[This project can only be compiled in 32-bit mode.]]) -endif() +find_package(SDL2 REQUIRED) +find_package(SDL2_mixer REQUIRED) # Note: In Debug mode, GCC generates spurious memory references that upset Valgrind, # these options fix that. string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-omit-frame-pointer") -if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") - # Clang/LLVM optimizations break everything -# string(APPEND CMAKE_CXX_FLAGS_DEBUG " -Og") -# string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fvar-tracking-assignments -ggdb -gdwarf-4") -endif() set(SOURCES Source/automap.cpp @@ -151,11 +142,9 @@ set(STUB_SOURCES ) include(CMake/SDL2_fixed.cmake) -include(CMake/sanitize.cmake) -include(CMake/absolute.cmake) -include(CMake/CodeCoverage.cmake) -include_directories(${SDL2_INCLUDE_DIRS}) +include_directories(${SDL2_INCLUDE_DIR} + ${SDL2_MIXER_INCLUDE_DIR}) include_directories(. Stub) @@ -181,7 +170,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-fms-extensions) endif() -# Vanilla build add_executable(devilution ${SOURCES} ${STUB_SOURCES} @@ -191,80 +179,11 @@ add_executable(devilution target_link_libraries(devilution PUBLIC m ${SDL2_LIBRARIES} + ${SDL2_MIXER_LIBRARIES} ) -# Coverage tracing library (compiled separately so it itself is not traced & can be optimized) -add_library(sanitize_coverage STATIC Stub/sanitize_coverage.cpp) -target_compile_options(sanitize_coverage PRIVATE -O2 -fno-pie -fno-pic) - -cmake_push_check_state() -set(SANITIZE_COVERAGE_FLAGS -fsanitize-coverage=trace-pc) -set(CMAKE_REQUIRED_FLAGS ${SANITIZE_COVERAGE_FLAGS}) -check_cxx_source_compiles([[extern "C" void __sanitizer_cov_trace_pc(void) {} int main() { return 0; }]] HAS_SANITIZE_COVERAGE) -cmake_pop_check_state() - - # xxhash fast hashing library add_library(xxhash STATIC 3rdParty/xxhash/xxhash.c) set_source_files_properties(3rdParty/xxhash/xxhash.c PROPERTIES LANGUAGE CXX) target_include_directories(xxhash PUBLIC 3rdParty/xxhash) target_compile_options(xxhash PRIVATE -O3 -fno-pie -fno-pic) - -# Build with harness enabled (conflicts with sanitizers) -if(TARGET harness) - add_executable(devil-harness - ${SOURCES} - ${STUB_SOURCES} - # Stub/main_harness.cpp - Stub/main_test.cpp - Absolute/absolute.cpp - Absolute/hook.cpp - Stub/test_utils.cpp - ) - - if(HAS_SANITIZE_COVERAGE) - target_compile_options(devil-harness PRIVATE ${SANITIZE_COVERAGE_FLAGS}) - target_compile_definitions(devil-harness PRIVATE -DHAVE_SANITIZE_COVERGE) - endif() - - target_compile_definitions(devil-harness PUBLIC -DHAVE_HARNESS) - - target_link_libraries(devil-harness PUBLIC - m - harness - xxhash - sanitize_coverage - ${SDL2_LIBRARIES} - ) -endif() - -# Build with sanitizers enabled -add_executable(devil-sanitize - ${SOURCES} - ${STUB_SOURCES} - Stub/main_test.cpp - Stub/test_utils.cpp - Stub/sanitize.cpp -) - -target_compile_options(devil-sanitize PRIVATE - ${SANITIZE_OPTIONS} - ${COVERAGE_COMPILER_FLAGS} -) - -target_link_libraries(devil-sanitize PUBLIC - m - xxhash - sanitize_coverage - ${SDL2_LIBRARIES} - ${SANITIZE_OPTIONS} - ${COVERAGE_COMPILER_FLAGS} -) - -if(COVERAGE_COMPILER_FLAGS) - SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML( - NAME devil-sanitize-coverage - EXECUTABLE devil-sanitize - DEPENDENCIES devil-sanitize - ) -endif()