Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/leapmotion/cmake-modules
Helpful CMake modules - 3.0+
https://github.com/leapmotion/cmake-modules
Last synced: 2 days ago
JSON representation
Helpful CMake modules - 3.0+
- Host: GitHub
- URL: https://github.com/leapmotion/cmake-modules
- Owner: leapmotion
- Created: 2014-11-04T19:28:26.000Z (about 10 years ago)
- Default Branch: develop
- Last Pushed: 2017-05-16T22:34:43.000Z (over 7 years ago)
- Last Synced: 2024-04-14T22:44:17.137Z (7 months ago)
- Language: CMake
- Size: 242 KB
- Stars: 12
- Watchers: 67
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
#### CMake-Modules
This repo is a set of helpful CMake modules we use internally and would like to share,
including customizedFind files and utility modules. It is intended to be
incorporated into projects as a subtree. This is NOT intended as a sample for using
CMake with the Leap API, though some of the functionality here will be helpful
if that's what you want to do. These modules are written for CMake 3.1+, and may not
function properly on older versions.##### Repo Directory Layout
* Root directory of the repo contains cmake modules created by Leap Motion.
* cmakeleap directory contains patched cmake modules that are normally included with cmake.
```
# At the beginning of your CMakeLists.txt
# Use the following to use Leap specific cmake modules and you are only using the Leap library.
list(APPEND CMAKE_MODULE_PATH "${PATH_TO_THIS_REPO}/cmake-modules")################################################################################
# Add this line if you want to include the patched cmake modules.
################################################################################
include(LeapWithCMake)```
##### Usage
First add the cmake-module repo as a remote, so you can more easily reference it
```
git remote add -f cmake-modules-repo [email protected]:leapmotion/cmake-modules.git
```To setup cmake-modules in your repository (only run once as a setup step):
```
git subtree add --prefix cmake-modules cmake-modules-repo develop
```To update the copy of cmake-modules in your repository from the latest code in the cmake-modules repo:
```
git fetch cmake-modules-repo develop
git subtree pull --prefix cmake-modules cmake-modules-repo develop
```To push changes from your repository upstream into the cmake-module repo:
```
git subtree push --prefix cmake-modules cmake-modules-repo
Open a pull request to merge to develop
```For more information on subtrees see Atlassian's [Git Subtree Tutorial](http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/)
#### Best Practices
These are practices we have found useful in producing and maintaining large-scale CMake projects
##### Rule 1: Always check the docs & existing modules for examples
Documentation for CMake is rapidly improving. See if you can find answers in the links below.* [CMake 3.1.0 Documentation](http://www.cmake.org/cmake/help/v3.1/index.html)
* [CMake git-master Documentation](http://www.cmake.org/cmake/help/git-master/)##### Naming conventions
* UPPER_CASE identifiers are public
* Mixed_CASE identifiers are also public assuming the first word is a namespace, as with package find modules
* _lower_idents with preceding underscores should be used for private, temporary variables
* lower_idents should also be used for function calls
* UPPER_CASE should be used for naming arguments to functions (see [CMakeParseArguments](http://www.cmake.org/cmake/help/git-master/module/CMakeParseArguments.html))##### General Guidelines
1. Prefer setting target properties over global or directory properties, eg. use target_include_directories over include_directories.
2. Prefer Generator expressions over PROPERTY_ variants wherever allowed. See [Generator Expressions Manual](http://www.cmake.org/cmake/help/v3.1/manual/cmake-generator-expressions.7.html)
3. install() is meant to define a step to package the build products of a library, and install them on the host system for use by cmake by adding it to the [Package Registry](http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#package-registry). For steps such as copying .DLLs or resource files to the appropriate location so a build can be run and debugged at all, use add_custom_command( POST_BUILD ...), or the TargetCopyLocalFiles module.
4. Never manually add a library directly in a CMakeLists.txt file (eg, via find_library or find_path). Instead, write a Find.cmake module. See the guidelines for writing find modules further down, as well as the official [Module Developer Docs](http://www.cmake.org/cmake/help/v3.1manual/cmake-developer.7.html#modules)
5. Avoid the target_link_libraries signatures which use[debug|optimized|general]. Use Generator Expressions instead.
6. Make use of INTERFACE targets and other pseudo targets to specify usage requirements. See
* [Pseudo Targets](http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#pseudo-targets) for information on what Pseudo Targets and Usage Requirements in general are.
* [Packages](http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html) for information on what packages are and how to write Config.cmake files that provide IMPORT targets.
7. Group settings first by locality, then by purpose. For example, in the root CMakeLists.txt every setting should be used by at 2 different sub-projects. If it isn't, then it should be moved to the CMakeLists file where it is actually used. Within file you might group all the options, then all the compiler and linker settings, then all the gloabal find_package operations. Any settings used by only one project should be set in that project's CMakeLists file.
##### Creating New Projects
This assumes that you have added cmake-modules as a subtree in a folder at the root of your project.##### Directory Structure
Root: A global CMakeLists.txt file containing global settings for all sub-projects.
If you have only one sub project, you may add and configure it at the end of the root cmakelists file.##### Handling Resources in OS X Bundles
See [CMake: Bundles and Frameworks](http://www.cmake.org/Wiki/CMake:Bundles_And_Frameworks)
as well as documentation for the [MACOSX_PACKAGE_LOCATION](http://www.cmake.org/cmake/help/v3.0/prop_sf/MACOSX_PACKAGE_LOCATION.html)##### Root CMakeLists.txt
```
cmake_minimum_required(VERSION 3.1)
project()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "" FORCE) #Disables MinSizeRel & MaxSpeedRel
set(CMAKE_INCLUDE_CURRENT_DIR ON) #essentially the same as include_directories(.) in every subdir
set(COPY_LOCAL_FILES_NO_AUTOSCAN ON) #Only do this if you are using the TargetImportedLibraries or TargetCopyLocalFiles modules.
set_property(GLOBAL PROPERTY USE_FOLDERS ON)################################################################################
# Include patches to cmake modules.
################################################################################
include(LeapWithCMake)include(TargetImportedLibraries)
#These lines are specific to how Leap organizes our external dependencies and may not apply to your project.
include(LeapCMakeTemplates)
leap_find_external_libraries()#Set any global flags for the project here, such as compiler settings you want used universally
#if(MSVC) #Uncomment this if you want to use use /MT instead of /MD on Windows
# add_compile_options($<$:/MTd> $<$:/MT>)
#endif()#Call add_subdirectory on relevant sub-directories here
add_subdirectory()
...verify_shared_libraries_resolved()
```
##### Project's CMakeLists.txt
```
set(_SRC )
set(_HEADERS )
add_( ${_SRC} ${_HEADERS})
################################################################################
# target_package command
################################################################################
target_package( REQUIRED) #Repeat as nessecary
target_link_libraries( ... ${Leap_BUILD_LIBRARIES})#set target's custom build settings here
#define install steps here
```
##### Simple CMakeLists.txt without patched cmake module changes and no external libraries.
```
cmake_minimum_required(VERSION 3.1)
project()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules")
set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "" FORCE) #Disables MinSizeRel & MaxSpeedRel
set(CMAKE_INCLUDE_CURRENT_DIR ON) #essentially the same as include_directories(.) in every subdir
set(COPY_LOCAL_FILES_NO_AUTOSCAN ON) #Only do this if you are using the TargetImportedLibraries or TargetCopyLocalFiles modules.
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
################################################################################
# Find leap and include libraries.
################################################################################
find_package(Leap REQUIRED)
include_directories(${Leap_INCLUDE_DIR})add_( ${_SRC} ${_HEADERS})
################################################################################
# No target package command.
################################################################################
target_link_libraries( ${Leap_BUILD_LIBRARIES} )
```##### Writing Find Modules
For packages which do not provide Package.cmake commands, or ones that do not yet support import targets,
you will have to author your own find module. This may be as simple as
```
include(${CMAKE_ROOT}/Modules/Find.cmake)
include(CreateImportTargetHelpers)
generate_import_target( )
```
but may also be much more complicated. See the existing Find modules in this repo for examples, and
CreateImportTargetHelpers.cmake's documentation on how it works.All Import targets generated by a Find module should use the
:: naming convention where :: is an import target which will include
all components specified as arguments to find_package. Private import targets should use
::_#### Notes & TODOs
- Better helpers and handling for modules which may be either SHARED or STATIC.
- Proposed solution is to define SHARED_LIBRARY and STATIC_LIBRARY separately, then set
LIBRARY to whichever one exists, and if both are defined then create an option so the
user can choose. Alternatively, we could detect which are available, default to SHARED
if both are, and expose an Xxx_IMPORT_TYPE cache variable that the user could override.
This would also let us throw errors if the files for the desired type are unavailable.- Make a cmake module for installing executables/resources in a platform-agnostic way
(e.g. Mac has a particular "bundle" format it follows).- The organization of the Components (with its component and library dependencies) should
be implemented using a cmake module, so little redundant boilerplate is necessary.- Write variants of find_file and find_path which actually return ALL matches, instead of
an ill-defined single match. This functionality is distinctly lacking in cmake, and
causes nontrivial problems when trying to find files/paths.