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

Create YCMBootstrapFetch to permit projects to bootstrap YCM using FetchContent #403

Merged
merged 9 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased Minor]

### Added
* Added new find module `FindSOXR.cmake` for libsoxr (https://github.com/robotology/ycm/pull/385)
* Added new find module `FindSOXR.cmake` for libsoxr (https://github.com/robotology/ycm/pull/385).
* Add new `YCMBootstrapFetch.cmake` module that substitutes the `YCMBootstrap.cmake` module (https://github.com/robotology/ycm/pull/403). The new `YCMBootstrapFetch.cmake` script to permit projects to bootstrap YCM by just using `FetchContent` module. A different file is created as the semantics of this new bootstrap script is a bit different, as it just make YCM available in the project, but it does not also adds it as a subproject in the superbuild sense. Superbuilds that want to switch from `YCMBootstrap.cmake` to `YCMBootstrapFetch.cmake` need to create `BuildYCM.cmake` script, and appropriately call `find_or_build_package(YCM)`, as done for example in the robotology-superbuild in https://github.com/robotology/robotology-superbuild/pull/1078 .

### Changed
* CMake 3.16 or later is now required (https://github.com/robotology/ycm/pull/386).
* The `CMakeRC` module is imported again from the official repository, and it no longer prints the debug message (https://github.com/robotology/ycm/pull/384).

### Deprecated
* The `YCMBootstrap.cmake` module is now deprecated (https://github.com/robotology/ycm/pull/403).

### Removed
* Removed `FindEigen3.cmake` module (https://github.com/robotology/ycm/pull/399).

Expand Down
6 changes: 3 additions & 3 deletions help/manual/ycm-superbuild-example.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Create a ``CMakeLists.txt`` with this content:

# Choose whether you want YCM to be a soft or a hard dependency and uncomment
# the appropriate line:
include(YCMBootstrap) # This will make it a soft dependency
include(YCMBootstrapFetch) # This will make it a soft dependency
# find_package(YCM 0.1 REQUIRED) # This will make it a hard dependency

include(FindOrBuildPackage)
Expand All @@ -125,12 +125,12 @@ Create a ``cmake`` folder that will contain all required CMake modules
mkdir cmake

If you want YCM as a soft dependency you will need to get the files
``tools/YCMBootstrap.cmake`` and ``modules/IncludeUrl.cmake`` from the YCM
``tools/YCMBootstrapFetch.cmake`` from the YCM
sources. If you want to make it a hard dependency you don't have to add these
files, but the user will have to install YCM before he can build the superbuild.

.. note:
If the user has YCM installed, ``YCMBootstrap`` will find it and will
If the user has YCM installed, ``YCMBootstrapFetch`` will find it and will
not download it again, but it will use the user's installation.

Create the files ``cmake/BuildTemplatePkg.cmake`` and
Expand Down
9 changes: 4 additions & 5 deletions help/manual/ycm-using.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,15 @@ Using YCM as Soft Dependency
----------------------------

In order to make it a soft dependency, you will need to get the files
``tools/YCMBootstrap.cmake`` and ``modules/IncludeUrl.cmake`` from the YCM
``tools/YCMBootstrapFetch.cmake`` from the YCM
sources (see :manual:`ycm-installing(7)` for instructions on how to download
YCM) and copy them inside your project tree:

.. code-block:: sh

cd <YOUR_PROJECT_DIR>
mkdir cmake
cp <PATH_TO_YCM_SOURCES>/tools/YCMBootstrap.cmake cmake
cp modules/IncludeUrl.cmake cmake
cp <PATH_TO_YCM_SOURCES>/tools/YCMBootstrapFetch.cmake cmake

These files must be in a folder included in :cmake:variable:`CMAKE_MODULE_PATH`
for your project:
Expand All @@ -141,15 +140,15 @@ for your project:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

Now you can include ``YCMBootstrap.cmake``:
Now you can include ``YCMBootstrapFetch.cmake``:

.. code-block:: cmake

# Uncomment the next line to specify a tag or a version.
# set(YCM_TAG [tag, branch, or commit hash])

# Bootstrap YCM
include(YCMBootstrap)
include(YCMBootstrapFetch)

This is the suggested method when you build a superbuild. Downloading all your
project would require a network connection anyway, therefore you will need to
Expand Down
6 changes: 3 additions & 3 deletions modules/YCMEPHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ set(_ycm_YCMBootstrap_sha1sum 59c6dfc84ec36518c5be5aef13af252a8250bad7)
# new scope the variables added by the included files.

macro(_YCM_INCLUDE _module)
if(YCM_FOUND)
if(YCM_FOUND OR DEFINED __USEYCMFROMSOURCE_INCLUDED)
include(${_module})
else()
# We assume that YCMEPHelper was included using include_url, or that at
Expand Down Expand Up @@ -215,7 +215,7 @@ macro(_YCM_SETUP)
set(_print-directories-all print-directories-all)
endif()

if(NOT YCM_FOUND) # Useless if we don't need to bootstrap
if(NOT (YCM_FOUND OR DEFINED __USEYCMFROMSOURCE_INCLUDED)) # Useless if we don't need to bootstrap
set(YCM_BOOTSTRAP_BASE_ADDRESS "https://raw.github.com/robotology/ycm/HEAD/" CACHE STRING "Base address of YCM repository")
mark_as_advanced(YCM_BOOTSTRAP_BASE_ADDRESS)
endif()
Expand Down Expand Up @@ -1327,7 +1327,7 @@ endfunction()

unset(__YCM_BOOTSTRAPPED_CALLED CACHE)
macro(YCM_BOOTSTRAP)
if(YCM_FOUND OR DEFINED __YCM_BOOTSTRAPPED_CALLED)
if(YCM_FOUND OR DEFINED __YCM_BOOTSTRAPPED_CALLED OR DEFINED __USEYCMFROMSOURCE_INCLUDED)
return()
endif()
set(__YCM_BOOTSTRAPPED_CALLED TRUE CACHE INTERNAL "")
Expand Down
18 changes: 18 additions & 0 deletions tools/UseYCMFromSource.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause

# This module can be used to use YCM modules directly from the source repo,
# to just use them in the build without installing them.

if(DEFINED __USEYCMFROMSOURCE_INCLUDED)
return()
endif()
set(__USEYCMFROMSOURCE_INCLUDED TRUE)

get_filename_component(_YCM_SRC_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)

list(APPEND CMAKE_MODULE_PATH ${_YCM_SRC_DIR}/modules)
list(APPEND CMAKE_MODULE_PATH ${_YCM_SRC_DIR}/find-modules)
list(APPEND CMAKE_MODULE_PATH ${_YCM_SRC_DIR}/build-modules)
list(APPEND CMAKE_MODULE_PATH ${_YCM_SRC_DIR}/style-modules)
list(APPEND CMAKE_MODULE_PATH ${_YCM_SRC_DIR}/cmake-next/proposed)
100 changes: 100 additions & 0 deletions tools/YCMBootstrapFetch.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause

# This module is intentionally kept as small as possible in order to
# avoid the spreading of different modules.
#

# CMake variables read as input by this module:
# YCM_MINIMUM_VERSION : minimum version of YCM requested to use a system YCM
# YCM_TAG : if no suitable system YCM was found, bootstrap from this
# : TAG (either branch, commit or tag) of YCM repository
# USE_SYSTEM_YCM : if defined and set FALSE, skip searching for a system
# YCM and always bootstrap


if(DEFINED __YCMBOOTSTRAP_INCLUDED)
return()
endif()
set(__YCMBOOTSTRAP_INCLUDED TRUE)


########################################################################
# _YCM_CLEAN_PATH
#
# Internal function that removes a directory and its subfolder from an
# environment variable.
# This is useful because will stop CMake from finding the external
# projects built in the main project on the second CMake run.
#
# _path: path that should be removed
# _envvar: environment variable to clean

function(_YCM_CLEAN_PATH _path _envvar)
get_filename_component(_path ${_path} REALPATH)
set(_var_new "")
if(NOT "$ENV{${_envvar}}" MATCHES "^$")
file(TO_CMAKE_PATH "$ENV{${_envvar}}" _var_old)
if(NOT WIN32)
# CMake handles correctly ":" except for the first character
string(REPLACE ":" ";" _var_old "${_var_old}")
endif()
foreach(_dir ${_var_old})
get_filename_component(_dir ${_dir} REALPATH)
if(NOT "${_dir}" MATCHES "^${_path}")
list(APPEND _var_new ${_dir})
endif()
endforeach()
endif()
list(REMOVE_DUPLICATES _var_new)
file(TO_NATIVE_PATH "${_var_new}" _var_new)
if(NOT WIN32)
string(REPLACE ";" ":" _var_new "${_var_new}")
endif()
set(ENV{${_envvar}} "${_var_new}")
endfunction()


# Remove binary dir from CMAKE_PREFIX_PATH and PATH before searching for
# YCM, in order to avoid to find the YCM version bootstrapped by YCM
# itself.
_ycm_clean_path("${CMAKE_BINARY_DIR}/install" CMAKE_PREFIX_PATH)
_ycm_clean_path("${CMAKE_BINARY_DIR}/install" PATH)


# If the USE_SYSTEM_YCM is explicitly set to false, we just skip to bootstrap.
if(NOT DEFINED USE_SYSTEM_YCM OR USE_SYSTEM_YCM)
find_package(YCM ${YCM_MINIMUM_VERSION} QUIET)
if(COMMAND set_package_properties)
set_package_properties(YCM PROPERTIES TYPE RECOMMENDED
PURPOSE "Used by the build system")
endif()
if(YCM_FOUND)
message(STATUS "YCM found in ${YCM_MODULE_DIR}.")
set_property(GLOBAL APPEND PROPERTY YCM_PROJECTS YCM)
return()
endif()
endif()

message(STATUS "YCM not found. Bootstrapping it.")

# Download and use a copy of the YCM library for bootstrapping
# This is different from the YCM that will be downloaded as part of the superbuild
include(FetchContent)
if(DEFINED YCM_TAG)
set(YCM_FETCHCONTENT_TAG ${YCM_TAG})
else()
set(YCM_FETCHCONTENT_TAG master)
endif()
FetchContent_Declare(YCM
GIT_REPOSITORY https://github.com/robotology/ycm
GIT_TAG ${YCM_FETCHCONTENT_TAG})

FetchContent_GetProperties(YCM)
if(NOT YCM_POPULATED)
message(STATUS "Fetching YCM.")
FetchContent_Populate(YCM)
# Add YCM modules in CMAKE_MODULE_PATH
include(${ycm_SOURCE_DIR}/tools/UseYCMFromSource.cmake)
endif()