Use Ceres_[SOURCE/BINARY]_DIR not CMAKE_XXX_DIR to support nesting.
- Using Ceres_[SOURCE/BINARY]_DIR (which are defined by CMake when
project(Ceres) is called, in favour of CMAKE_[SOURCE/BINARY]_DIR
enables Ceres to be nested within (and built by) a larger CMake
project (which also contains other projects).
- CMAKE_[SOURCE/BINARY]_DIR always refers to the top-level source
and binary directories (i.e. the first encountered), as a result if
Ceres is a nested project within a larger project, these would not
correctly identify the source/binary directories for Ceres (as they
would refer to the root project in which Ceres is nested).
- Using Ceres_[SOURCE/BINARY]_DIR should ensure that Ceres always uses
the correct source/binary directories, irrespective of whether Ceres
is nested or not.
Change-Id: I62226ea3f6552b1d7e2bdac1aef02f1f489ae55e
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf5f845..a782c34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,15 +39,24 @@
project(Ceres C CXX)
+# NOTE: The 'generic' CMake variables CMAKE_[SOURCE/BINARY]_DIR should not be
+# used. Always use the project-specific variants (generated by CMake):
+# <PROJECT_NAME_MATCHING_CASE>_[SOURCE/BINARY]_DIR, e.g.
+# Ceres_SOURCE_DIR (note, *not* CERES_SOURCE_DIR) instead, as these will
+# always point to the correct directories for the Ceres project, even if
+# it is nested inside another source tree, whereas the 'generic'
+# CMake variables refer to the *first* project() declaration, i.e. the
+# top-level project, not Ceres, if Ceres is nested.
+
# Make CMake aware of the cmake folder for local FindXXX scripts,
# append rather than set in case the user has passed their own
# additional paths via -D.
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+list(APPEND CMAKE_MODULE_PATH "${Ceres_SOURCE_DIR}/cmake")
include(UpdateCacheVariable)
# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
include(AddGerritCommitHook)
-add_gerrit_commit_hook()
+add_gerrit_commit_hook(${Ceres_SOURCE_DIR} ${Ceres_BINARY_DIR})
# On OS X, add the Homebrew prefix to the set of prefixes searched by
# CMake in find_path & find_library. This should ensure that we can
@@ -67,9 +76,9 @@
endif()
endif()
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/bin)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Ceres_BINARY_DIR}/lib)
# Set postfixes for generated libraries based on buildtype.
set(CMAKE_RELEASE_POSTFIX "")
set(CMAKE_DEBUG_POSTFIX "-debug")
@@ -77,7 +86,7 @@
# Read the Ceres version from the source, such that we only ever have a single
# definition of the Ceres version.
include(ReadCeresVersionFromSource)
-read_ceres_version_from_source(${CMAKE_SOURCE_DIR})
+read_ceres_version_from_source(${Ceres_SOURCE_DIR})
enable_testing()
@@ -724,13 +733,13 @@
list(REMOVE_DUPLICATES CERES_COMPILE_OPTIONS)
include(CreateCeresConfig)
create_ceres_config("${CERES_COMPILE_OPTIONS}"
- ${CMAKE_BINARY_DIR}/config/ceres/internal)
+ ${Ceres_BINARY_DIR}/config/ceres/internal)
# Force the location containing the configured config.h to the front of the
# include_directories list (by default it is appended to the back) to ensure
# that if the user has an installed version of Ceres in the same location as one
# of the dependencies (e.g. /usr/local) that we find the config.h we just
# configured, not the (older) installed config.h.
-include_directories(BEFORE ${CMAKE_BINARY_DIR}/config)
+include_directories(BEFORE ${Ceres_BINARY_DIR}/config)
add_subdirectory(internal/ceres)
@@ -758,21 +767,21 @@
endif (BUILD_EXAMPLES)
# Setup installation of Ceres public headers.
-file(GLOB CERES_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/*.h)
+file(GLOB CERES_HDRS ${Ceres_SOURCE_DIR}/include/ceres/*.h)
install(FILES ${CERES_HDRS} DESTINATION include/ceres)
-file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_SOURCE_DIR}/include/ceres/internal/*.h)
+file(GLOB CERES_PUBLIC_INTERNAL_HDRS ${Ceres_SOURCE_DIR}/include/ceres/internal/*.h)
install(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION include/ceres/internal)
# Also setup installation of Ceres config.h configured with the current
# build options into the installed headers directory.
-install(FILES ${CMAKE_BINARY_DIR}/config/ceres/internal/config.h
+install(FILES ${Ceres_BINARY_DIR}/config/ceres/internal/config.h
DESTINATION include/ceres/internal)
if (MINIGLOG)
# Install miniglog header if being used as logging #includes appear in
# installed public Ceres headers.
- install(FILES ${CMAKE_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
+ install(FILES ${Ceres_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h
DESTINATION include/ceres/internal/miniglog/glog)
endif (MINIGLOG)
@@ -805,8 +814,8 @@
# Create a CeresConfigVersion.cmake file containing the version information,
# used by both export() & install().
-configure_file("${CMAKE_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
- "${CMAKE_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
+configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfigVersion.cmake.in"
+ "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake" @ONLY)
# Install method #1: Put Ceres in CMAKE_INSTALL_PREFIX: /usr/local or equivalent.
@@ -838,31 +847,31 @@
#
# NOTE: The -install suffix is necessary to distinguish the install version from
# the exported version, which must be named CeresConfig.cmake in
-# CMAKE_BINARY_DIR to be detected. The suffix is removed when
+# Ceres_BINARY_DIR to be detected. The suffix is removed when
# it is installed.
set(SETUP_CERES_CONFIG_FOR_INSTALLATION TRUE)
-configure_file("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
- "${CMAKE_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
+configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
+ "${Ceres_BINARY_DIR}/CeresConfig-install.cmake" @ONLY)
# Install the configuration files into the same directory as the autogenerated
# CeresTargets.cmake file. We include the find_package() scripts for libraries
# whose headers are included in the public API of Ceres and should thus be
# present in CERES_INCLUDE_DIRS.
-install(FILES "${CMAKE_BINARY_DIR}/CeresConfig-install.cmake"
+install(FILES "${Ceres_BINARY_DIR}/CeresConfig-install.cmake"
RENAME CeresConfig.cmake
DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
-install(FILES "${CMAKE_BINARY_DIR}/CeresConfigVersion.cmake"
- "${CMAKE_SOURCE_DIR}/cmake/FindEigen.cmake"
- "${CMAKE_SOURCE_DIR}/cmake/FindGlog.cmake"
- "${CMAKE_SOURCE_DIR}/cmake/FindGflags.cmake"
+install(FILES "${Ceres_BINARY_DIR}/CeresConfigVersion.cmake"
+ "${Ceres_SOURCE_DIR}/cmake/FindEigen.cmake"
+ "${Ceres_SOURCE_DIR}/cmake/FindGlog.cmake"
+ "${Ceres_SOURCE_DIR}/cmake/FindGflags.cmake"
DESTINATION ${RELATIVE_CMAKECONFIG_INSTALL_DIR})
# Create an uninstall target to remove all installed files.
-configure_file("${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in"
- "${CMAKE_BINARY_DIR}/cmake/uninstall.cmake"
+configure_file("${Ceres_SOURCE_DIR}/cmake/uninstall.cmake.in"
+ "${Ceres_BINARY_DIR}/cmake/uninstall.cmake"
@ONLY)
add_custom_target(uninstall
- COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/uninstall.cmake)
+ COMMAND ${CMAKE_COMMAND} -P ${Ceres_BINARY_DIR}/cmake/uninstall.cmake)
# Install method #2: Put Ceres build into local CMake registry.
#
@@ -874,18 +883,18 @@
# Save the relative path from the build directory to the source directory.
file(RELATIVE_PATH INSTALL_ROOT_REL_CONFIG_INSTALL_DIR
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR})
+ ${Ceres_BINARY_DIR}
+ ${Ceres_SOURCE_DIR})
# Analogously to install(EXPORT ...), export the Ceres target from the build
# directory as a package called Ceres into the local CMake package registry.
- export(TARGETS ceres FILE ${CMAKE_BINARY_DIR}/CeresTargets.cmake)
+ export(TARGETS ceres FILE ${Ceres_BINARY_DIR}/CeresTargets.cmake)
export(PACKAGE ${CMAKE_PROJECT_NAME})
# Configure a CeresConfig.cmake file for the export of the Ceres build
# directory from the template, reflecting the current build options.
set(SETUP_CERES_CONFIG_FOR_INSTALLATION FALSE)
- configure_file("${CMAKE_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
- "${CMAKE_BINARY_DIR}/CeresConfig.cmake" @ONLY)
+ configure_file("${Ceres_SOURCE_DIR}/cmake/CeresConfig.cmake.in"
+ "${Ceres_BINARY_DIR}/CeresConfig.cmake" @ONLY)
endif (EXPORT_BUILD_DIR)
diff --git a/cmake/AddGerritCommitHook.cmake b/cmake/AddGerritCommitHook.cmake
index 071e84a..4347028 100644
--- a/cmake/AddGerritCommitHook.cmake
+++ b/cmake/AddGerritCommitHook.cmake
@@ -30,20 +30,28 @@
# alexs.mac@gmail.com (Alex Stewart)
# Set up the git hook to make Gerrit Change-Id: lines in commit messages.
-function(ADD_GERRIT_COMMIT_HOOK)
+function(ADD_GERRIT_COMMIT_HOOK SOURCE_DIR BINARY_DIR)
+ if (NOT EXISTS ${SOURCE_DIR} AND IS_DIRECTORY ${SOURCE_DIR})
+ message(FATAL_ERROR "Specified SOURCE_DIR: ${SOURCE_DIR} does not exist, "
+ "or is not a directory, cannot add Gerrit commit hook.")
+ endif()
+ if (NOT EXISTS ${BINARY_DIR} AND IS_DIRECTORY ${BINARY_DIR})
+ message(FATAL_ERROR "Specified BINARY_DIR: ${BINARY_DIR} does not exist, "
+ "or is not a directory, cannot add Gerrit commit hook.")
+ endif()
unset (LOCAL_GIT_DIRECTORY)
- if (EXISTS ${CMAKE_SOURCE_DIR}/.git)
- if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
+ if (EXISTS ${SOURCE_DIR}/.git)
+ if (IS_DIRECTORY ${SOURCE_DIR}/.git)
# .git directory can be found on Unix based system, or on Windows with
# Git Bash (shipped with msysgit).
- set (LOCAL_GIT_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
- else(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
+ set (LOCAL_GIT_DIRECTORY ${SOURCE_DIR}/.git)
+ else(IS_DIRECTORY ${SOURCE_DIR}/.git)
# .git is a file, this means Ceres is a git submodule of another project
# and our .git file contains the path to the git directory which manages
# Ceres, so we should add the gerrit hook there.
- file(READ ${CMAKE_SOURCE_DIR}/.git GIT_SUBMODULE_FILE_CONTENTS)
+ file(READ ${SOURCE_DIR}/.git GIT_SUBMODULE_FILE_CONTENTS)
# Strip any trailing newline characters, s/t we get a valid path.
- string(REGEX REPLACE "gitdir:[ ]*([^$].*)[\n].*" "${CMAKE_SOURCE_DIR}/\\1"
+ string(REGEX REPLACE "gitdir:[ ]*([^$].*)[\n].*" "${SOURCE_DIR}/\\1"
GIT_SUBMODULE_GIT_DIRECTORY_PATH "${GIT_SUBMODULE_FILE_CONTENTS}")
get_filename_component(GIT_SUBMODULE_GIT_DIRECTORY_PATH
"${GIT_SUBMODULE_GIT_DIRECTORY_PATH}" ABSOLUTE)
@@ -52,9 +60,9 @@
set(LOCAL_GIT_DIRECTORY "${GIT_SUBMODULE_GIT_DIRECTORY_PATH}")
endif()
endif()
- else (EXISTS ${CMAKE_SOURCE_DIR}/.git)
+ else (EXISTS ${SOURCE_DIR}/.git)
# TODO(keir) Add proper Windows support.
- endif (EXISTS ${CMAKE_SOURCE_DIR}/.git)
+ endif (EXISTS ${SOURCE_DIR}/.git)
if (EXISTS ${LOCAL_GIT_DIRECTORY})
if (NOT EXISTS ${LOCAL_GIT_DIRECTORY}/hooks/commit-msg)
@@ -62,10 +70,10 @@
"commit hook for Gerrit to: ${LOCAL_GIT_DIRECTORY}")
# Download the hook only if it is not already present.
file(DOWNLOAD https://ceres-solver-review.googlesource.com/tools/hooks/commit-msg
- ${CMAKE_BINARY_DIR}/commit-msg)
+ ${BINARY_DIR}/commit-msg)
# Make the downloaded file executable, since it is not by default.
- file(COPY ${CMAKE_BINARY_DIR}/commit-msg
+ file(COPY ${BINARY_DIR}/commit-msg
DESTINATION ${LOCAL_GIT_DIRECTORY}/hooks/
FILE_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
diff --git a/docs/source/CMakeLists.txt b/docs/source/CMakeLists.txt
index 0f07a5b..70bf998 100644
--- a/docs/source/CMakeLists.txt
+++ b/docs/source/CMakeLists.txt
@@ -1,7 +1,7 @@
find_package(Sphinx REQUIRED)
# HTML output directory
-set(SPHINX_HTML_DIR "${CMAKE_BINARY_DIR}/docs/html")
+set(SPHINX_HTML_DIR "${Ceres_BINARY_DIR}/docs/html")
# Install documentation
install(DIRECTORY ${SPHINX_HTML_DIR}
@@ -12,8 +12,8 @@
# Building using 'make_docs.py' python script
add_custom_target(ceres_docs ALL
python
- "${CMAKE_SOURCE_DIR}/scripts/make_docs.py"
- "${CMAKE_SOURCE_DIR}"
- "${CMAKE_BINARY_DIR}/docs"
+ "${Ceres_SOURCE_DIR}/scripts/make_docs.py"
+ "${Ceres_SOURCE_DIR}"
+ "${Ceres_BINARY_DIR}/docs"
"${SPHINX_EXECUTABLE}"
COMMENT "Building HTML documentation with Sphinx")
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 6eb6979..4159e39 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -294,7 +294,7 @@
add_test(NAME ${NAME}_test
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test
--test_srcdir
- ${CMAKE_SOURCE_DIR}/data)
+ ${Ceres_SOURCE_DIR}/data)
endmacro (CERES_TEST)
ceres_test(array_utils)