# This file is automatically generated from cmake.toml - DO NOT EDIT
# See https://github.com/build-cpp/cmkr for more information

cmake_minimum_required(VERSION 3.15)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
	message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()

set(CMKR_ROOT_PROJECT OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
	set(CMKR_ROOT_PROJECT ON)

	# Bootstrap cmkr and automatically regenerate CMakeLists.txt
	include(cmkr.cmake OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT)
	if(CMKR_INCLUDE_RESULT)
		cmkr()
	endif()

	# Enable folder support
	set_property(GLOBAL PROPERTY USE_FOLDERS ON)

	# Create a configure-time dependency on cmake.toml to improve IDE support
	configure_file(cmake.toml cmake.toml COPYONLY)
endif()

# Options
option(SAFETYHOOK_BUILD_DOCS "" OFF)
option(SAFETYHOOK_BUILD_TEST "" OFF)
option(SAFETYHOOK_BUILD_EXAMPLES "" OFF)
option(SAFETYHOOK_AMALGAMATE "" OFF)
option(SAFETYHOOK_FETCH_ZYDIS "" ON)
option(SAFETYHOOK_USE_CXXMODULES "" OFF)

project(safetyhook)

include(FetchContent)

if(SAFETYHOOK_BUILD_TEST) # build-test
	message(STATUS "Fetching ut (v2.0.1)...")
	FetchContent_Declare(ut
		GIT_REPOSITORY
			"https://github.com/boost-ext/ut.git"
		GIT_TAG
			v2.0.1
		GIT_SHALLOW
			ON
		EXCLUDE_FROM_ALL
			ON
	)
	FetchContent_MakeAvailable(ut)

endif()
if(SAFETYHOOK_BUILD_TEST) # build-test
	message(STATUS "Fetching xbyak (v6.69)...")
	FetchContent_Declare(xbyak
		GIT_REPOSITORY
			"https://github.com/herumi/xbyak.git"
		GIT_TAG
			v6.69
		GIT_SHALLOW
			ON
		EXCLUDE_FROM_ALL
			ON
	)
	FetchContent_MakeAvailable(xbyak)

endif()
if(SAFETYHOOK_FETCH_ZYDIS) # fetch-zydis
	option(ZYDIS_BUILD_EXAMPLES "" OFF)
	option(ZYDIS_BUILD_TOOLS "" OFF)
	option(ZYDIS_BUILD_DOXYGEN "" OFF)

	message(STATUS "Fetching Zydis (v4.1.0)...")
	FetchContent_Declare(Zydis
		GIT_REPOSITORY
			"https://github.com/zyantific/zydis.git"
		GIT_TAG
			v4.1.0
		GIT_SHALLOW
			ON
		EXCLUDE_FROM_ALL
			ON
	)
	FetchContent_MakeAvailable(Zydis)

endif()
# Packages
if(SAFETYHOOK_BUILD_DOCS) # build-docs
	find_package(Doxygen REQUIRED)

endif()
if(SAFETYHOOK_AMALGAMATE) # amalgamate
	find_package(Python3 REQUIRED)

endif()
if((NOT SAFETYHOOK_FETCH_ZYDIS)) # find-zydis
	find_package(Zydis REQUIRED CONFIG)

endif()
# Target: safetyhook
set(CMKR_TARGET safetyhook)
if(TARGET Zydis::Zydis AND NOT TARGET Zydis)
    add_library(Zydis ALIAS Zydis::Zydis)
endif()

set(safetyhook_SOURCES
	"src/allocator.cpp"
	"src/easy.cpp"
	"src/inline_hook.cpp"
	"src/mid_hook.cpp"
	"src/os.linux.cpp"
	"src/os.windows.cpp"
	"src/utility.cpp"
	"src/vmt_hook.cpp"
	cmake.toml
)

add_library(safetyhook)

target_sources(safetyhook PRIVATE ${safetyhook_SOURCES})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${safetyhook_SOURCES})

add_library(safetyhook::safetyhook ALIAS safetyhook)
if(BUILD_SHARED_LIBS) # shared
	target_compile_definitions(safetyhook PUBLIC
		SAFETYHOOK_SHARED_LIB
	)
endif()

if(BUILD_SHARED_LIBS) # shared
	target_compile_definitions(safetyhook PRIVATE
		SAFETYHOOK_BUILDING
	)
endif()

