cpplocate is an MIT licensed, cross-platform C++ library that provides tools for applications to locate themselves, their data assets, as well as dependend modules.
In the context of cross-platform applications, locating data assets belonging to an application or library is not an easy task.
Depending on the situation, data assets can occupy different locations on a system: in a development tree, data might be located relative to the executable in a build directory, when installed into the system, they might be located in a global directory such as /usr/share
or C:\Users\...\AppData
, while for self-contained installs they might be located relative to the executable.
When projects are deployed using software installers or archives, the final location can be controlled by the user installing the software, therefore it cannot be known at build-time.
The situation gets even more complicated when an application does not only need access to its own data assets, but depends on other modules, such as dynamic libraries or even plugins, which bring their own data.
However, a software should be able to locate its data assets as easy as possible and still be relocatable for typical deployment and installation routines to work as expected.
CG Internals offers computer graphics R&D as well as reliable technology and innovative concepts to support your computer graphics visions. We provide trainings and can help you integrate and customize cpplocate in your next project.
Visit Professional Support and Services for more details.
Service | System | Compiler | Status |
---|---|---|---|
Travis-CI | Ubuntu 14.04 | GCC 4.8, Clang 3.5 | |
Travis-CI | macOS | AppleClang 7.3 | |
AppVeyor | Windows | MSVC 2013 MSVC 2015 MSVC 2017 |
|
Coverity | Ubuntu 14.04 | GCC 5.3 | upcoming |
Jenkins |
Ubuntu 14.04 |
GCC 4.8 GCC 4.9 GCC 5.4 Clang 3.9 |
|
Jenkins |
Windows 10 |
MSVC 2013 Update 5 MSVC 2015 Update 1 |
Please note that our macOS build node is currently broken (physically). However, cpplocate is maintained for macOS as well and there are many people using it on macOS on a regular basis.
cpplocate is available for different platforms using different distribution channels.
ToDo
ToDo
ToDo
ToDo
ToDo
There is currently no precompiled package maintained. Please download the source code and commence building from source.
The only mandatory run-time dependencies of cpplocate are the STL of the used compiler. Building cpplocate utilizes:
- CMake 3.0 or higher for building cpplocate from source (mandatory for any build from source)
- git for version control (optional)
- Doxygen 1.8 or higher for generating the documentation on your system (optional)
- graphviz for generating diagrams (optional)
For compilation, a C++11 compliant compiler, e.g., GCC 4.8, Clang 3.3, MSVC 2013 Update 3, is required.
First, download the source code as archive or via git:
> git clone https://github.com/cginternals/cpplocate.git
> cd cpplocate
Then, depending on the version of cpplocate you want to build, choose the appropriate tag or branch, e.g., for the 1.0.0 release:
> git fetch --tags
> git checkout v1.0.0
The actual compilation can be done using CMake and your favorite compiler and IDE.
For building cpplocate CMake via command line can be used (should work on all systems):
First create a build directory (we do not recommend in-source builds):
> mkdir build
> cd build
Configure cpplocate with your prefered or default generator, e.g., for Visual Studio 2015 in x64 use (note: some IDEs have integrated support for CMake projects, e.g., Qt Creator, and allow you to skip the manual project configuration):
> cmake .. -G "Visual Studio 14 2015 Win64"
In order to compile the project, either use you favorite Editor/IDE with the created project or use CMake as follows:
> cmake --build .
We suggest using the build system of cpplocate for a smooth integration: CMake For it, cpplocate provides a find configuration script that should be installed into your system or at least be accessible by CMake. In the projects CMakeLists.txt, add one of the following lines:
find_package(cpplocate QUIET) # if you want to check for existance
find_package(cpplocate REQUIRED) # if it is really required in your project
There is no need for explicit linking (e.g., target_link_libraries(${target} ... PUBLIC cpplocate::cpplocate)
) anymore.
The find configuration script takes care of that.
ToDo
cpplocate
offers a cross-platform implementation to obtain the location of the current executable
in most cases. This can be used by the application itself to locate its data.
Module information files contain meta-information about a module, such as project name, version, and vendor. They also provide the information of where to find data assets for that module based on the location of the module information file itself, or, in some cases, using an absolute path.
A module information file has the filename <projectname>.modinfo
and contains an arbitrary
number of key/value-pairs, e.g.:
name: examplelib
version: 1.0.0
description: Example library
author: Example organization
dataPath: ${ModulePath}/data
The keys are purely conventional and can be used in any way as defined by the using application.
To express file paths relative to the module information file, the placeholder variable ${ModulePath}
can be used. When loading the module information, this variable will be replaced with the path
to the directory containing the module information file.
A CMake module is provided for creating module information files automatically, taking into account different situations such as build-time (finding modules and data in a development tree) and install-time (finding modules and data from an installed location).
Use find_package(cpplocate)
to find the cpplocate library, pointing CMAKE_PREFIX_PATH
to the
directory that contains cpplocate
. This will locate the library and also include the necessary
cmake functions into your project.
The following cmake functions are provided by cpplocate
:
generate_module_info(<project_id>
VALUES
[<key> <value>]*
BUILD_VALUES
[<key> <value>]*
INSTALL_VALUES
[<key> <value>]*
)
Define a module information file for a module named by project_id
. The module name can be chosen
arbitrarily and can, but does not need to, match the name of the project or a library. The
filename will be derived as <project_id>.modinfo
.
The generated module information file will contain all key/value-pairs specified after VALUES
.
When created into the build-directory of the current development tree, the values specified
after BUILD_VALUES
will also be added. But when installed using the cmake INSTALL
-target, the
values after INSTALL_VALUES
will be used instead. This allows for providing different values
in the development tree and in installed location, e.g., the data path might point to the
absolute path in the development tree, but be defined relative to the module file on install.
Example usage:
generate_module_info(examplelib
VALUES
name "examplelib"
version "1.0.0"
description "Example library"
author "Example organization"
BUILD_VALUES
dataPath "${PROJECT_SOURCE_DIR}/data"
INSTALL_VALUES
dataPath "\${ModulePath}/data"
)
export_module_info(<project_id>
TARGET <target>
[ FOLDER <folder>
[RENAME <filename>]
]
)
Creates the actual module information file for a module named by project_id
in the output directory of target <target>
. It uses the values from VALUES
and BUILD_VALUES
. This is executed at build-time, providing a target named <target>-modinfo
. If FOLDER
is specified, the target is put into the UI folder named by folder
. If RENAME
is specified, the target output name is set as <filename>
, filename
can contain generator expressions.
Example usage:
export_module_info(examplelib TARGET examplelib FOLDER "cmake")
export_module_info_with_deps
: Create module information file and copy module information files of dependencies into the build directory
export_module_info_with_deps(<target>
[ FOLDER <folder>
[RENAME <filename>]
]
REQUIRES <module_name> <import_target> [ <module_name> <import_target> ]*
)
Creates the actual module information file for a module named by <target>
in the output directory of that target. It uses the values from VALUES
and BUILD_VALUES
. This is executed at build-time, providing a target named <target>-modinfo
. If FOLDER
is specified, the target is put into the UI folder named by folder
. If RENAME
is specified, the target output name is set as <filename>
, filename
can contain generator expressions. REQUIRES specifies a list of dependencies, whose module information files will be located and copied into the output directory.
To locate the module information file, a file named <module_name>.modinfo
is located in the directory of the given target <import_target>
. Therefore, the module file must reside in the same directory as the library for this mechanism to work.
Example usage:
export_module_info_with_deps(examplelib TARGET examplelib FOLDER "cmake")
install_module_info(<project_id>
DESTINATION <dest>
[COMPONENT <component>]
[RENAME <filename>]
)
Creates an installation rule to install a module information file named by project_id
. It uses the values from VALUES
and INSTALL_VALUES
. The destination location is specified by dest
. If RENAME
is specified, the file will be renamed to <filename>
on installation, filename
can contain generator expressions. If COMPONENT
is specified, the module information file is added to the specified installation component.
Example usage:
install_module_info(examplelib DESTINATION "." COMPONENT dev)
copy_module_info(<project_id> <filename>)
This function writes the module information file named by project_id
to an output file specified by filename
at build-time, filename
can contain generator expressions. It uses the values from VALUES
and BUILD_VALUES
.
Similar to a dynamic linker, cpplocate
can resolve dependencies to other modules by locating
module information files. The search for modules is conducted in the following order:
-
in the directory of the current executable (not the working directory!)
-
in the directories provided by the environment variable
CPPLOCATE_PATH
<path>/<module>-info.modinfo
<path>/<module>/<module>-info.modinfo
-
in standard locations:
C:\Program Files\<module>\<module>-info.modinfo
/usr/share/<module>/<module>-info.modinfo
/usr/local/share/<module>/<module>-info.modinfo
This functionality can be used by a library to locate its own data at runtime.
If it is used as a dependency for another project, such as an application or a
plugin using the library, it cannot rely on the data being relative to the
current executable or even the working directory. Therefore, the library can
use cpplocate
to locate itself:
namespace examplelib
{
std::string determineDataPath()
{
const cpplocate::ModuleInfo moduleInfo = cpplocate::findModule("examplelib");
const std::string moduleInfoPath = moduleInfo.value("dataPath");
return moduleInfoPath.empty() ? "data" : moduleInfoPath;
}
const std::string & dataPath()
{
static const auto path = determineDataPath();
return path;
}
}
And whenever data needs to be accessed, code like the following should be used:
std::string filename = dataPath() + "/textures/logo.png";