mirror of
https://github.com/Rogiel/CMakeDependency
synced 2025-12-06 05:22:48 +00:00
Initial commit
This commit is contained in:
61
CMakeDependency.cmake
Normal file
61
CMakeDependency.cmake
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# CMake dependency: this is a little and lightweight helper tool that
|
||||||
|
# automatically downloads, extracts and configures dependencies based on a
|
||||||
|
# declaration on a .json file.
|
||||||
|
#
|
||||||
|
# To manually add a dependency, call `import_dependency(<name> URL <url>). After
|
||||||
|
# this call, CMake will have downloaded and extracted the dependency source. The
|
||||||
|
# extracted files are located at `${<name>_SOURCE_DIR}`.
|
||||||
|
#
|
||||||
|
# Also, it is possible to import a dependency JSON file by calling
|
||||||
|
# `import_dependencies_from_json(<json file>)`. All dependencies are
|
||||||
|
# automatically configured as declared in the JSON file. CMake will also
|
||||||
|
# regenerate any configuration needed if the JSON is ever changed.
|
||||||
|
|
||||||
|
set(CMDEP_GENERATOR_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/DependencyGenerator.py)
|
||||||
|
set(CMDEP_DEPENDENCY_DECL_TMPL ${CMAKE_CURRENT_LIST_DIR}/DependencyDeclaration.cmake.in)
|
||||||
|
|
||||||
|
set(CMDEP_ROOT_DIR
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
CACHE PATH "A path that points to the location in which CMake dependency files should be downloaded and extracted to.")
|
||||||
|
set(CMDEP_ZIP_DIR
|
||||||
|
${CMDEP_ROOT_DIR}/zips
|
||||||
|
CACHE PATH "A path that points to the location in which ZIP files should be downloaded to.")
|
||||||
|
|
||||||
|
function(import_dependency name)
|
||||||
|
set(options)
|
||||||
|
set(oneValueArgs URL DOWNLOAD_NAME)
|
||||||
|
set(multiValueArgs)
|
||||||
|
cmake_parse_arguments(DEPENDENCY "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||||
|
cmake_parse_arguments(${name} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||||
|
|
||||||
|
set(DEPENDENCY_NAME ${name})
|
||||||
|
|
||||||
|
configure_file(${CMDEP_DEPENDENCY_DECL_TMPL} ${CMAKE_CURRENT_BINARY_DIR}/${name}.dep.cmake @ONLY)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_BINARY_DIR}/${name}.dep.cmake)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(import_dependencies_from_json json)
|
||||||
|
set(json_dep_file ${json})
|
||||||
|
set(cmake_dep_file ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.deps.txt)
|
||||||
|
|
||||||
|
find_package(Python3 COMPONENTS Interpreter)
|
||||||
|
if(Python3_Interpreter_FOUND)
|
||||||
|
list(APPEND CMAKE_CONFIGURE_DEPENDS ${json_dep_file})
|
||||||
|
|
||||||
|
file(LOCK ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY GUARD FILE)
|
||||||
|
if(${json_dep_file} IS_NEWER_THAN ${cmake_dep_file} OR
|
||||||
|
${CMDEP_GENERATOR_SCRIPT} IS_NEWER_THAN ${cmake_dep_file})
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${Python3_EXECUTABLE} ${CMDEP_GENERATOR_SCRIPT}
|
||||||
|
INPUT_FILE ${json_dep_file}
|
||||||
|
OUTPUT_FILE ${cmake_dep_file})
|
||||||
|
endif()
|
||||||
|
file(LOCK ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY RELEASE)
|
||||||
|
else()
|
||||||
|
message(STATUS "Python interpreter not found. CMake dependencies will NOT update automatically.")
|
||||||
|
endif()
|
||||||
|
include(${cmake_dep_file})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
list(APPEND CMAKE_CONFIGURE_DEPENDS ${CMDEP_GENERATOR_SCRIPT})
|
||||||
94
DependencyDeclaration.cmake.in
Normal file
94
DependencyDeclaration.cmake.in
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
set(@DEPENDENCY_NAME@_URL
|
||||||
|
"@DEPENDENCY_URL@"
|
||||||
|
CACHE STRING "A path that points to a @DEPENDENCY_NAME@ URL to be downloaded. CMake will use this URL to download the file if needed.")
|
||||||
|
set(@DEPENDENCY_NAME@_DIR
|
||||||
|
${CMDEP_ROOT_DIR}/@DEPENDENCY_NAME@
|
||||||
|
CACHE PATH "A path that points to a @DEPENDENCY_NAME@ directory containing it's sources.")
|
||||||
|
set(@DEPENDENCY_NAME@_LOCK ${CMDEP_ROOT_DIR})
|
||||||
|
|
||||||
|
set(@DEPENDENCY_NAME@_SOURCE_DIR
|
||||||
|
${@DEPENDENCY_NAME@_DIR}
|
||||||
|
CACHE PATH "A path that points to a @DEPENDENCY_NAME@ source directory. If manually set, no downloading or extraction will take place and this will be used instead.")
|
||||||
|
set(@DEPENDENCY_NAME@_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/@DEPENDENCY_NAME@)
|
||||||
|
|
||||||
|
get_filename_component(@DEPENDENCY_NAME@_DOWNLOAD_NAME "${@DEPENDENCY_NAME@_URL}" NAME CACHE)
|
||||||
|
set(@DEPENDENCY_NAME@_ZIP
|
||||||
|
${CMDEP_ZIP_DIR}/${@DEPENDENCY_NAME@_DOWNLOAD_NAME}
|
||||||
|
CACHE PATH "A path that points to a @DEPENDENCY_NAME@ zip file. If this file does not exists, it will be downloaded.")
|
||||||
|
|
||||||
|
# To prevent other concurrent CMake instances from trying to download or extract
|
||||||
|
# the file, we lock the source directory. This will guarantee that only a single
|
||||||
|
# CMake instance downloads or extracts a file.
|
||||||
|
#
|
||||||
|
file(LOCK ${@DEPENDENCY_NAME@_LOCK} DIRECTORY GUARD FILE)
|
||||||
|
|
||||||
|
if(NOT EXISTS ${@DEPENDENCY_NAME@_SOURCE_DIR})
|
||||||
|
if(NOT EXISTS ${@DEPENDENCY_NAME@_ZIP})
|
||||||
|
get_filename_component(@DEPENDENCY_NAME@_ZIP_DIRECTORY "${@DEPENDENCY_NAME@_ZIP}" DIRECTORY)
|
||||||
|
|
||||||
|
if(NOT EXISTS ${@DEPENDENCY_NAME@_ZIP_DIRECTORY})
|
||||||
|
file(MAKE_DIRECTORY ${@DEPENDENCY_NAME@_ZIP_DIRECTORY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: Downloading from ${@DEPENDENCY_NAME@_URL}")
|
||||||
|
|
||||||
|
file(DOWNLOAD ${@DEPENDENCY_NAME@_URL}
|
||||||
|
${@DEPENDENCY_NAME@_ZIP}
|
||||||
|
SHOW_PROGRESS
|
||||||
|
# no TIMEOUT
|
||||||
|
STATUS status
|
||||||
|
LOG log)
|
||||||
|
|
||||||
|
list(GET status 0 status_code)
|
||||||
|
list(GET status 1 status_string)
|
||||||
|
|
||||||
|
if(status_code EQUAL 0)
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: Download complete")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "@DEPENDENCY_NAME@: error: downloading from '${@DEPENDENCY_NAME@_URL}' failed with error code ${status_code} (${status_string}) -- ${log}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prepare a space for extracting:
|
||||||
|
#
|
||||||
|
set(tmp_dir "${CMAKE_CURRENT_BINARY_DIR}/@DEPENDENCY_NAME@-tmp")
|
||||||
|
file(MAKE_DIRECTORY "${tmp_dir}")
|
||||||
|
|
||||||
|
# Extract it:
|
||||||
|
#
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: extracting...")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${@DEPENDENCY_NAME@_ZIP}
|
||||||
|
WORKING_DIRECTORY ${tmp_dir}
|
||||||
|
RESULT_VARIABLE rv)
|
||||||
|
if(NOT rv EQUAL 0)
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: extracting... [error clean up]")
|
||||||
|
file(REMOVE_RECURSE "${tmp_dir}")
|
||||||
|
message(FATAL_ERROR "@DEPENDENCY_NAME@: error: extract of '${@DEPENDENCY_NAME@_DOWNLOAD_NAME}' failed")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Analyze what came out of the tar file:
|
||||||
|
#
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: extracting... [analysis]")
|
||||||
|
file(GLOB contents "${tmp_dir}/*")
|
||||||
|
list(REMOVE_ITEM contents "${tmp_dir}/.DS_Store")
|
||||||
|
list(LENGTH contents n)
|
||||||
|
if(NOT n EQUAL 1 OR NOT IS_DIRECTORY "${contents}")
|
||||||
|
set(contents "${tmp_dir}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Move "the one" directory to the final directory:
|
||||||
|
#
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: extracting... [rename]")
|
||||||
|
file(REMOVE_RECURSE ${@DEPENDENCY_NAME@_DIR})
|
||||||
|
get_filename_component(contents ${contents} ABSOLUTE)
|
||||||
|
file(RENAME ${contents} ${@DEPENDENCY_NAME@_DIR})
|
||||||
|
|
||||||
|
# Clean up:
|
||||||
|
#
|
||||||
|
message(STATUS "@DEPENDENCY_NAME@: extracting... [clean up]")
|
||||||
|
file(REMOVE_RECURSE "${tmp_dir}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We are now done. We can unlock the CMake directory and proceed.
|
||||||
|
#
|
||||||
|
file(LOCK ${@DEPENDENCY_NAME@_LOCK} DIRECTORY RELEASE)
|
||||||
115
DependencyGenerator.py
Normal file
115
DependencyGenerator.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import json, os, sys
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
tab = " "*4
|
||||||
|
nl_indent = "\n"+tab*2
|
||||||
|
|
||||||
|
|
||||||
|
def escape(s, n):
|
||||||
|
return ' ' * n + s
|
||||||
|
|
||||||
|
|
||||||
|
def generate_dependency_decl(name, keys):
|
||||||
|
max_key_length = 0
|
||||||
|
for (key, value) in keys.items():
|
||||||
|
max_key_length = max(max_key_length, len(key))
|
||||||
|
|
||||||
|
s = "import_dependency(" + name + nl_indent + (nl_indent).join(
|
||||||
|
map(lambda k: k[0] + " " + escape(k[1], max_key_length - len(k[0]) + 3), keys.items())) + ")"
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
j = json.load(sys.stdin)
|
||||||
|
|
||||||
|
for (name, dep_info) in j.items():
|
||||||
|
sys.stderr.write('Updating dependency definitions for ' + name + '\n')
|
||||||
|
target_info = dep_info["target"]
|
||||||
|
|
||||||
|
target_type = target_info["type"]
|
||||||
|
src_dir = "${" + name + "_SOURCE_DIR}/"
|
||||||
|
|
||||||
|
dep_args = {}
|
||||||
|
if "git" in dep_info:
|
||||||
|
git_info = dep_info["git"]
|
||||||
|
git_repo = git_info["repository"]
|
||||||
|
git_tag = git_info["tag"]
|
||||||
|
|
||||||
|
git_url_parsed = urlparse(git_repo)
|
||||||
|
if git_url_parsed.hostname == 'github.com':
|
||||||
|
parts = git_url_parsed.path.split("/")
|
||||||
|
user = parts[1]
|
||||||
|
repo = parts[2]
|
||||||
|
repo = repo[:-4] if repo.endswith('.git') else repo
|
||||||
|
dep_args["URL"] = "https://github.com/" + user + "/" + repo + "/archive/" + git_tag + ".zip"
|
||||||
|
dep_args["DOWNLOAD_NAME"] = repo + "-" + git_tag + ".zip"
|
||||||
|
else:
|
||||||
|
print('git is only supported for github repositories at the moment.', file=sys.stderr)
|
||||||
|
exit(-1)
|
||||||
|
elif "url" in dep_info:
|
||||||
|
dep_args["URL"] = " ".join(dep_info["url"])
|
||||||
|
|
||||||
|
if 'download_name' in dep_info:
|
||||||
|
dep_args["DOWNLOAD_NAME"] = dep_info['download_name']
|
||||||
|
|
||||||
|
print("# -- Dependency: " + name)
|
||||||
|
print(generate_dependency_decl(name, dep_args))
|
||||||
|
|
||||||
|
public_decl_type = "PUBLIC"
|
||||||
|
if target_type == "static":
|
||||||
|
if isinstance(target_info["srcs"], list):
|
||||||
|
srcs = (nl_indent).join(map(lambda x: src_dir + x,target_info["srcs"]))
|
||||||
|
else:
|
||||||
|
print("file(GLOB " + name + "_SRCS " + src_dir + target_info["srcs"] + ")")
|
||||||
|
srcs = "${" + name + "_SRCS}"
|
||||||
|
print("add_library("+name+" STATIC "+nl_indent+srcs+")")
|
||||||
|
|
||||||
|
if target_type == "interface":
|
||||||
|
print("add_library("+name+" INTERFACE)")
|
||||||
|
public_decl_type = "INTERFACE"
|
||||||
|
|
||||||
|
if target_type == "subdirectory":
|
||||||
|
if "cache" in target_info:
|
||||||
|
for (var_name, value) in target_info["cache"].items():
|
||||||
|
if isinstance(value, bool):
|
||||||
|
print("set("+var_name+" "+("ON" if value else "OFF")+" CACHE INTERNAL \"\" FORCE)")
|
||||||
|
|
||||||
|
print("add_subdirectory(${" + name + "_SOURCE_DIR} ${" + name + "_BINARY_DIR})")
|
||||||
|
|
||||||
|
if target_type == "cmake":
|
||||||
|
print("include(${PROJECT_SOURCE_DIR}/" + target_info["file"]+")\n")
|
||||||
|
continue
|
||||||
|
|
||||||
|
includes = []
|
||||||
|
if "public_includes" in target_info:
|
||||||
|
includes += list(map(lambda x: public_decl_type + " " + src_dir + x, target_info["public_includes"]))
|
||||||
|
if "private_includes" in target_info:
|
||||||
|
includes += list(map(lambda x: "PRIVATE " + src_dir + x, target_info["private_includes"]))
|
||||||
|
if len(includes) != 0:
|
||||||
|
print("target_include_directories("+name+" "+nl_indent+
|
||||||
|
nl_indent.join(includes)
|
||||||
|
+")")
|
||||||
|
|
||||||
|
defines = []
|
||||||
|
if "public_defines" in target_info:
|
||||||
|
defines += list(map(lambda x: public_decl_type + " " + x, target_info["public_defines"]))
|
||||||
|
if "private_defines" in target_info:
|
||||||
|
defines += list(map(lambda x: "PRIVATE " + x, target_info["private_defines"]))
|
||||||
|
if len(defines) != 0:
|
||||||
|
print("target_compile_definitions("+name+" "+nl_indent+
|
||||||
|
nl_indent.join(defines)
|
||||||
|
+")")
|
||||||
|
|
||||||
|
if "links" in target_info:
|
||||||
|
print("target_link_libraries("+name+" "+nl_indent+
|
||||||
|
nl_indent.join(map(lambda x: public_decl_type + ' ' + x, target_info["links"]))
|
||||||
|
+")")
|
||||||
|
|
||||||
|
if "aliases" in target_info:
|
||||||
|
for (tgt, src) in target_info["aliases"].items():
|
||||||
|
print("add_library("+tgt+" ALIAS "+src+")")
|
||||||
|
|
||||||
|
if "extra_cmake" in target_info:
|
||||||
|
print()
|
||||||
|
print("include(${PROJECT_SOURCE_DIR}/" + target_info["extra_cmake"]+")")
|
||||||
|
print()
|
||||||
|
|
||||||
217
README.md
Normal file
217
README.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
# CMakeDependency
|
||||||
|
|
||||||
|
A little and lightweight CMake helper tool that automatically downloads, extracts and configures dependencies based on a declaration on a .json file.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
First you need to declare a dependency in your `dependencies.json` file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"JSON": {
|
||||||
|
"url": [
|
||||||
|
"https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip"
|
||||||
|
],
|
||||||
|
"download_name": "json-3.7.0.zip",
|
||||||
|
"target": {
|
||||||
|
"type": "interface",
|
||||||
|
"public_includes": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In your CMakeLists.txt all you need is to include the module and import all dependencies from your JSON file:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# Include the CMakeDependency module
|
||||||
|
include(CMakeDependency/CMakeDependency.cmake)
|
||||||
|
|
||||||
|
# Import dependencies from JSON
|
||||||
|
import_dependencies_from_json(${PROJECT_SOURCE_DIR}/dependencies.json)
|
||||||
|
```
|
||||||
|
|
||||||
|
You are done! `JSON` is now available as a target in CMake!
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
target_link_libraries(MyTarget PUBLIC JSON)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that CMakeDependency will create a file called `CMakeLists.deps.txt` in `CMAKE_CURRENT_SOURCE_DIR`. This file contains the preprocessed JSON file that is included by CMake. You can commit this file into your repository if you don't want to depend on Python 3 when compiling.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
This CMake module requires **CMake 3.15** and up. **Python3** is required if you want to automatically generate the CMake dependencies from the JSON file.
|
||||||
|
|
||||||
|
## Declaring dependencies manually in CMake
|
||||||
|
|
||||||
|
You don't have to use the JSON file if you don't want to. You can import dependencies directly in CMake by calling `import_dependency`:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
import_dependency(JSON
|
||||||
|
URL https://github.com/nlohmann/json/releases/download/v3.7.0/include.zip
|
||||||
|
DOWNLOAD_NAME json-3.7.0.zip)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `DOWNLOAD_NAME` is optional. If not given, CMakeDependency will resolve a name based on the given `URL`.
|
||||||
|
|
||||||
|
In this mode, no target is created but the ZIP file is downloaded and extracted. The extracted contents are in `JSON_SOURCE_DIR`. If this library is a CMake library, you can simply call `add_subdirectory` and be done with it.
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
add_subdirectory(${JSON_SOURCE_DIR} ${JSON_BINARY_DIR})
|
||||||
|
```
|
||||||
|
|
||||||
|
or if the dependency is **NOT** a CMake project, you can manually create a target:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
add_library(JSON INTERFACE)
|
||||||
|
target_include_directories(JSON INTERFACE ${JSON_SOURCE_DIR})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Overriding a dependency
|
||||||
|
|
||||||
|
If you don't want to duplicate your dependencies across multiple projects you can override the dependency source dir by setting `JSON_DIR` cache variable. You can do so when invoking CMake:
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
cmake -DJSON_DIR="/my/json/lib" [...]
|
||||||
|
```
|
||||||
|
|
||||||
|
or from within CMake itself, before calling `import_dependency` or `import_dependencies_from_json`:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
set(JSON_DIR "/my/json/lib" CACHE PATH "" FORCE)
|
||||||
|
```
|
||||||
|
|
||||||
|
Node that when setting `JSON_DIR`, if the dependency is not downloaded it will be downloaded and imported to the given directory. If this is not something you want, for example, you want to use a system provided dependency, you can override the directory by setting `JSON_SOURCE_DIR`.
|
||||||
|
|
||||||
|
Additionally, you can override just the zip file by setting `JSON_ZIP`.
|
||||||
|
|
||||||
|
## `dependencies.json` by example
|
||||||
|
|
||||||
|
### Boost
|
||||||
|
|
||||||
|
This example downloads the Boost source zip and configures it by building the `system` library.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Boost": {
|
||||||
|
"url": [
|
||||||
|
"https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.zip"
|
||||||
|
],
|
||||||
|
"target": {
|
||||||
|
"type": "static",
|
||||||
|
"srcs": [
|
||||||
|
"libs/system/src/error_code.cpp"
|
||||||
|
],
|
||||||
|
"public_includes": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"public_defines": {
|
||||||
|
"BOOST_ALL_NO_LIB": "1",
|
||||||
|
"BOOST_ASIO_NO_TYPEID": "1"
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
"$<$<PLATFORM_ID:Windows>:bcrypt.dll>"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### [Naios/continuable](https://github.com/Naios/continuable)
|
||||||
|
|
||||||
|
This will [Naios/continuable](https://github.com/Naios/continuable) and it's dependency [Naios/function2](https://github.com/Naios/function2) create both targets as a CMake interface library and link `Function2` into `Continuable`. As a consumer, you can simply link against `Continuabe` and CMake will add `Function2` transitively fot you.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Continuable": {
|
||||||
|
"git": {
|
||||||
|
"repository": "https://github.com/Naios/continuable.git",
|
||||||
|
"tag": "cacb84371a5e486567b4aed244ce742ea6509d7d"
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "interface",
|
||||||
|
"public_includes": [
|
||||||
|
"include"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
"Function2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Function2": {
|
||||||
|
"git": {
|
||||||
|
"repository": "https://github.com/Naios/function2.git",
|
||||||
|
"tag": "7cd95374b0f1c941892bfc40f0ebb6564d33fdb9"
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "interface",
|
||||||
|
"public_includes": [
|
||||||
|
"include"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### [Rogiel/PacketBuffer](https://github.com/Rogiel/PacketBuffer)
|
||||||
|
|
||||||
|
This will download [Rogiel/PacketBuffer](https://github.com/Rogiel/PacketBuffer) and import it by using CMake's `add_subdirectory` command.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"PacketBuffer": {
|
||||||
|
"git": {
|
||||||
|
"repository": "https://github.com/Rogiel/PacketBuffer.git",
|
||||||
|
"tag": "37e76659eaf4ed7d4407d1ccc5e31dee5454ef2c"
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "subdirectory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Poco
|
||||||
|
|
||||||
|
This example will download the Poco library and include `Poco.cmake` for further configuration. You can use `Poco_SOURCE_DIR` and `Poco_BINARY_DIR` if needed to configure your target.
|
||||||
|
|
||||||
|
This allows very flexible build configuration for dependencies.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Poco": {
|
||||||
|
"url": [
|
||||||
|
"https://pocoproject.org/releases/poco-1.9.4/poco-1.9.4.zip"
|
||||||
|
],
|
||||||
|
"target": {
|
||||||
|
"type": "cmake",
|
||||||
|
"file": "Poco.cmake"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced features
|
||||||
|
|
||||||
|
### Global cache variables
|
||||||
|
- **`CMDEP_ROOT_DIR`**: A path that points to the location in which CMake dependency files should be downloaded and extracted to. Defaults to `${CMAKE_CURRENT_SOURCE_DIR}`.
|
||||||
|
- **`CMDEP_ZIP_DIR`**: A path that points to the location in which ZIP files should be downloaded to. Defaults to `${CMDEP_ROOT_DIR}/zips`.
|
||||||
|
|
||||||
|
### Dependency cache variables
|
||||||
|
- **`<name>_URL`**: A path that points to a URL to be downloaded. CMake will use this URL to download the file if needed. Defaults to the value given in `import_dependency`.
|
||||||
|
- **`<name>_DIR`**: A path that points to a directory containing the dependency sources. Defaults to `${CMDEP_ROOT_DIR}/<name>`.
|
||||||
|
- **`<name>_SOURCE_DIR`**: A path that points to a source directory. If manually set, no downloading or extraction will take place and this will be used instead. Defaults to `${<name>_DIR}`.
|
||||||
|
- **`<name>_ZIP`**: A path that points to a zip file. If this file does not exists, it will be downloaded. You can use this to override the download and point to an already existing ZIP file. Defaults to `${CMDEP_ZIP_DIR}/<file name>.zip`.
|
||||||
|
|
||||||
|
## Concurrency with CMake
|
||||||
|
|
||||||
|
Some IDEs, such as CLion, use multiple CMake invocations for each configuration. This could cause problems when downloading dependencies to a common location. To avoid such problems, `CMakeDependency` uses CMake's advisory locking mechanism to prevent multiple CMake instances from downloading the same file.
|
||||||
|
|
||||||
|
This lock is acquired in the `CMDEP_ROOT_DIR` directory. Beware that CMake will create a `cmake.lock` file in this directory and you should exclude it from your source control if needed.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- Improve documentation on `dependencies.json` syntax.
|
||||||
Reference in New Issue
Block a user