target_compile_features(safetyhook PUBLIC
	cxx_std_23
)

if(MSVC) # msvc
	target_compile_options(safetyhook PRIVATE
		"/permissive-"
		"/W4"
		"/w14640"
		"/wd4251"
	)
endif()

if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$") OR (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$")) # clang
	target_compile_options(safetyhook PRIVATE
		-Wall
		-Wextra
		-Wshadow
		-Wnon-virtual-dtor
		-pedantic
	)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU") # gcc
	target_compile_options(safetyhook PRIVATE
		-Wall
		-Wextra
		-Wshadow
		-Wnon-virtual-dtor
		-pedantic
	)
endif()

target_include_directories(safetyhook PUBLIC
	"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
	"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

target_link_libraries(safetyhook PUBLIC
	Zydis
)

if(SAFETYHOOK_USE_CXXMODULES)
    target_compile_definitions(safetyhook INTERFACE SAFETYHOOK_USE_CXXMODULES)
endif()

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/safetyhook-config.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/safetyhook-config.cmake
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/safetyhook
)

install(
    TARGETS safetyhook
    EXPORT safetyhook-targets
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(
    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(
    EXPORT safetyhook-targets
    FILE safetyhook-targets.cmake
    NAMESPACE safetyhook::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/safetyhook
)

install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/safetyhook-config.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/safetyhook
)

# Target: docs
if(SAFETYHOOK_BUILD_DOCS) # build-docs
	set(CMKR_TARGET docs)
	file(GLOB_RECURSE HEADER_FILES include/*.hpp)
	set(DOXYGEN_INDEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/docs/html/index.html)
	set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in)
	set(DOXYFILE_OUT ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile)
	configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT})
	add_custom_command(
	    OUTPUT ${DOXYGEN_INDEX_FILE}
	    DEPENDS ${HEADER_FILES}
	    COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
	    MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
	    COMMENT "Generating docs"
	)
	add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE})

	set(docs_SOURCES
		cmake.toml
	)

	add_custom_target(docs SOURCES)

	target_sources(docs PRIVATE ${docs_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${docs_SOURCES})

endif()
# Target: amalgamation
if(SAFETYHOOK_AMALGAMATE) # amalgamate
	set(CMKR_TARGET amalgamation)
	file(GLOB_RECURSE HEADER_FILES include/*.hpp)
	file(GLOB_RECURSE SOURCE_FILES src/*.cpp)
	set(AMALGAMATED_FILE ${CMAKE_CURRENT_SOURCE_DIR}/amalgamated-dist/safetyhook.cpp)
	set(AMALGAMATED_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/amalgamated-dist/safetyhook.hpp)
	set(AMALGAMATE_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate.py)
	add_custom_command(
	    OUTPUT ${AMALGAMATED_FILE} ${AMALGAMATED_HEADER}
	    DEPENDS ${HEADER_FILES} ${SOURCE_FILES} ${AMALGAMATE_SCRIPT}
	    COMMAND ${Python3_EXECUTABLE} ${AMALGAMATE_SCRIPT}
	    MAIN_DEPENDENCY ${AMALGAMATE_SCRIPT}
	    COMMENT "Amalgamating"
	)
	add_custom_target(Amalgamate ALL DEPENDS ${AMALGAMATED_FILE} ${AMALGAMATED_HEADER})

	set(amalgamation_SOURCES
		cmake.toml
	)

	add_custom_target(amalgamation SOURCES)

	target_sources(amalgamation PRIVATE ${amalgamation_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${amalgamation_SOURCES})

endif()
# Target: example-minimal
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
	set(example-minimal_SOURCES
		"example/minimal.cpp"
		cmake.toml
	)

	add_executable(example-minimal)

	target_sources(example-minimal PRIVATE ${example-minimal_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-minimal_SOURCES})

	target_compile_features(example-minimal PRIVATE
		cxx_std_23
	)

	target_link_libraries(example-minimal PRIVATE
		safetyhook::safetyhook
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-minimal)
	endif()

endif()
# Target: example-multiple
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
	set(example-multiple_SOURCES
		"example/multiple.cpp"
		cmake.toml
	)

	add_executable(example-multiple)

	target_sources(example-multiple PRIVATE ${example-multiple_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-multiple_SOURCES})

	target_compile_features(example-multiple PRIVATE
		cxx_std_23
	)

	target_link_libraries(example-multiple PRIVATE
		safetyhook::safetyhook
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-multiple)
	endif()

endif()
# Target: example-midhook
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
	set(example-midhook_SOURCES
		"example/midhook.cpp"
		cmake.toml
	)

	add_executable(example-midhook)

	target_sources(example-midhook PRIVATE ${example-midhook_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-midhook_SOURCES})

	target_compile_features(example-midhook PRIVATE
		cxx_std_23
	)

	target_link_libraries(example-midhook PRIVATE
		safetyhook::safetyhook
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-midhook)
	endif()

endif()
# Target: example-threadsafe
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
	set(example-threadsafe_SOURCES
		"example/threadsafe.cpp"
		cmake.toml
	)

	add_executable(example-threadsafe)

	target_sources(example-threadsafe PRIVATE ${example-threadsafe_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-threadsafe_SOURCES})

	target_compile_features(example-threadsafe PRIVATE
		cxx_std_23
	)

	target_link_libraries(example-threadsafe PRIVATE
		safetyhook::safetyhook
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-threadsafe)
	endif()

endif()
# Target: example-dll
if(SAFETYHOOK_BUILD_EXAMPLES AND WIN32) # windows-only-example
	set(example-dll_SOURCES
		"example/dll.cpp"
		cmake.toml
	)

	add_library(example-dll SHARED)

	target_sources(example-dll PRIVATE ${example-dll_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-dll_SOURCES})

	target_compile_features(example-dll PUBLIC
		cxx_std_23
	)

	target_link_libraries(example-dll PUBLIC
		safetyhook::safetyhook
	)

endif()
# Target: example-vmthook
if(SAFETYHOOK_BUILD_EXAMPLES) # build-examples
	set(example-vmthook_SOURCES
		"example/vmthook.cpp"
		cmake.toml
	)

	add_executable(example-vmthook)

	target_sources(example-vmthook PRIVATE ${example-vmthook_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${example-vmthook_SOURCES})

	target_compile_features(example-vmthook PRIVATE
		cxx_std_23
	)

	target_link_libraries(example-vmthook PRIVATE
		safetyhook::safetyhook
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT example-vmthook)
	endif()

endif()
# Target: test
if(SAFETYHOOK_BUILD_TEST) # build-test
	set(test_SOURCES
		"test/allocator.cpp"
		"test/inline_hook.cpp"
		"test/inline_hook.x86_64.cpp"
		"test/main.cpp"
		"test/mid_hook.cpp"
		"test/vmt_hook.cpp"
		cmake.toml
	)

	add_executable(test)

	target_sources(test PRIVATE ${test_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${test_SOURCES})

	target_compile_definitions(test PRIVATE
		BOOST_UT_DISABLE_MODULE
	)

	target_compile_features(test PRIVATE
		cxx_std_23
	)

	target_link_libraries(test PRIVATE
		Boost::ut
		safetyhook::safetyhook
		xbyak::xbyak
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT test)
	endif()

endif()
# Target: test-amalgamated
if(SAFETYHOOK_BUILD_TEST AND SAFETYHOOK_AMALGAMATE) # build-amalgamate-test
	set(test-amalgamated_SOURCES
		"test/allocator.cpp"
		"test/inline_hook.cpp"
		"test/inline_hook.x86_64.cpp"
		"test/main.cpp"
		"test/mid_hook.cpp"
		"test/vmt_hook.cpp"
		"amalgamated-dist/safetyhook.cpp"
		cmake.toml
	)

	add_executable(test-amalgamated)

	target_sources(test-amalgamated PRIVATE ${test-amalgamated_SOURCES})
	source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${test-amalgamated_SOURCES})

	target_compile_definitions(test-amalgamated PRIVATE
		BOOST_UT_DISABLE_MODULE
	)

	target_compile_features(test-amalgamated PRIVATE
		cxx_std_23
	)

	target_include_directories(test-amalgamated PRIVATE
		"amalgamated-dist/"
	)

	target_link_libraries(test-amalgamated PRIVATE
		Zydis
		Boost::ut
		xbyak::xbyak
	)

	get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
	if(NOT CMKR_VS_STARTUP_PROJECT)
		set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT test-amalgamated)
	endif()

	set(CMKR_TARGET test-amalgamated)
	add_dependencies(test-amalgamated Amalgamate)

endif()
