2023-07-27 00:53:04 +02:00
|
|
|
macro(add_imhex_plugin)
|
2023-08-22 19:29:03 +02:00
|
|
|
# Parse arguments
|
2023-12-23 21:09:41 +01:00
|
|
|
set(options LIBRARY_PLUGIN)
|
2024-01-04 12:01:40 +01:00
|
|
|
set(oneValueArgs NAME IMHEX_VERSION)
|
2023-12-31 11:39:24 +01:00
|
|
|
set(multiValueArgs SOURCES INCLUDES LIBRARIES FEATURES)
|
2023-07-27 00:53:04 +02:00
|
|
|
cmake_parse_arguments(IMHEX_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
2023-10-04 12:00:32 +02:00
|
|
|
|
2024-01-04 12:01:40 +01:00
|
|
|
if (IMHEX_PLUGIN_IMHEX_VERSION)
|
|
|
|
message(STATUS "Compiling plugin ${IMHEX_PLUGIN_NAME} for ImHex Version ${IMHEX_PLUGIN_IMHEX_VERSION}")
|
|
|
|
set(IMHEX_VERSION_STRING "${IMHEX_PLUGIN_IMHEX_VERSION}")
|
|
|
|
endif()
|
|
|
|
|
2023-10-04 12:00:32 +02:00
|
|
|
if (IMHEX_STATIC_LINK_PLUGINS)
|
|
|
|
set(IMHEX_PLUGIN_LIBRARY_TYPE STATIC)
|
|
|
|
|
|
|
|
target_link_libraries(libimhex PUBLIC ${IMHEX_PLUGIN_NAME})
|
|
|
|
|
|
|
|
configure_file(${CMAKE_SOURCE_DIR}/dist/web/plugin-bundle.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp @ONLY)
|
|
|
|
target_sources(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp)
|
2023-12-23 21:09:41 +01:00
|
|
|
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
2023-10-04 12:00:32 +02:00
|
|
|
else()
|
2023-12-23 21:09:41 +01:00
|
|
|
if (IMHEX_PLUGIN_LIBRARY_PLUGIN)
|
|
|
|
set(IMHEX_PLUGIN_LIBRARY_TYPE SHARED)
|
|
|
|
set(IMHEX_PLUGIN_SUFFIX ".hexpluglib")
|
|
|
|
else()
|
|
|
|
set(IMHEX_PLUGIN_LIBRARY_TYPE MODULE)
|
|
|
|
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
|
|
|
endif()
|
2023-10-04 12:00:32 +02:00
|
|
|
endif()
|
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Define new project for plugin
|
2023-07-27 00:53:04 +02:00
|
|
|
project(${IMHEX_PLUGIN_NAME})
|
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Create a new shared library for the plugin source code
|
2023-10-04 12:00:32 +02:00
|
|
|
add_library(${IMHEX_PLUGIN_NAME} ${IMHEX_PLUGIN_LIBRARY_TYPE} ${IMHEX_PLUGIN_SOURCES})
|
2023-07-27 00:53:04 +02:00
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Add include directories and link libraries
|
2023-10-04 12:00:32 +02:00
|
|
|
target_include_directories(${IMHEX_PLUGIN_NAME} PUBLIC ${IMHEX_PLUGIN_INCLUDES})
|
2024-02-29 19:48:16 +01:00
|
|
|
target_link_libraries(${IMHEX_PLUGIN_NAME} PUBLIC ${IMHEX_PLUGIN_LIBRARIES})
|
|
|
|
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE libimhex ${FMT_LIBRARIES} imgui_all_includes libwolv)
|
2023-12-22 23:39:38 +01:00
|
|
|
addIncludesFromLibrary(${IMHEX_PLUGIN_NAME} libpl)
|
2024-02-29 19:48:16 +01:00
|
|
|
addIncludesFromLibrary(${IMHEX_PLUGIN_NAME} libpl-gen)
|
2023-07-27 00:53:04 +02:00
|
|
|
|
2024-03-02 11:51:33 +01:00
|
|
|
precompileHeaders(${IMHEX_PLUGIN_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Add IMHEX_PROJECT_NAME and IMHEX_VERSION define
|
2023-07-27 00:53:04 +02:00
|
|
|
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PROJECT_NAME="${IMHEX_PLUGIN_NAME}")
|
|
|
|
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_VERSION="${IMHEX_VERSION_STRING}")
|
2023-10-04 12:00:32 +02:00
|
|
|
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PLUGIN_NAME=${IMHEX_PLUGIN_NAME})
|
2023-07-27 00:53:04 +02:00
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Enable required compiler flags
|
2023-11-30 10:22:15 +01:00
|
|
|
enableUnityBuild(${IMHEX_PLUGIN_NAME})
|
2023-07-27 00:53:04 +02:00
|
|
|
setupCompilerFlags(${IMHEX_PLUGIN_NAME})
|
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Configure build properties
|
|
|
|
set_target_properties(${IMHEX_PLUGIN_NAME}
|
|
|
|
PROPERTIES
|
build: Xcode accomodating CMake setup (#1688)
### Problem description
This PR implements some rudimentary Xcode support for building and
editing ImHex.
### Implementation description
#### Problem 1: Xcode is a multi-configuration buildsystem
The project is already rather CMake generator independent, thus it did
not need to change much to support Xcode's multi-configuration paradigm:
By default, CMake generates a `.xcodeproj` in which targets build their
artifacts into the specified `<>_OUTPUT_DIRECTORY`, postfixed by the
currently active configuration. To better fit the existing paradigm, I
instead opted ot introduce `IMHEX_MAIN_OUTPUT_DIRECTORY`. This variable
is equal to the previously used `RUNTIME_OUTPUT_DIRECTORY` when using
other generators, and is changed to include a configuration specific
_prefix_ when used with Xcode.
The result is different output directories when using Xcode, and no
changes when using any other generator.
#### Problem 2: ImHex does not support AppleClang
To allow building the codebase with Xcode, I have introduced
`IMHEX_IDE_HELPERS_OVERRIDE_XCODE_COMPILER`. Specifying this option to
`ON` will force CMake to honor the user specified compiler settings,
even when using the Xcode generator.
In practice this can be used together with the new "xcode" CMakePreset
to build the project with mainline clang using `xcodebuild`, or Xcode
itself by generating a buildsystem like so:
```
cmake --preset xcode -DCMAKE_PREFIX_PATH=/opt/homebrew/opt/llvm@17
```
This solution is of course not without flaws. The inner workings are a
particularly ugly hack, and mainline clang does not implement the
necessary extensions to allow Xcode to index the code. Regardless this
option is useful to enable future work in terms of bundling/signing
macOS applications in the "intended" way using Xcode without additional
source modifications.
#### Problem 3: Vanilla CMake + Xcode = Bad developer UX
By default, the CMake generated `.xcodeproj` is a mess. Tons of targets
are scattered about, and source files are not organized beyond grouping
them into a "Source Files" and "Header Files" group.
Even "Header Files" is missing, because the ImHex build system does not
regard private header files of libraries as sources of a target, and
Xcode does not try to guess this information.
The solution is twofold:
* Additional code has been added which organizes the targets into a neat
folder structure
* Additional code was added behind a configuration flag
`IMHEX_IDE_HELPERS_INTRUSIVE_IDE_TWEAKS` which automatically creates
source file trees in Xcode targets, and discovers the non-declared
header files via the folder convention.
### Screenshots
N/A
### Additional things
As a bonus: `IMHEX_OFFLINE_BUILD` assumes that ImHex-Patterns is cloned
into the source tree. I have added an additional fallback that tries to
locate it as a sibling folder of `${CMAKE_SOURCE_DIR}`, as this meshes
better with my filesystem setup.
The setup was tested with `CMake 3.29.2`, `Xcode 15.2`, and `llvm@17`
from homebrew.
2024-05-20 12:12:57 +02:00
|
|
|
RUNTIME_OUTPUT_DIRECTORY "${IMHEX_MAIN_OUTPUT_DIRECTORY}/plugins"
|
2023-08-22 19:29:03 +02:00
|
|
|
CXX_STANDARD 23
|
|
|
|
PREFIX ""
|
2023-12-23 21:09:41 +01:00
|
|
|
SUFFIX ${IMHEX_PLUGIN_SUFFIX}
|
2023-08-22 19:29:03 +02:00
|
|
|
)
|
|
|
|
|
2024-01-24 22:30:40 +01:00
|
|
|
# Set rpath of plugin libraries to the plugins folder
|
|
|
|
if (APPLE)
|
|
|
|
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES BUILD_RPATH "@executable_path/../Frameworks;@executable_path/plugins")
|
|
|
|
endif()
|
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Setup a romfs for the plugin
|
2023-10-29 19:43:40 +01:00
|
|
|
list(APPEND LIBROMFS_RESOURCE_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/romfs)
|
2023-07-27 00:53:04 +02:00
|
|
|
set(LIBROMFS_PROJECT_NAME ${IMHEX_PLUGIN_NAME})
|
|
|
|
add_subdirectory(${IMHEX_BASE_FOLDER}/lib/external/libromfs ${CMAKE_CURRENT_BINARY_DIR}/libromfs)
|
|
|
|
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE ${LIBROMFS_LIBRARY})
|
2023-07-27 02:07:36 +02:00
|
|
|
|
2024-07-08 18:12:46 +02:00
|
|
|
set(FEATURE_DEFINE_CONTENT)
|
|
|
|
|
|
|
|
if (IMHEX_PLUGIN_FEATURES)
|
|
|
|
list(LENGTH IMHEX_PLUGIN_FEATURES IMHEX_FEATURE_COUNT)
|
|
|
|
math(EXPR IMHEX_FEATURE_COUNT "${IMHEX_FEATURE_COUNT} - 1" OUTPUT_FORMAT DECIMAL)
|
|
|
|
foreach(index RANGE 0 ${IMHEX_FEATURE_COUNT} 2)
|
|
|
|
list(SUBLIST IMHEX_PLUGIN_FEATURES ${index} 2 IMHEX_PLUGIN_FEATURE)
|
|
|
|
list(GET IMHEX_PLUGIN_FEATURE 0 feature_define)
|
|
|
|
list(GET IMHEX_PLUGIN_FEATURE 1 feature_description)
|
|
|
|
|
|
|
|
string(TOUPPER ${feature_define} feature_define)
|
|
|
|
add_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature_define}=0)
|
|
|
|
set(FEATURE_DEFINE_CONTENT "${FEATURE_DEFINE_CONTENT}{ \"${feature_description}\", IMHEX_FEATURE_ENABLED(${feature_define}) },")
|
|
|
|
endforeach()
|
|
|
|
endif()
|
|
|
|
|
|
|
|
target_compile_options(${IMHEX_PLUGIN_NAME} PRIVATE -DIMHEX_PLUGIN_FEATURES_CONTENT=${FEATURE_DEFINE_CONTENT})
|
2023-12-31 11:39:24 +01:00
|
|
|
|
2023-08-22 19:29:03 +02:00
|
|
|
# Add the new plugin to the main dependency list so it gets built by default
|
2023-12-22 23:39:38 +01:00
|
|
|
if (TARGET imhex_all)
|
|
|
|
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
|
|
|
endif()
|
2024-01-04 12:01:40 +01:00
|
|
|
|
2024-01-04 10:25:29 +01:00
|
|
|
if (IMHEX_EXTERNAL_PLUGIN_BUILD)
|
|
|
|
install(TARGETS ${IMHEX_PLUGIN_NAME} DESTINATION ".")
|
2024-01-24 22:30:40 +01:00
|
|
|
endif()
|
2024-01-04 12:01:40 +01:00
|
|
|
|
2024-01-24 22:30:40 +01:00
|
|
|
# Fix rpath
|
|
|
|
if (APPLE)
|
2024-06-25 23:17:15 +02:00
|
|
|
set_target_properties(
|
|
|
|
${IMHEX_PLUGIN_NAME}
|
|
|
|
PROPERTIES
|
|
|
|
INSTALL_RPATH "@executable_path/../Frameworks;@executable_path/plugins"
|
|
|
|
)
|
2024-02-07 21:51:59 +01:00
|
|
|
elseif (UNIX)
|
2024-06-28 22:21:10 +02:00
|
|
|
set(PLUGIN_RPATH "")
|
|
|
|
list(APPEND PLUGIN_RPATH "$ORIGIN")
|
|
|
|
|
|
|
|
if (IMHEX_PLUGIN_ADD_INSTALL_PREFIX_TO_RPATH)
|
|
|
|
list(APPEND PLUGIN_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
|
|
|
|
endif()
|
|
|
|
|
2024-06-25 23:17:15 +02:00
|
|
|
set_target_properties(
|
|
|
|
${IMHEX_PLUGIN_NAME}
|
|
|
|
PROPERTIES
|
|
|
|
INSTALL_RPATH_USE_ORIGIN ON
|
2024-06-28 22:21:10 +02:00
|
|
|
INSTALL_RPATH "${PLUGIN_RPATH}"
|
2024-06-25 23:17:15 +02:00
|
|
|
)
|
2024-01-04 10:25:29 +01:00
|
|
|
endif()
|
2024-02-26 20:51:08 +01:00
|
|
|
|
2024-06-25 21:54:48 +02:00
|
|
|
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt AND IMHEX_ENABLE_UNIT_TESTS AND IMHEX_ENABLE_PLUGIN_TESTS)
|
2024-02-26 20:51:08 +01:00
|
|
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)
|
|
|
|
target_link_libraries(${IMHEX_PLUGIN_NAME} PUBLIC ${IMHEX_PLUGIN_NAME}_tests)
|
|
|
|
target_compile_definitions(${IMHEX_PLUGIN_NAME}_tests PRIVATE IMHEX_PROJECT_NAME="${IMHEX_PLUGIN_NAME}-tests")
|
|
|
|
endif()
|
2023-08-22 19:29:03 +02:00
|
|
|
endmacro()
|
2023-10-29 19:43:40 +01:00
|
|
|
|
|
|
|
macro(add_romfs_resource input output)
|
2024-06-29 19:43:24 +02:00
|
|
|
if (NOT EXISTS ${input})
|
|
|
|
message(WARNING "Resource file ${input} does not exist")
|
|
|
|
endif()
|
|
|
|
|
2023-10-29 19:43:40 +01:00
|
|
|
configure_file(${input} ${CMAKE_CURRENT_BINARY_DIR}/romfs/${output} COPYONLY)
|
|
|
|
|
|
|
|
list(APPEND LIBROMFS_RESOURCE_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/romfs)
|
2023-12-31 11:39:24 +01:00
|
|
|
endmacro()
|
|
|
|
|
|
|
|
macro (enable_plugin_feature feature)
|
|
|
|
string(TOUPPER ${feature} feature)
|
|
|
|
if (NOT (feature IN_LIST IMHEX_PLUGIN_FEATURES))
|
|
|
|
message(FATAL_ERROR "Feature ${feature} is not enabled for plugin ${IMHEX_PLUGIN_NAME}")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
remove_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=0)
|
|
|
|
add_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=1)
|
2023-10-29 19:43:40 +01:00
|
|
|
endmacro()
|