<commit_before>===
CPM
===

C++ Package Manager based on CMake.

CPM is designed to save you time and promote small, well-tested, and composable
C++ modules. It allows you to link against multiple different versions of the
same static library so that you can include other C++ modules that may depend
on older or newer versions of the same modules you are using. CPM will also
automatically download and build these C++ modules for you. CPM's goal is to
help support the growth of a module eco-system similar to that of Node.js'.

You can also manage external C or C++ libraries that do not use CPM. Using CPM
externals is akin to using CMake's external project mechanism with the external
project details hidden.

  Note: Modules are fully implemented but external libraries are not.

+---------------+--------------------------------------------------------------+
|  **Warning**  |  CPM is alpha software. The module code is complete but CPM  |
|               |  externals are missing. Feel free to evaluate CPM but please |
|               |  wait until CPM leaves alpha before using it in projects.    |
+---------------+--------------------------------------------------------------+

Using CPM
=========

To use CPM in your C++ project include the following at the top of your
CMakeLists.txt::

  #------------------------------------------------------------------------------
  # Required CPM Setup - See: http://github.com/iauns/cpm
  #------------------------------------------------------------------------------
  # You may set CPM_DIR to any path you want. Outside of the binary directory,
  # or anywhere on your harddrive. Any project that wants to use the same
  # version of any module can benefit immediately from the built packages.
  # Just be careful of pre-project settings for modules.
  set(CPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpm-packages" CACHE TYPE STRING)
  
  find_package(Git)
  if(NOT GIT_FOUND)
    message(FATAL_ERROR "CPM requires Git.")
  endif()
  if (NOT EXISTS ${CPM_DIR}/CPM.cmake)
    execute_process(
      COMMAND "${GIT_EXECUTABLE}" clone https://github.com/iauns/cpm ${CPM_DIR}
      RESULT_VARIABLE error_code
      OUTPUT_VARIABLE head_sha
      )
    if(error_code)
      message(FATAL_ERROR "CPM failed to get the hash for HEAD")
    endif()
  endif()
  include(${CPM_DIR}/CPM.cmake)
  
  # Include any modules and externals here...
  
  CPM_Finish()

Then add the ``${CPM_LIBRARIES}`` variable to your ``target_link_libraries``.
That's it. You will be able to start using CPM modules right away by adding
something like::

  CPM_AddModule("spire"
    GIT_REPOSITORY "https://github.com/SCIInstitute/spire"
    GIT_TAG "v0.7.0")

This snippet will automatically download, build, and link version 0.7.0 of a
thin OpenGL client named Spire. A new namespace is generated for 'spire' and a
preprocessor definition for this namespace is automatically added to your
project. The namespace preprocessor definition always follows the form
"``CPM_<NAME>_NS``" where ``<NAME>`` is the first argument of your call to
``CPM_AddModule``. The name is always capitalized before being added to your
preprocessor definitions.

For example, in the 'spire' snippet above, the preprocessor definition
``CPM_SPIRE_NS`` would be added to our project. This declares the namepsace
under which CPM has bound the 'Spire' module. You can access spire's interface
class through this namespace like so: ``CPM_SPIRE_NS::Interface``. In general
you will want to rename the namespace to something more appropriate:
``namespace spire = CPM_SPIRE_NS;``. It has been our experience that building a
header containing all of your module namespaces is quite useful. Something like
the following::

  #ifndef __MY_NAMESPACES_H
  #define __MY_NAMESPACES_H

  // 'Forward declaration' of CPM module namespaces.
  namespace CPM_SPIRE_NS {}
  namespace CPM_SPIRE_SCIRUN_NS {}
  ... (more forward declarations) ...
  
  // Renaming the namespaces in our top level namespace.
  namespace my_namespace {
    namespace spire     = CPM_SPIRE_NS;
    namespace spire_sr  = CPM_SPIRE_SCIRUN_NS;
  }

  #endif

Also be sure to place your calls to CPM_AddModule before your call to
CPM_Finish. The ``# Include any modules here...`` section mentioned in the
first snippet indicates where you should place calls to ``CPM_AddModule`` and
``CPM_AddExternal``.

Remember not to expose your namespaces.h header file in your public interface.
Use the preprocessor definitions in your public interface. If you absolutely
must include the namespaces header file in your public interface, then ensure
you give the include guard for your namespaces header a unique name.

CPM Externals
-------------

If the library you are interested in isn't a CPM module, try using CPM
externals. While you won't be able to statically link against multiple versions
of the library you can quickly include it if there is a CPM external formula
for it. If the library is hosted in a public location, use the URL of the
library::

  CPM_AddExternal("Full URL goes here")

Otherwise you may attempt to reference the library by name directly::

  CPM_AddExternal("mongodb-c")

If you don't find a formula for a library that you would like to use, kindly
consider contributing one to our CPM externals repository. We're always looking
to expand these formula.

Advantages
----------

* Automatically manages code retrieval and the building of CPM modules and externals.
* Allows the use of multiple different versions of the same statically linked
  module in the same executable.
* Built entirely in CMake. Nothing else is required.
* Encourages small well-tested and composable code modules.
* All CPM module code will be included in any generated project solution.
* Will automatically detect naming conflicts based on the names you assign 
  modules.

Limitations
-----------

* Only supports git.

Building CPM Modules
====================

If you only want to use pre-existing CPM modules and aren't interested in
building modules yourself, feel free to skip this section. But, if you are
interested in building CPM modules then please read on as some guidelines and
requirements are listed below.

CMakeLists.txt Entry
--------------------

There must be a CMakeLists.txt at the root of your module project and this
CMakeLists.txt file must contain all relevant CPM directives and code (see
below). Do not use issue calls to CPM (``CPM_*``) in a subdirectory
(``add_subdirectory``).

Add the following to the top of the CMakeLists.txt for your module:: 

  #-----------------------------------------------------------------------
  # CPM configuration
  #-----------------------------------------------------------------------
  set(CPM_MODULE_NAME <name>)
  set(CPM_LIB_TARGET_NAME ${CPM_MODULE_NAME})
  
  if ((DEFINED CPM_DIR) AND (DEFINED CPM_UNIQUE_ID) AND (DEFINED CPM_TARGET_NAME))
    set(CPM_LIB_TARGET_NAME ${CPM_TARGET_NAME})
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CPM_DIR})
    include(CPM)
  else()
    set(CPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpm-packages" CACHE TYPE STRING)
    find_package(Git)
    if(NOT GIT_FOUND)
      message(FATAL_ERROR "CPM requires Git.")
    endif()
    if (NOT EXISTS ${CPM_DIR}/CPM.cmake)
      execute_process(
        COMMAND "${GIT_EXECUTABLE}" clone https://github.com/iauns/cpm ${CPM_DIR}
        RESULT_VARIABLE error_code
        OUTPUT_VARIABLE head_sha)
      if(error_code)
        message(FATAL_ERROR "CPM failed to get the hash for HEAD")
      endif()
    endif()
    include(${CPM_DIR}/CPM.cmake)
  endif()
  
  # Include CPM modules or externals here (with CPM_AddModule / CPM_AddExternal).
  
  CPM_InitModule(${CPM_MODULE_NAME})<commit_msg>Removing any mention of CPM_AddExternal.<commit_after>===
CPM
===

C++ Package Manager based on CMake.

CPM is designed to save you time and promote small, well-tested, and composable
C++ modules. It allows you to link against multiple different versions of the
same static library so that you can include other C++ modules that may depend
on older or newer versions of the same modules you are using. CPM will also
automatically download and build these C++ modules for you. CPM's goal is to
help support the growth of a "do one thing and do it well" module eco-system in
C++.

Using CPM, you can also manage C or C++ libraries that do not use CPM. A number
of what we call 'external' modules are already in the cpm-modules repository.
These modules abstract away the details of writing a CMake external project for
you. Just be aware that you cannot statically link against multiple different
versions of these external modules.

Using CPM
=========

To use CPM in your C++ project include the following at the top of your
CMakeLists.txt::

  #------------------------------------------------------------------------------
  # Required CPM Setup - See: http://github.com/iauns/cpm
  #------------------------------------------------------------------------------
  # You may set CPM_DIR to any path you want. Outside of the binary directory,
  # or anywhere on your harddrive. Any project that wants to use the same
  # version of any module can benefit immediately from the built packages.
  # Just be careful of pre-project settings for modules.
  set(CPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpm-packages" CACHE TYPE STRING)
  
  find_package(Git)
  if(NOT GIT_FOUND)
    message(FATAL_ERROR "CPM requires Git.")
  endif()
  if (NOT EXISTS ${CPM_DIR}/CPM.cmake)
    execute_process(
      COMMAND "${GIT_EXECUTABLE}" clone https://github.com/iauns/cpm ${CPM_DIR}
      RESULT_VARIABLE error_code
      OUTPUT_VARIABLE head_sha
      )
    if(error_code)
      message(FATAL_ERROR "CPM failed to get the hash for HEAD")
    endif()
  endif()
  include(${CPM_DIR}/CPM.cmake)
  
  # Include any modules and externals here...
  
  CPM_Finish()

Then add the ``${CPM_LIBRARIES}`` variable to your ``target_link_libraries``.
That's it. You will be able to start using CPM modules right away by adding
something like::

  CPM_AddModule("spire"
    GIT_REPOSITORY "https://github.com/SCIInstitute/spire"
    GIT_TAG "v0.7.0")

This snippet will automatically download, build, and link version 0.7.0 of a
thin OpenGL client named Spire. A new namespace is generated for 'spire' and a
preprocessor definition for this namespace is automatically added to your
project. The namespace preprocessor definition always follows the form
"``CPM_<NAME>_NS``" where ``<NAME>`` is the first argument of your call to
``CPM_AddModule``. The name is always capitalized before being added to your
preprocessor definitions.

For example, in the 'spire' snippet above, the preprocessor definition
``CPM_SPIRE_NS`` would be added to our project. This declares the namepsace
under which CPM has bound the 'Spire' module. You can access spire's interface
class through this namespace like so: ``CPM_SPIRE_NS::Interface``. In general
you will want to rename the namespace to something more appropriate:
``namespace spire = CPM_SPIRE_NS;``. It has been our experience that building a
header containing all of your module namespaces is quite useful. Something like
the following::

  #ifndef __MY_NAMESPACES_H
  #define __MY_NAMESPACES_H

  // 'Forward declaration' of CPM module namespaces.
  namespace CPM_SPIRE_NS {}
  namespace CPM_SPIRE_SCIRUN_NS {}
  ... (more forward declarations) ...
  
  // Renaming the namespaces in our top level namespace.
  namespace my_namespace {
    namespace spire     = CPM_SPIRE_NS;
    namespace spire_sr  = CPM_SPIRE_SCIRUN_NS;
  }

  #endif

Also be sure to place your calls to CPM_AddModule before your call to
CPM_Finish. The ``# Include any modules here...`` section mentioned in the
first snippet indicates where you should place calls to ``CPM_AddModule``.

Remember not to expose your namespaces.h header file in your public interface.
Use the preprocessor definitions in your public interface. If you absolutely
must include the namespaces header file in your public interface, then ensure
you give the include guard for your namespaces header a unique name.

CPM Externals
-------------

If the library you are interested in isn't a CPM module, try browsing through
the CPM externals listed on http://www.cppcpm.org. While you won't be able to
statically link against multiple versions of the library, you can quickly
include it if there is already CPM external formula for it. Just use
CPM_AddModule as you would with any other module.

If you don't find a formula for your favorite library, kindly consider
contributing one to our CPM externals repository. We're always looking to
expand these formulae.

Advantages
----------

* Automatically manages code retrieval and the building of CPM modules and externals.
* Allows the use of multiple different versions of the same statically linked
  module in the same executable.
* Built entirely in CMake. Nothing else is required.
* Encourages small well-tested and composable code modules.
* All CPM module code will be included in any generated project solution.
* Will automatically detect naming conflicts based on the names you assign 
  modules.

Limitations
-----------

* Only supports git.

Building CPM Modules
====================

If you only want to use pre-existing CPM modules and aren't interested in
building modules yourself, feel free to skip this section. But, if you are
interested in building CPM modules then please read on as some guidelines and
requirements are listed below.

CMakeLists.txt Entry
--------------------

There must be a CMakeLists.txt at the root of your module project and this
CMakeLists.txt file must contain all relevant CPM directives and code (see
below). Do not use issue calls to CPM (``CPM_*``) in a subdirectory
(``add_subdirectory``).

Add the following to the top of the CMakeLists.txt for your module:: 

  #-----------------------------------------------------------------------
  # CPM configuration
  #-----------------------------------------------------------------------
  set(CPM_MODULE_NAME <name>)
  set(CPM_LIB_TARGET_NAME ${CPM_MODULE_NAME})
  
  if ((DEFINED CPM_DIR) AND (DEFINED CPM_UNIQUE_ID) AND (DEFINED CPM_TARGET_NAME))
    set(CPM_LIB_TARGET_NAME ${CPM_TARGET_NAME})
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CPM_DIR})
    include(CPM)
  else()
    set(CPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpm-packages" CACHE TYPE STRING)
    find_package(Git)
    if(NOT GIT_FOUND)
      message(FATAL_ERROR "CPM requires Git.")
    endif()
    if (NOT EXISTS ${CPM_DIR}/CPM.cmake)
      execute_process(
        COMMAND "${GIT_EXECUTABLE}" clone https://github.com/iauns/cpm ${CPM_DIR}
        RESULT_VARIABLE error_code
        OUTPUT_VARIABLE head_sha)
      if(error_code)
        message(FATAL_ERROR "CPM failed to get the hash for HEAD")
      endif()
    endif()
    include(${CPM_DIR}/CPM.cmake)
  endif()
  
  # Include CPM modules or externals here (with CPM_AddModule).
  
  CPM_InitModule(${CPM_MODULE_NAME})
{'fraction_non_alphanumeric': 0.1226484568521122, 'fraction_numerical': 0.0008033741715203856, 'mean_word_length': 3.1072312345339568, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 6, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1135017', 'n_tokens_mistral': 4248, 'n_tokens_neox': 4079, 'n_words': 1816}