150 lines
5.1 KiB
CMake
150 lines
5.1 KiB
CMake
|
|
||
|
option(IMHEX_IDE_HELPERS_OVERRIDE_XCODE_COMPILER "Enable choice of compiler for Xcode builds, despite CMake's best efforts" OFF)
|
||
|
option(IMHEX_IDE_HELPERS_INTRUSIVE_IDE_TWEAKS "Enable intrusive CMake tweaks to better support IDEs with folder support" OFF)
|
||
|
|
||
|
# The CMake infrastructure silently ignores the CMAKE_<>_COMPILER settings when
|
||
|
# using the `Xcode` generator.
|
||
|
#
|
||
|
# A particularly nasty (and potentially only) way of getting around this is to
|
||
|
# temporarily lie about the generator being used, while CMake determines and
|
||
|
# locks in the compiler to use.
|
||
|
#
|
||
|
# Needless to say, this is hacky and fragile. Use at your own risk!
|
||
|
if (IMHEX_IDE_HELPERS_OVERRIDE_XCODE_COMPILER AND CMAKE_GENERATOR STREQUAL "Xcode")
|
||
|
set(CMAKE_GENERATOR "Unknown")
|
||
|
enable_language(C CXX)
|
||
|
|
||
|
set(CMAKE_GENERATOR "Xcode")
|
||
|
|
||
|
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_C_COMPILER}")
|
||
|
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CXX_COMPILER}")
|
||
|
|
||
|
if (CLANG)
|
||
|
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}")
|
||
|
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")
|
||
|
endif()
|
||
|
|
||
|
# By default Xcode passes a `-index-store-path=<...>` parameter to the compiler
|
||
|
# during builds to build code completion indexes. This is not supported by
|
||
|
# anything other than AppleClang
|
||
|
set(CMAKE_XCODE_ATTRIBUTE_COMPILER_INDEX_STORE_ENABLE "NO")
|
||
|
endif()
|
||
|
|
||
|
# Generate a launch/build scheme for all targets
|
||
|
set(CMAKE_XCODE_GENERATE_SCHEME YES)
|
||
|
|
||
|
# Utility function that helps avoid messing with non-standard targets
|
||
|
macro(returnIfTargetIsNonTweakable target)
|
||
|
get_target_property(targetIsAliased ${target} ALIASED_TARGET)
|
||
|
get_target_property(targetIsImported ${target} IMPORTED)
|
||
|
|
||
|
if (targetIsAliased OR targetIsImported)
|
||
|
return()
|
||
|
endif()
|
||
|
|
||
|
get_target_property(targetType ${target} TYPE)
|
||
|
if (targetType MATCHES "INTERFACE_LIBRARY|UNKNOWN_LIBRARY")
|
||
|
return()
|
||
|
endif()
|
||
|
endmacro()
|
||
|
|
||
|
# Targets usually don't specify their private headers, nor group their source files
|
||
|
# which results in very spotty coverage by IDEs with folders support
|
||
|
#
|
||
|
# Unfortunately, CMake does not have a `target_source_group` like construct yet, therefore
|
||
|
# we have to play by the limitations of `source_group`.
|
||
|
#
|
||
|
# A particularly problematic part is that the function must be called within the directoryies
|
||
|
# scope for the grouping to take effect.
|
||
|
#
|
||
|
# See: https://discourse.cmake.org/t/topic/7388
|
||
|
function(tweakTargetForIDESupport target)
|
||
|
returnIfTargetIsNonTweakable(${target})
|
||
|
|
||
|
# Don't assume directory structure of third parties
|
||
|
get_target_property(targetSourceDir ${target} SOURCE_DIR)
|
||
|
if (targetSourceDir MATCHES "third_party")
|
||
|
return()
|
||
|
endif()
|
||
|
|
||
|
# Add headers to target
|
||
|
get_target_property(targetSourceDir ${target} SOURCE_DIR)
|
||
|
if (targetSourceDir)
|
||
|
file(GLOB_RECURSE targetPrivateHeaders CONFIGURE_DEPENDS "${targetSourceDir}/include/*.hpp")
|
||
|
|
||
|
target_sources(${target} PRIVATE "${targetPrivateHeaders}")
|
||
|
endif()
|
||
|
|
||
|
# Organize target sources into directory tree
|
||
|
get_target_property(sources ${target} SOURCES)
|
||
|
foreach(file IN LISTS sources)
|
||
|
get_filename_component(path "${file}" ABSOLUTE)
|
||
|
|
||
|
if (NOT path MATCHES "^${targetSourceDir}")
|
||
|
continue()
|
||
|
endif()
|
||
|
|
||
|
source_group(TREE "${targetSourceDir}" PREFIX "Source Tree" FILES "${file}")
|
||
|
endforeach()
|
||
|
endfunction()
|
||
|
|
||
|
if (IMHEX_IDE_HELPERS_INTRUSIVE_IDE_TWEAKS)
|
||
|
# See tweakTargetForIDESupport for rationale
|
||
|
|
||
|
function(add_library target)
|
||
|
_add_library(${target} ${ARGN})
|
||
|
|
||
|
tweakTargetForIDESupport(${target})
|
||
|
endfunction()
|
||
|
|
||
|
function(add_executable target)
|
||
|
_add_executable(${target} ${ARGN})
|
||
|
|
||
|
tweakTargetForIDESupport(${target})
|
||
|
endfunction()
|
||
|
endif()
|
||
|
|
||
|
# Adjust target's FOLDER property, which is an IDE only preference
|
||
|
function(_tweakTarget target path)
|
||
|
get_target_property(targetType ${target} TYPE)
|
||
|
|
||
|
if (TARGET generator-${target})
|
||
|
set_target_properties(generator-${target} PROPERTIES FOLDER "romfs/${target}")
|
||
|
endif()
|
||
|
if (TARGET romfs_file_packer-${target})
|
||
|
set_target_properties(romfs_file_packer-${target} PROPERTIES FOLDER "romfs/${target}")
|
||
|
endif()
|
||
|
if (TARGET libromfs-${target})
|
||
|
set_target_properties(libromfs-${target} PROPERTIES FOLDER "romfs/${target}")
|
||
|
endif()
|
||
|
|
||
|
if (${targetType} MATCHES "EXECUTABLE|LIBRARY")
|
||
|
set_target_properties(${target} PROPERTIES FOLDER "${path}")
|
||
|
endif()
|
||
|
endfunction()
|
||
|
|
||
|
macro(_tweakTargetsRecursive dir)
|
||
|
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
|
||
|
foreach(subdir IN LISTS subdirectories)
|
||
|
_tweakTargetsRecursive("${subdir}")
|
||
|
endforeach()
|
||
|
|
||
|
if(${dir} STREQUAL ${CMAKE_SOURCE_DIR})
|
||
|
return()
|
||
|
endif()
|
||
|
|
||
|
get_property(targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
|
||
|
file(RELATIVE_PATH rdir ${CMAKE_SOURCE_DIR} "${dir}/..")
|
||
|
|
||
|
foreach(target ${targets})
|
||
|
_tweakTarget(${target} "${rdir}")
|
||
|
endforeach()
|
||
|
endmacro()
|
||
|
|
||
|
# Tweak all targets this CMake build is aware about
|
||
|
function(tweakTargetsForIDESupport)
|
||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||
|
|
||
|
_tweakTargetsRecursive("${CMAKE_SOURCE_DIR}")
|
||
|
endfunction()
|