Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake Fixes #1062

Merged
merged 8 commits into from
Sep 22, 2023
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ cmake --build . --target all
| `FLAMEGPU_SHARE_USAGE_STATISTICS` | `ON`/`OFF` | Share usage statistics ([telemetry](https://docs.flamegpu.com/guide/telemetry)) to support evidencing usage/impact of the software. Default `ON`. |
| `FLAMEGPU_TELEMETRY_SUPPRESS_NOTICE` | `ON`/`OFF` | Suppress notice encouraging telemetry to be enabled, which is emitted once per binary execution if telemetry is disabled. Defaults to `OFF`, or the value of a system environment variable of the same name. |
| `FLAMEGPU_TELEMETRY_TEST_MODE` | `ON`/`OFF` | Submit telemetry values to the test mode of TelemetryDeck. Intended for use during development of FLAMEGPU rather than use. Defaults to `OFF`, or the value of a system environment variable of the same name.|
| `FLAMEGPU_ENABLE_LINT_FLAMEGPU` | `ON`/`OFF` | Enable/Disable creation of the `lint_flamegpu` target. Default `ON` if this repository is the root CMAKE_SOURCE_DIR, otherwise `OFF` |

<!-- Additional options which users can find if they need them.
| `FLAMEGPU_BUILD_API_DOCUMENTATION` | `ON`/`OFF` | Build the documentation target. Default `ON` |
Expand Down
261 changes: 198 additions & 63 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ function(flamegpu_common_compiler_settings)

# Ensure that a target has been passed, and that it is a valid target.
if(NOT CCS_TARGET)
message( FATAL_ERROR "flamegpu_common_compiler_settings: 'TARGET' argument required")
message( FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: 'TARGET' argument required")
elseif(NOT TARGET ${CCS_TARGET} )
message( FATAL_ERROR "flamegpu_common_compiler_settings: TARGET '${CCS_TARGET}' is not a valid target")
message( FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: TARGET '${CCS_TARGET}' is not a valid target")
endif()

# Enable -lineinfo for Release builds, for improved profiling output.
Expand Down Expand Up @@ -225,10 +225,142 @@ function(flamegpu_common_compiler_settings)

endfunction()

function(flamegpu_configure_rc_file)
cmake_parse_arguments(
FCRF
""
"TARGET"
""
${ARGN}
)
if(NOT FCRF_TARGET)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: 'TARGET' argument required.")
elseif(NOT TARGET ${FCRF_TARGET})
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: TARGET '${FCRF_TARGET}' is not a valid target")
endif()
if(WIN32)
# configure a rc file to set application icon
set (FLAMEGPU_ICON_PATH ${FLAMEGPU_ROOT}/cmake/flamegpu.ico)
set (PYFLAMEGPU_ICON_PATH ${FLAMEGPU_ROOT}/cmake/pyflamegpu.ico)
configure_file(
${FLAMEGPU_ROOT}/cmake/application_icon.rc.in
application_icon.rc
@ONLY)
target_sources(${FCRF_TARGET} PRIVATE application_icon.rc)
endif()
endfunction()

function(flamegpu_target_cxx17)
cmake_parse_arguments(
FTC
""
"TARGET"
""
${ARGN}
)
if(NOT FTC_TARGET)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: 'TARGET' argument required.")
elseif(NOT TARGET ${FTC_TARGET})
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: TARGET '${FTC_TARGET}' is not a valid target")
endif()
target_compile_features(${FTC_TARGET} PUBLIC cxx_std_17)
target_compile_features(${FTC_TARGET} PUBLIC cuda_std_17)
set_property(TARGET ${FTC_TARGET} PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET ${FTC_TARGET} PROPERTY CUDA_EXTENSIONS OFF)
set_property(TARGET ${FTC_TARGET} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${FTC_TARGET} PROPERTY CUDA_STANDARD_REQUIRED ON)
endfunction()

function(flamegpu_copy_runtime_dependencies)
cmake_parse_arguments(
FCRD
""
"TARGET"
""
${ARGN}
)
if(NOT FCRD_TARGET)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: 'TARGET' argument required.")
elseif(NOT TARGET ${FCRD_TARGET})
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: TARGET '${FCRD_TARGET}' is not a valid target")
endif()
if (FLAMEGPU_VISUALISATION)
# Copy DLLs / other Runtime dependencies
if(COMMAND flamegpu_visualiser_get_runtime_depenencies)
flamegpu_visualiser_get_runtime_depenencies(vis_runtime_dependencies)
# For each runtime dependency (dll)
foreach(vis_runtime_dependency ${vis_runtime_dependencies})
# Add a post build command which copies the dll to the directory of the binary if needed.
add_custom_command(
TARGET "${FCRD_TARGET}" POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${vis_runtime_dependency}"
$<TARGET_FILE_DIR:${FCRD_TARGET}>
)
endforeach()
unset(vis_runtime_dependencies)
endif()
endif()
endfunction()

function(flamegpu_setup_source_groups)
cmake_parse_arguments(
FSSG
""
""
"SRC"
${ARGN}
)
if(NOT FSSG_SRC)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: 'SRC' argument required.")
endif()

# Get a regex escaped represenatation of the current source dir, for paths containg + etc.
escape_regex("${CMAKE_CURRENT_SOURCE_DIR}" CURRENT_SOURCE_DIR_ESCAPE)

# Convert all paths to abs paths, to remove any ../ components
set(ABS_SRC "")
foreach(FILEPATH IN LISTS SRC)
get_filename_component(ABS_FILEPATH ${FILEPATH} REALPATH)
list(APPEND ABS_SRC ${ABS_FILEPATH})
unset(ABS_FILEPATH)
endforeach()

# Filter files which cannot be used with sourge_group(TREE) into separate lists.
set(SRC_GROUP_TREE_COMPATIBLE "${ABS_SRC}")
set(SRC_GROUP_MANUAL "${ABS_SRC}")
list(FILTER SRC_GROUP_TREE_COMPATIBLE INCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/")
list(FILTER SRC_GROUP_MANUAL EXCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/")
unset(ABS_SRC)

# Filter out header and source files separately for those which can use TREE
set(SRC_GROUP_TREE_COMPATIBLE_HEADERS "${SRC_GROUP_TREE_COMPATIBLE}")
list(FILTER SRC_GROUP_TREE_COMPATIBLE_HEADERS INCLUDE REGEX ".*\.(h|hpp|cuh)$")
set(SRC_GROUP_TREE_COMPATIBLE_SOURCES "${SRC_GROUP_TREE_COMPATIBLE}")
list(FILTER SRC_GROUP_TREE_COMPATIBLE_SOURCES EXCLUDE REGEX ".*\.(h|hpp|cuh)$")
# Apply source group filters with TREE, using CMake's default "Header Files" and "Source Files" for consistency
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "Header Files" FILES ${SRC_GROUP_TREE_COMPATIBLE_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "Source Files" FILES ${SRC_GROUP_TREE_COMPATIBLE_SOURCES})
# Clean up variables
unset(SRC_GROUP_TREE_COMPATIBLE_HEADERS)
unset(SRC_GROUP_TREE_COMPATIBLE_SOURCES)

# Filter out header and source files which CANNOT use TREE
set(SRC_GROUP_MANUAL_HEADERS "${SRC_GROUP_MANUAL}")
list(FILTER SRC_GROUP_MANUAL_HEADERS INCLUDE REGEX ".*\.(h|hpp|cuh)$")
set(SRC_GROUP_MANUAL_SOURCES "${SRC_GROUP_MANUAL}")
list(FILTER SRC_GROUP_MANUAL_SOURCES EXCLUDE REGEX ".*\.(h|hpp|cuh)$")
# Apply source group filters WITHOUT TREE, using CMake's default "Header Files" and "Source Files" for consistency
# These will just be placed in the root of the folder, as we cannot have a ../ type setup in sources, so no point bothering with directories
source_group("Header Files" FILES ${SRC_GROUP_MANUAL_HEADERS})
source_group("Source Files" FILES ${SRC_GROUP_MANUAL_SOURCES})
# Clean up variables
unset(SRC_GROUP_MANUAL_HEADERS)
unset(SRC_GROUP_MANUAL_SOURCES)
endfunction()

# Function to mask some of the steps to create an executable which links against the static library
function(flamegpu_add_executable NAME SRC FLAMEGPU_ROOT PROJECT_ROOT IS_EXAMPLE)
# @todo - correctly set PUBLIC/PRIVATE/INTERFACE for executables created with this utility function

# Parse optional arugments.
cmake_parse_arguments(
FLAMEGPU_ADD_EXECUTABLE
Expand All @@ -242,32 +374,17 @@ function(flamegpu_add_executable NAME SRC FLAMEGPU_ROOT PROJECT_ROOT IS_EXAMPLE)
add_subdirectory("${FLAMEGPU_ROOT}/src" "${PROJECT_ROOT}/FLAMEGPU")
endif()

if(WIN32)
# configure a rc file to set application icon
set (FLAMEGPU_ICON_PATH ${FLAMEGPU_ROOT}/cmake/flamegpu.ico)
set (PYFLAMEGPU_ICON_PATH ${FLAMEGPU_ROOT}/cmake/pyflamegpu.ico)
configure_file(
${FLAMEGPU_ROOT}/cmake/application_icon.rc.in
application_icon.rc
@ONLY)
SET(SRC ${SRC} application_icon.rc)
endif()

# Define which source files are required for the target executable
add_executable(${NAME} ${SRC})

# Add an application icon file on windows
flamegpu_configure_rc_file(TARGET "${NAME}")
# Set target level warnings.
flamegpu_enable_compiler_warnings(TARGET "${NAME}")
# Apply common compiler settings
flamegpu_common_compiler_settings(TARGET "${NAME}")

# Set C++17 using modern CMake options
target_compile_features(${NAME} PUBLIC cxx_std_17)
target_compile_features(${NAME} PUBLIC cuda_std_17)
set_property(TARGET ${NAME} PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET ${NAME} PROPERTY CUDA_EXTENSIONS OFF)
set_property(TARGET ${NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${NAME} PROPERTY CUDA_STANDARD_REQUIRED ON)
flamegpu_target_cxx17(TARGET "${NAME}")

# Enable RDC for the target
set_property(TARGET ${NAME} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
Expand All @@ -280,52 +397,70 @@ function(flamegpu_add_executable NAME SRC FLAMEGPU_ROOT PROJECT_ROOT IS_EXAMPLE)
# Provide the absolute path to the lib file, rather than the relative version cmake provides.
target_link_libraries(${NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE:flamegpu>")
endif()

# Activate visualisation if requested
if (FLAMEGPU_VISUALISATION)
# Copy DLLs / other Runtime dependencies
if(COMMAND flamegpu_visualiser_get_runtime_depenencies)
flamegpu_visualiser_get_runtime_depenencies(vis_runtime_dependencies)
# For each runtime dependency (dll)
foreach(vis_runtime_dependency ${vis_runtime_dependencies})
# Add a post build comamnd which copies the dll to the directory of the binary if needed.
add_custom_command(
TARGET "${NAME}" POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${vis_runtime_dependency}"
$<TARGET_FILE_DIR:${NAME}>
)
endforeach()
unset(vis_runtime_dependencies)
endif()
endif()

# Add post-build commands to copy runtime dependencies to the targets output location
flamegpu_copy_runtime_dependencies(TARGET "${NAME}")

# Flag the new linter target and the files to be linted, and pass optional exclusions filters (regex)
flamegpu_new_linter_target(${NAME} "${SRC}" EXCLUDE_FILTERS "${FLAMEGPU_ADD_EXECUTABLE_LINT_EXCLUDE_FILTERS}")

# Setup Visual Studio (and eclipse) filters
#src/.h
escape_regex("${CMAKE_CURRENT_SOURCE_DIR}" CURRENT_SOURCE_DIR_ESCAPE)
set(T_SRC "${SRC}")
list(FILTER T_SRC INCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/src")
list(FILTER T_SRC INCLUDE REGEX ".*\.(h|hpp|cuh)$")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX headers FILES ${T_SRC})
#src/.cpp
set(T_SRC "${SRC}")
list(FILTER T_SRC INCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/src")
list(FILTER T_SRC EXCLUDE REGEX ".*\.(h|hpp|cuh)$")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX src FILES ${T_SRC})
#./.h
set(T_SRC "${SRC}")
list(FILTER T_SRC EXCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/src")
list(FILTER T_SRC INCLUDE REGEX ".*\.(h|hpp|cuh)$")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX headers FILES ${T_SRC})
#./.cpp
set(T_SRC "${SRC}")
list(FILTER T_SRC EXCLUDE REGEX "^${CURRENT_SOURCE_DIR_ESCAPE}/src")
list(FILTER T_SRC EXCLUDE REGEX ".*\.(h|hpp|cuh|rc)$")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX src FILES ${T_SRC})
# Setup IDE (Visual Studio) filters
flamegpu_setup_source_groups(SRC ${SRC})

# Put within Examples filter
if(IS_EXAMPLE)
flamegpu_set_target_folder(${NAME} "Examples")
endif()
endfunction()


# Function to mask some of the steps to create a static library which links against the FLAMEGPU static library, i.e. to allow testable simulation implementations
function(flamegpu_add_library NAME SRC FLAMEGPU_ROOT PROJECT_ROOT IS_EXAMPLE)
# Parse optional arugments.
cmake_parse_arguments(
FLAMEGPU_ADD_EXECUTABLE
""
""
"LINT_EXCLUDE_FILTERS"
${ARGN})

# If the library does not exist as a target, add it.
if (NOT TARGET flamegpu)
add_subdirectory("${FLAMEGPU_ROOT}/src" "${PROJECT_ROOT}/FLAMEGPU")
endif()

# Define which source files are required for the target executable
add_library(${NAME} STATIC ${SRC})

# Add an application icon file on windows
flamegpu_configure_rc_file(TARGET "${NAME}")
# Set target level warnings.
flamegpu_enable_compiler_warnings(TARGET "${NAME}")
# Apply common compiler settings
flamegpu_common_compiler_settings(TARGET "${NAME}")
# Set C++17 using modern CMake options
flamegpu_target_cxx17(TARGET "${NAME}")

# Enable RDC for the target
set_property(TARGET ${NAME} PROPERTY CUDA_SEPARABLE_COMPILATION ON)

# Link against the flamegpu static library target.
target_link_libraries(${NAME} PRIVATE flamegpu)
# Workaround for incremental rebuilds on MSVC, where device link was not being performed.
# https://github.com/FLAMEGPU/FLAMEGPU2/issues/483
if(MSVC AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.1")
# Provide the absolute path to the lib file, rather than the relative version cmake provides.
target_link_libraries(${NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE:flamegpu>")
endif()

# Add post-build commands to copy runtime dependencies to the targets output location
flamegpu_copy_runtime_dependencies(TARGET "${NAME}")

# Flag the new linter target and the files to be linted, and pass optional exclusions filters (regex)
flamegpu_new_linter_target(${NAME} "${SRC}" EXCLUDE_FILTERS "${FLAMEGPU_ADD_EXECUTABLE_LINT_EXCLUDE_FILTERS}")

# Setup IDE (Visual Studio) filters
flamegpu_setup_source_groups(SRC ${SRC})

# Put within Examples filter
if(IS_EXAMPLE)
Expand Down
4 changes: 2 additions & 2 deletions cmake/cpplint.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function(flamegpu_new_linter_target NAME SRC)
endif()
# Add the lint_ target
add_custom_target(
"lint_${PROJECT_NAME}"
"lint_${NAME}"
COMMAND ${CPPLINT_EXECUTABLE} ${CPPLINT_ARGS}
${SRC}
)
Expand All @@ -95,6 +95,6 @@ function(flamegpu_new_linter_target NAME SRC)
# Put within Lint filter
if (CMAKE_USE_FOLDERS)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(TARGET "lint_${PROJECT_NAME}" PROPERTY FOLDER "Lint")
set_property(TARGET "lint_${NAME}" PROPERTY FOLDER "Lint")
endif ()
endfunction()
7 changes: 6 additions & 1 deletion cmake/dependencies/doxygen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
find_package(Doxygen OPTIONAL_COMPONENTS mscgen dia dot)
if(DOXYGEN_FOUND)
include(CMakeDependentOption)
option(FLAMEGPU_BUILD_API_DOCUMENTATION "Enable building documentation (requires Doxygen)" ON)
set(FLAMEGPU_BUILD_API_DOCUMENTATION_DEFAULT OFF)
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}" OR "${CMAKE_SOURCE_DIR}" STREQUAL "${FLAMEGPU_ROOT}")
set(FLAMEGPU_BUILD_API_DOCUMENTATION_DEFAULT ON)
endif()
option(FLAMEGPU_BUILD_API_DOCUMENTATION "Enable building documentation (requires Doxygen)" ${FLAMEGPU_BUILD_API_DOCUMENTATION_DEFAULT})

# option to hide / not hide the detail namespace from the docs, developers can enable it if they want detail docs / the actual docs website might require this due to breathe/exhale not respecting doxygen exclude correctly and not having an equivalent option.
cmake_dependent_option(FLAMEGPU_API_DOCUMENTATION_EXCLUDE_DETAIL "Exclude the detail namespace from doxygen documentation" ON "FLAMEGPU_BUILD_API_DOCUMENTATION" ON)
mark_as_advanced(FLAMEGPU_API_DOCUMENTATION_EXCLUDE_DETAIL)
Expand Down
Loading