Revision: 77468
http://sourceforge.net/p/brlcad/code/77468
Author: starseeker
Date: 2020-10-17 14:27:00 +0000 (Sat, 17 Oct 2020)
Log Message:
-----------
Replace manual tracking of build target sets with use of new CMake properties.
Significantly reduces (but doesn't yet eliminate) our use of the discouraged
practice of CMake function redefinition.
Modified Paths:
--------------
brlcad/trunk/CMakeLists.txt
Modified: brlcad/trunk/CMakeLists.txt
===================================================================
--- brlcad/trunk/CMakeLists.txt 2020-10-17 04:41:17 UTC (rev 77467)
+++ brlcad/trunk/CMakeLists.txt 2020-10-17 14:27:00 UTC (rev 77468)
@@ -79,7 +79,7 @@
# BRL-CAD software package.
# Minimum required version of CMake
-cmake_minimum_required(VERSION 3.1.3)
+cmake_minimum_required(VERSION 3.7.2)
# set CMake project name
project(BRLCAD)
@@ -365,71 +365,18 @@
# once the logic for both jobs is intertwined below.
if(NOT BRLCAD_IS_SUBBUILD)
- # Functions in CMake have local variable scope,
- # hence the use of properties to allow access to directory-specific
- # and global information scopes.
- define_property(GLOBAL PROPERTY CMAKE_LIBRARY_TARGET_LIST BRIEF_DOCS
"libtarget list" FULL_DOCS "Library target list")
- define_property(GLOBAL PROPERTY CMAKE_EXEC_TARGET_LIST BRIEF_DOCS "exec
target list" FULL_DOCS "Executable target list")
- define_property(GLOBAL PROPERTY CMAKE_CUSTOM_TARGET_LIST BRIEF_DOCS "custom
target list" FULL_DOCS "Custom target list")
- define_property(GLOBAL PROPERTY CMAKE_EXTERNAL_TARGET_LIST BRIEF_DOCS
"external target list" FULL_DOCS "External target list")
- mark_as_advanced(CMAKE_LIBRARY_TARGET_LIST)
- mark_as_advanced(CMAKE_EXEC_TARGET_LIST)
- mark_as_advanced(CMAKE_CUSTOM_TARGET_LIST)
- mark_as_advanced(CMAKE_EXTERNAL_TARGET_LIST)
- # Override and wrap add_library. While we're at it, avoid doubling up
- # on the lib prefix for libraries if the target name is lib<target>
+ # Override and wrap add_library. Avoid doubling up on the lib prefix for
+ # libraries if the target name is lib<target>.
+ #
+ # TODO - move this to BRLCAD_ADDLIB, avoid the redefinition
function(add_library name)
_add_library(${name} ${ARGN})
if(${name} MATCHES "^lib*")
set_target_properties(${name} PROPERTIES PREFIX "")
endif(${name} MATCHES "^lib*")
-
- # TODO - the mechanism below should eventually be replaced by a proper
- # feature in CMake, but it is as yet unimplemented:
- # https://cmake.org/pipermail/cmake-developers/2015-July/025682.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027985.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027993.html
- set(add_lib_to_list 1)
- foreach(libarg ${ARGN})
- if("${libarg}" STREQUAL "INTERFACE")
- set(add_lib_to_list 0)
- endif("${libarg}" STREQUAL "INTERFACE")
- endforeach(libarg ${ARGN})
- if (add_lib_to_list)
- set_property(GLOBAL APPEND PROPERTY CMAKE_LIBRARY_TARGET_LIST ${name})
- endif (add_lib_to_list)
endfunction(add_library)
- # Override and wrap add_executable
- function(add_executable name)
- _add_executable(${name} ${ARGN})
-
- # TODO - the mechanism below should eventually be replaced by a proper
- # feature in CMake, but it is as yet unimplemented:
- # https://cmake.org/pipermail/cmake-developers/2015-July/025682.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027985.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027993.html
- set_property(GLOBAL APPEND PROPERTY CMAKE_EXEC_TARGET_LIST ${name})
- endfunction(add_executable)
-
- # Override and wrap add_custom_target
- function(add_custom_target name)
- _add_custom_target(${name} ${ARGN})
-
- # TODO - the mechanism below should eventually be replaced by a proper
- # feature in CMake, but it is as yet unimplemented:
- # https://cmake.org/pipermail/cmake-developers/2015-July/025682.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027985.html
- # https://cmake.org/pipermail/cmake-developers/2016-March/027993.html
- set_property(GLOBAL APPEND PROPERTY CMAKE_CUSTOM_TARGET_LIST ${name})
- endfunction(add_custom_target)
-
- # Note that at the moment we do not need to override CMake's external
- # project mechanisms because CMake does not use them, but if that changes
- # in the future an override will need to be added here - probably of the
- # ExternalProject_Add functionality.
-
# Override and wrap configure_file. In the case of configure_file, we'll
# check that the file is part of the source tree and not itself a
# generated file, but not reject full-path entries since there are quite a
@@ -3385,65 +3332,66 @@
set_target_properties(buildtimedelta PROPERTIES FOLDER "Compilation
Utilities")
endif(NOT BRLCAD_IS_SUBBUILD)
-# We want the timestamp to come first, so make ALL targets, depend on
-# timestamp. Similarly, buildtimedelta needs to depend on every target
-# not excluded from the default build list.
-if(NOT BRLCAD_IS_SUBBUILD)
+#------------------------------------------------------------------------------
+# We want the timestamp to come first, so make all targets depend on timestamp.
+# Similarly, buildtimedelta needs to depend on every target not excluded from
+# the default build list. Doing this without function overrides for
+# bookkeeping drives a minimum CMake version requirement of 3.7, in order to
+# get the SUBDIRECTORIES and BUILDSYTEM_TARGETS properties.
- # Libraries and executables are fairly straightforward
- get_property(CMAKE_LIBRARY_TARGET_LIST GLOBAL PROPERTY
CMAKE_LIBRARY_TARGET_LIST)
- get_property(CMAKE_EXEC_TARGET_LIST GLOBAL PROPERTY CMAKE_EXEC_TARGET_LIST)
- mark_as_advanced(CMAKE_LIBRARY_TARGET_LIST)
- mark_as_advanced(CMAKE_EXEC_TARGET_LIST)
- list(REMOVE_DUPLICATES CMAKE_LIBRARY_TARGET_LIST)
- list(REMOVE_DUPLICATES CMAKE_EXEC_TARGET_LIST)
- foreach(ctarget ${CMAKE_LIBRARY_TARGET_LIST} ${CMAKE_EXEC_TARGET_LIST})
- if(TARGET ${ctarget})
- add_dependencies(${ctarget} timestamp)
- get_target_property(not_in_all ${ctarget} EXCLUDE_FROM_ALL)
- get_target_property(not_in_default ${ctarget} EXCLUDE_FROM_DEFAULT_BUILD)
- if(NOT not_in_all AND NOT not_in_default)
- add_dependencies(buildtimedelta ${ctarget})
- endif(NOT not_in_all AND NOT not_in_default)
- endif(TARGET ${ctarget})
- endforeach(ctarget ${CMAKE_LIBRARY_TARGET_LIST} ${CMAKE_EXEC_TARGET_LIST})
+# First, use the SUBDIRECTORIES property to build up a list of all
+# active directories in CMake:
+# https://cmake.org/cmake/help/latest/prop_dir/SUBDIRECTORIES.html
+#
+# We do this because we need to use get_property on them, and get_property will
+# produce an error if we give it a non-CMake processed directory. As a side
+# benefit, it should also be considerably faster than using FILE_GLOB and
+# trying to trim down the results.
+set(ALL_DIRS)
+get_property(SUBDIRS DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY SUBDIRECTORIES)
+while(SUBDIRS)
+ # TODO - once we require 3.15.7 or greater, use list(POP_FRONT) for this...
+ list(GET SUBDIRS 0 CDIR)
+ list(REMOVE_AT SUBDIRS 0)
+ set(ALL_DIRS ${ALL_DIRS} ${CDIR})
+ get_property(CSUBDIRS DIRECTORY "${CDIR}" PROPERTY SUBDIRECTORIES)
+ set(SUBDIRS ${SUBDIRS} ${CSUBDIRS})
+endwhile(SUBDIRS)
- # For the custom targets, we need to avoid circular dependencies
- get_property(CMAKE_CUSTOM_TARGET_LIST GLOBAL PROPERTY
CMAKE_CUSTOM_TARGET_LIST)
- mark_as_advanced(CMAKE_CUSTOM_TARGET_LIST)
- list(REMOVE_DUPLICATES CMAKE_CUSTOM_TARGET_LIST)
- foreach(custtarget ${CMAKE_CUSTOM_TARGET_LIST})
- if(NOT ${custtarget} MATCHES "timestamp")
- add_dependencies(${custtarget} timestamp)
- endif(NOT ${custtarget} MATCHES "timestamp")
- if(NOT ${custtarget} MATCHES "buildtimedelta")
- get_target_property(not_in_all ${custtarget} EXCLUDE_FROM_ALL)
- get_target_property(not_in_default ${custtarget}
EXCLUDE_FROM_DEFAULT_BUILD)
- if(NOT not_in_all AND NOT not_in_default)
- add_dependencies(buildtimedelta ${custtarget})
- endif(NOT not_in_all AND NOT not_in_default)
- endif(NOT ${custtarget} MATCHES "buildtimedelta")
- endforeach(custtarget ${CMAKE_CUSTOM_TARGET_LIST})
+# Next, for all active directories, collect the list of targets using the
+# BUILDSYSTEM_TARGETS property set on each directory.
- # Theoretical logic to handle external targets - not currently in use
- get_property(CMAKE_EXTERNAL_TARGET_LIST GLOBAL PROPERTY
CMAKE_EXTERNAL_TARGET_LIST)
- mark_as_advanced(CMAKE_EXTERNAL_TARGET_LIST)
- if(CMAKE_EXTERNAL_TARGET_LIST)
- list(REMOVE_DUPLICATES CMAKE_EXTERNAL_TARGET_LIST)
- endif(CMAKE_EXTERNAL_TARGET_LIST)
- foreach(externaltarget ${CMAKE_EXTERNAL_TARGET_LIST})
- get_target_property(target_confcmd ${externaltarget} _EP_CONFIGURE_COMMAND)
- if(target_confcmd)
- add_dependencies(${externaltarget} timestamp)
- add_dependencies(buildtimedelta ${externaltarget})
- endif(target_confcmd)
- endforeach(externaltarget ${CMAKE_EXTERNAL_TARGET_LIST})
+# Iterate over all the SUBDIRECTORIES identified directories to build up the
+# comprehensive set. As target names are unique, we don't need to worry about
+# removing duplicates. Because we're using the set of all active directories
+# assembled above, this should collect all build targets we need to care about
+# for timestamping purposes.
+set(ALL_TARGETS)
+foreach(ad ${ALL_DIRS})
+ get_property(DIR_TARGETS DIRECTORY "${ad}" PROPERTY BUILDSYSTEM_TARGETS SET)
+ if (DIR_TARGETS)
+ get_property(DIR_TARGETS DIRECTORY "${ad}" PROPERTY BUILDSYSTEM_TARGETS)
+ set(ALL_TARGETS ${ALL_TARGETS} ${DIR_TARGETS})
+ endif (DIR_TARGETS)
+endforeach(ad ${ALL_DIRS})
-endif(NOT BRLCAD_IS_SUBBUILD)
+# Now, set up the target dependencies for tiemstamp and buildtimedelta. These
+# dependencies will produce a build-tool-independent ordering that gives us the
+# timing behavior we want.
+foreach(ctarget ${ALL_TARGETS})
+ if(NOT ${ctarget} MATCHES "timestamp")
+ add_dependencies(${ctarget} timestamp)
+ endif(NOT ${ctarget} MATCHES "timestamp")
+ if(NOT ${ctarget} MATCHES "buildtimedelta")
+ get_target_property(not_in_all ${ctarget} EXCLUDE_FROM_ALL)
+ get_target_property(not_in_default ${ctarget} EXCLUDE_FROM_DEFAULT_BUILD)
+ if(NOT not_in_all AND NOT not_in_default)
+ add_dependencies(buildtimedelta ${ctarget})
+ endif(NOT not_in_all AND NOT not_in_default)
+ endif(NOT ${ctarget} MATCHES "buildtimedelta")
+endforeach(ctarget ${ALL_TARGETS})
-
-# TODO - the below logic will have to be rethought in a superbuild setup...
-
+#------------------------------------------------------------------------------
# To set correct install paths for CMake at build time, rather than CMake
# time, some rather special logic is necessary - a build target that needs
# to be run when the current build type changes, and introspective scripting
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits