diff options
Diffstat (limited to 'Help')
162 files changed, 4142 insertions, 60 deletions
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index dde4dbb..40f1c1a 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -89,7 +89,8 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: searched after paths from the current module, i.e. ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``, ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc. - This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed. + This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting + the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``. See policy :policy:`CMP0074`. * |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| @@ -97,7 +98,8 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: 2. Search paths specified in cmake-specific cache variables. These are intended to be used on the command line with a ``-DVAR=value``. The values are interpreted as :ref:`semicolon-separated lists <CMake Language Lists>`. - This can be skipped if ``NO_CMAKE_PATH`` is passed. + This can be skipped if ``NO_CMAKE_PATH`` is passed or by setting the + :variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``. * |CMAKE_PREFIX_PATH_XXX| * |CMAKE_XXX_PATH| @@ -107,7 +109,8 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: These are intended to be set in the user's shell configuration, and therefore use the host's native path separator (``;`` on Windows and ``:`` on UNIX). - This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed. + This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or + by setting the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``. * |CMAKE_PREFIX_PATH_XXX| * |CMAKE_XXX_PATH| @@ -119,13 +122,16 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: Hard-coded guesses should be specified with the ``PATHS`` option. 5. Search the standard system environment variables. - This can be skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is an argument. + This can be skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed or by + setting the :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH` to ``FALSE``. * |SYSTEM_ENVIRONMENT_PATH_XXX| + * |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| 6. Search cmake variables defined in the Platform files for the current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` - is passed. + is passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` + to ``FALSE``. * |CMAKE_SYSTEM_PREFIX_PATH_XXX| * |CMAKE_SYSTEM_XXX_PATH| diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst index 46b9b63..884b2ee 100644 --- a/Help/command/add_test.rst +++ b/Help/command/add_test.rst @@ -7,7 +7,8 @@ Add a test to the project to be run by :manual:`ctest(1)`. add_test(NAME <name> COMMAND <command> [<arg>...] [CONFIGURATIONS <config>...] - [WORKING_DIRECTORY <dir>]) + [WORKING_DIRECTORY <dir>] + [COMMAND_EXPAND_LISTS]) Adds a test called ``<name>``. The test name may not contain spaces, quotes, or other characters special in CMake syntax. The options are: @@ -28,6 +29,11 @@ quotes, or other characters special in CMake syntax. The options are: directory set to the build directory corresponding to the current source directory. +``COMMAND_EXPAND_LISTS`` + Lists in ``COMMAND`` arguments will be expanded, including those + created with + :manual:`generator expressions <cmake-generator-expressions(7)>`. + The given test command is expected to exit with code ``0`` to pass and non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test property is set. Any output written to stdout or stderr will be diff --git a/Help/command/file.rst b/Help/command/file.rst index f99021e..c06451a 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -13,6 +13,7 @@ Synopsis file(`STRINGS`_ <filename> <out-var> [...]) file(`\<HASH\> <HASH_>`_ <filename> <out-var>) file(`TIMESTAMP`_ <filename> <out-var> [...]) + file(`GET_RUNTIME_DEPENDENCIES`_ [...]) `Writing`_ file({`WRITE`_ | `APPEND`_} <filename> <content>...) @@ -130,6 +131,273 @@ timestamp variable will be set to the empty string (""). See the :command:`string(TIMESTAMP)` command for documentation of the ``<format>`` and ``UTC`` options. +.. _GET_RUNTIME_DEPENDENCIES: + +.. code-block:: cmake + + file(GET_RUNTIME_DEPENDENCIES + [RESOLVED_DEPENDENCIES_VAR <deps_var>] + [UNRESOLVED_DEPENDENCIES_VAR <unresolved_deps_var>] + [CONFLICTING_DEPENDENICES_PREFIX <conflicting_deps_prefix>] + [EXECUTABLES [<executable_files>...]] + [LIBRARIES [<library_files>...]] + [MODULES [<module_files>...]] + [DIRECTORIES [<directories>...]] + [BUNDLE_EXECUTABLE <bundle_executable_file>] + [PRE_INCLUDE_REGEXES [<regexes>...]] + [PRE_EXCLUDE_REGEXES [<regexes>...]] + [POST_INCLUDE_REGEXES [<regexes>...]] + [POST_EXCLUDE_REGEXES [<regexes>...]] + ) + +Recursively get the list of libraries depended on by the given files. + +Please note that this sub-command is not intended to be used in project mode. +Instead, use it in an :command:`install(CODE)` or :command:`install(SCRIPT)` +block. For example: + +.. code-block:: cmake + + install(CODE [[ + file(GET_RUNTIME_DEPENDENCIES + # ... + ) + ]]) + +The arguments are as follows: + +``RESOLVED_DEPENDENCIES_VAR <deps_var>`` + Name of the variable in which to store the list of resolved dependencies. + +``UNRESOLVED_DEPENDENCIES_VAR <unresolved_deps_var>`` + Name of the variable in which to store the list of unresolved dependencies. + If this variable is not specified, and there are any unresolved dependencies, + an error is issued. + +``CONFLICTING_DEPENDENCIES_PREFIX <conflicting_deps_prefix>`` + Variable prefix in which to store conflicting dependency information. + Dependencies are conflicting if two files with the same name are found in + two different directories. The list of filenames that conflict are stored in + ``<conflicting_deps_prefix>_FILENAMES``. For each filename, the list of paths + that were found for that filename are stored in + ``<conflicting_deps_prefix>_<filename>``. + +``EXECUTABLES <executable_files>`` + List of executable files to read for dependencies. These are executables that + are typically created with :command:`add_executable`, but they do not have to + be created by CMake. On Apple platforms, the paths to these files determine + the value of ``@executable_path`` when recursively resolving the libraries. + Specifying ``STATIC`` libraries, ``MODULE`` s, or ``SHARED`` libraries here + will result in undefined behavior. + +``LIBRARIES <library_files>`` + List of library files to read for dependencies. These are libraries that are + typically created with :command:`add_library(SHARED)`, but they do not have + to be created by CMake. Specifying ``STATIC`` libraries, ``MODULE`` s, or + executables here will result in undefined behavior. + +``MODULES <module_files>`` + List of loadable module files to read for dependencies. These are modules + that are typically created with :command:`add_library(MODULE)`, but they do + not have to be created by CMake. They are typically used by calling + ``dlopen()`` at runtime rather than linked at link time with ``ld -l``. + Specifying ``STATIC`` libraries, ``SHARED`` libraries, or executables here + will result in undefined behavior. + +``DIRECTORIES <directories>`` + List of additional directories to search for dependencies. On Linux + platforms, these directories are searched if the dependency is not found in + any of the other usual paths. If it is found in such a directory, a warning + is issued, because it means that the file is incomplete (it does not list all + of the directories that contain its dependencies.) On Windows platforms, + these directories are searched if the dependency is not found in any of the + other search paths, but no warning is issued, because searching other paths + is a normal part of Windows dependency resolution. On Apple platforms, this + argument has no effect. + +``BUNDLE_EXECTUBLE <bundle_executable_file>`` + Executable to treat as the "bundle executable" when resolving libraries. On + Apple platforms, this argument determines the value of ``@executable_path`` + when recursively resolving libraries for ``LIBRARIES`` and ``MODULES`` files. + It has no effect on ``EXECUTABLES`` files. On other platforms, it has no + effect. This is typically (but not always) one of the executables in the + ``EXECUTABLES`` argument which designates the "main" executable of the + package. + +The following arguments specify filters for including or excluding libraries to +be resolved. See below for a full description of how they work. + +``PRE_INCLUDE_REGEXES <regexes>`` + List of pre-include regexes through which to filter the names of + not-yet-resolved dependencies. + +``PRE_EXCLUDE_REGEXES <regexes>`` + List of pre-exclude regexes through which to filter the names of + not-yet-resolved dependencies. + +``POST_INCLUDE_REGEXES <regexes>`` + List of post-include regexes through which to filter the names of resolved + dependencies. + +``POST_EXCLUDE_REGEXES <regexes>`` + List of post-exclude regexes through which to filter the names of resolved + dependencies. + +These arguments can be used to blacklist unwanted system libraries when +resolving the dependencies, or to whitelist libraries from a specific +directory. The filtering works as follows: + +1. If the not-yet-resolved dependency matches any of the + ``PRE_INCLUDE_REGEXES``, steps 2 and 3 are skipped, and the dependency + resolution proceeds to step 4. +2. If the not-yet-resolved dependency matches any of the + ``PRE_EXCLUDE_REGEXES``, dependency resolution stops for that dependency. +3. Otherwise, dependency resolution proceeds. +4. ``file(GET_RUNTIME_DEPENDENCIES)`` searches for the dependency according to + the linking rules of the platform (see below). +5. If the dependency is found, and its full path matches one of the + ``POST_INCLUDE_REGEXES``, the full path is added to the resolved + dependencies, and ``file(GET_RUNTIME_DEPENDENCIES)`` recursively resolves + that library's own dependencies. Otherwise, resolution proceeds to step 6. +6. If the dependency is found, but its full path matches one of the + ``POST_EXCLUDE_REGEXES``, it is not added to the resolved dependencies, and + dependency resolution stops for that dependency. +7. If the dependency is found, and its full path does not match either + ``POST_INCLUDE_REGEXES`` or ``POST_EXCLUDE_REGEXES``, the full path is added + to the resolved dependencies, and ``file(GET_RUNTIME_DEPENDENCIES)`` + recursively resolves that library's own dependencies. + +Different platforms have different rules for how dependencies are resolved. +These specifics are described here. + +On Linux platforms, library resolution works as follows: + +1. If the depending file does not have any ``RUNPATH`` entries, and the library + exists in one of the depending file's ``RPATH`` entries, or its parents', in + that order, the dependency is resolved to that file. +2. Otherwise, if the depending file has any ``RUNPATH`` entries, and the + library exists in one of those entries, the dependency is resolved to that + file. +3. Otherwise, if the library exists in one of the directories listed by + ``ldconfig``, the dependency is resolved to that file. +4. Otherwise, if the library exists in one of the ``DIRECTORIES`` entries, the + dependency is resolved to that file. In this case, a warning is issued, + because finding a file in one of the ``DIRECTORIES`` means that the + depending file is not complete (it does not list all the directories from + which it pulls dependencies.) +5. Otherwise, the dependency is unresolved. + +On Windows platforms, library resolution works as follows: + +1. The dependent DLL name is converted to lowercase. Windows DLL names are + case-insensitive, and some linkers mangle the case of the DLL dependency + names. However, this makes it more difficult for ``PRE_INCLUDE_REGEXES``, + ``PRE_EXCLUDE_REGEXES``, ``POST_INCLUDE_REGEXES``, and + ``POST_EXCLUDE_REGEXES`` to properly filter DLL names - every regex would + have to check for both uppercase and lowercase letters. For example: + + .. code-block:: cmake + + file(GET_RUNTIME_DEPENDENCIES + # ... + PRE_INCLUDE_REGEXES "^[Mm][Yy][Ll][Ii][Bb][Rr][Aa][Rr][Yy]\\.[Dd][Ll][Ll]$" + ) + + Converting the DLL name to lowercase allows the regexes to only match + lowercase names, thus simplifying the regex. For example: + + .. code-block:: cmake + + file(GET_RUNTIME_DEPENDENCIES + # ... + PRE_INCLUDE_REGEXES "^mylibrary\\.dll$" + ) + + This regex will match ``mylibrary.dll`` regardless of how it is cased, + either on disk or in the depending file. (For example, it will match + ``mylibrary.dll``, ``MyLibrary.dll``, and ``MYLIBRARY.DLL``.) + + Please note that the directory portion of any resolved DLLs retains its + casing and is not converted to lowercase. Only the filename portion is + converted. + +2. (**Not yet implemented**) If the depending file is a Windows Store app, and + the dependency is listed as a dependency in the application's package + manifest, the dependency is resolved to that file. +3. Otherwise, if the library exists in the same directory as the depending + file, the dependency is resolved to that file. +4. Otherwise, if the library exists in either the operating system's + ``system32`` directory or the ``Windows`` directory, in that order, the + dependency is resolved to that file. +5. Otherwise, if the library exists in one of the directories specified by + ``DIRECTORIES``, in the order they are listed, the dependency is resolved to + that file. (In this case, a warning is not issued, because searching other + directories is a normal part of Windows library resolution.) +6. Otherwise, the dependency is unresolved. + +On Apple platforms, library resolution works as follows: + +1. If the dependency starts with ``@executable_path/``, and an ``EXECUTABLES`` + argument is in the process of being resolved, and replacing + ``@executable_path/`` with the directory of the executable yields an + existing file, the dependency is resolved to that file. +2. Otherwise, if the dependency starts with ``@executable_path/``, and there is + a ``BUNDLE_EXECUTABLE`` argument, and replacing ``@executable_path/`` with + the directory of the bundle executable yields an existing file, the + dependency is resolved to that file. +3. Otherwise, if the dependency starts with ``@loader_path/``, and replacing + ``@loader_path/`` with the directory of the depending file yields an + existing file, the dependency is resolved to that file. +4. Otherwise, if the dependency starts with ``@rpath/``, and replacing + ``@rpath/`` with one of the ``RPATH`` entries of the depending file yields + an existing file, the dependency is resolved to that file. (Note that + ``RPATH`` entries that start with ``@executable_path/`` or ``@loader_path/`` + also have these items replaced with the appropriate path.) +5. Otherwise, if the dependency is an absolute file that exists, the dependency + is resolved to that file. +6. Otherwise, the dependency is unresolved. + +This function accepts several variables that determine which tool is used for +dependency resolution: + +.. variable:: CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM + + Determines which operating system and executable format the files are built + for. This could be one of several values: + + * ``linux+elf`` + * ``windows+pe`` + * ``macos+macho`` + + If this variable is not specified, it is determined automatically by system + introspection. + +.. variable:: CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL + + Determines the tool to use for dependency resolution. It could be one of + several values, depending on the value of + :variable:`CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM`: + + ================================================= ============================================= + ``CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM`` ``CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL`` + ================================================= ============================================= + ``linux+elf`` ``objdump`` + ``windows+pe`` ``dumpbin`` + ``windows+pe`` ``objdump`` + ``macos+macho`` ``otool`` + ================================================= ============================================= + + If this variable is not specified, it is determined automatically by system + introspection. + +.. variable:: CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND + + Determines the path to the tool to use for dependency resolution. This is the + actual path to ``objdump``, ``dumpbin``, or ``otool``. + + If this variable is not specified, it is determined automatically by system + introspection. + Writing ^^^^^^^ @@ -235,6 +503,11 @@ regular expressions, but much simpler. If ``RELATIVE`` flag is specified, the results will be returned as relative paths to the given path. The results will be ordered lexicographically. +On Windows and macOS, globbing is case-insensitive even if the underlying +filesystem is case-sensitive (both filenames and globbing expressions are +converted to lowercase before matching). On other platforms, globbing is +case-sensitive. + If the ``CONFIGURE_DEPENDS`` flag is specified, CMake will add logic to the main build system check target to rerun the flagged ``GLOB`` commands at build time. If any of the outputs change, CMake will regenerate the build diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst index 2a14ad7..3f03f37 100644 --- a/Help/command/find_file.rst +++ b/Help/command/find_file.rst @@ -17,11 +17,10 @@ find_file .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``. - On Windows hosts: - ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` - is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the - directories in ``PATH`` itself. +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` and ``INCLUDE``. +.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: + ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` + is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst index 0861d67..8a55aca 100644 --- a/Help/command/find_library.rst +++ b/Help/command/find_library.rst @@ -17,11 +17,10 @@ find_library .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``LIB``. - On Windows hosts: - ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set, - and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, - and the directories in ``PATH`` itself. +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` and ``INCLUDE``. +.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: + ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` + is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set, diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index e5e5b2c..6e1d232 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -330,8 +330,10 @@ enabled. 6. Search paths stored in the CMake :ref:`User Package Registry`. This can be skipped if ``NO_CMAKE_PACKAGE_REGISTRY`` is passed or by - setting the :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` - to ``TRUE``. + setting the variable :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` + to ``FALSE`` or the deprecated variable + :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` to ``TRUE``. + See the :manual:`cmake-packages(7)` manual for details on the user package registry. diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst index 988a3fa..52ffe3c 100644 --- a/Help/command/find_path.rst +++ b/Help/command/find_path.rst @@ -17,11 +17,10 @@ find_path .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``. - On Windows hosts: - ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` - is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the - directories in ``PATH`` itself. +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` and ``INCLUDE``. +.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: + ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` + is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst index 4f00773..e2ff693 100644 --- a/Help/command/find_program.rst +++ b/Help/command/find_program.rst @@ -15,7 +15,8 @@ find_program .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH` -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: ``PATH`` +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` itself. +.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts no extra search paths are included .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR| diff --git a/Help/command/install.rst b/Help/command/install.rst index ab6fef6..5affc5b 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -126,6 +126,8 @@ project. There are several kinds of target files that may be installed: marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK`` below.) For DLL platforms (all Windows-based systems including Cygwin), the DLL import library is treated as an ``ARCHIVE`` target. + On AIX, the linker import file created for executables with + :prop_tgt:`ENABLE_EXPORTS` is treated as an ``ARCHIVE`` target. ``LIBRARY`` Module libraries are always treated as ``LIBRARY`` targets. For non- diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt new file mode 100644 index 0000000..e84f932 --- /dev/null +++ b/Help/guide/tutorial/Complete/CMakeLists.txt @@ -0,0 +1,115 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +if(APPLE) + set(CMAKE_INSTALL_RPATH "@executable_path/../lib") +elseif(UNIX) + set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") +endif() + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) + +# install the configuration targets +install(EXPORT MathFunctionsTargets + FILE MathFunctionsTargets.cmake + DESTINATION lib/cmake/MathFunctions +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" + VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion +) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + DESTINATION lib/cmake/MathFunctions + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT MathFunctionsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" +) diff --git a/Help/guide/tutorial/Complete/Config.cmake.in b/Help/guide/tutorial/Complete/Config.cmake.in new file mode 100644 index 0000000..17cbabd --- /dev/null +++ b/Help/guide/tutorial/Complete/Config.cmake.in @@ -0,0 +1,4 @@ + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) diff --git a/Help/guide/tutorial/Complete/License.txt b/Help/guide/tutorial/Complete/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Complete/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..63c0f5f --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt @@ -0,0 +1,68 @@ +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# setup the version numbering +set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0") +set_property(TARGET MathFunctions PROPERTY SOVERSION "1") + +# install rules +install(TARGETS MathFunctions + DESTINATION lib + EXPORT MathFunctionsTargets) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Help/guide/tutorial/Complete/TutorialConfig.h.in b/Help/guide/tutorial/Complete/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Help/guide/tutorial/Complete/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Complete/tutorial.cxx b/Help/guide/tutorial/Complete/tutorial.cxx new file mode 100644 index 0000000..4451cbd --- /dev/null +++ b/Help/guide/tutorial/Complete/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Consumer/CMakeLists.txt b/Help/guide/tutorial/Consumer/CMakeLists.txt new file mode 100644 index 0000000..5097917 --- /dev/null +++ b/Help/guide/tutorial/Consumer/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.3) + +if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + + +function(find_external_dependency name) + set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}") + mark_as_advanced(${name}_DIR) + find_package(${name} PATHS ${${name}_ROOT} REQUIRED) +endfunction() + + +project(Consumer) + +find_external_dependency(MathFunctions) + +add_library(consumer consumer.cxx) +target_link_libraries(consumer PUBLIC MathFunctions) + +# install the consumer library +install(TARGETS consumer DESTINATION bin EXPORT ConsumerTargets) + +# install the configuration targets +install(EXPORT ConsumerTargets + FILE ConsumerTargets.cmake + DESTINATION lib/cmake/Consumer +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake + DESTINATION lib/cmake/Consumer + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT ConsumerTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/ConsumerTargets.cmake" +) diff --git a/Help/guide/tutorial/Consumer/Config.cmake.in b/Help/guide/tutorial/Consumer/Config.cmake.in new file mode 100644 index 0000000..0b3f1e4 --- /dev/null +++ b/Help/guide/tutorial/Consumer/Config.cmake.in @@ -0,0 +1,14 @@ + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +function(find_external_dependency name) + set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}") + mark_as_advanced(${name}_DIR) + find_dependency(${name} PATHS ${${name}_ROOT} REQUIRED) +endfunction() + +find_external_dependency(MathFunctions) + +include ( "${CMAKE_CURRENT_LIST_DIR}/ConsumerTargets.cmake" ) diff --git a/Help/guide/tutorial/Consumer/consumer.cxx b/Help/guide/tutorial/Consumer/consumer.cxx new file mode 100644 index 0000000..ae7877b --- /dev/null +++ b/Help/guide/tutorial/Consumer/consumer.cxx @@ -0,0 +1,11 @@ +// A simple function that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" + +double string_square_root(std::string const& value) +{ + return mathfunctions::sqrt(std::stod(value)); +} diff --git a/Help/guide/tutorial/MultiPackage/CMakeLists.txt b/Help/guide/tutorial/MultiPackage/CMakeLists.txt new file mode 100644 index 0000000..067e807 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +# control how we mark up Debug libraries compared to Release libraries +set(CMAKE_DEBUG_POSTFIX "-d") + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) + +# install the configuration targets +install(EXPORT MathFunctionsTargets + FILE MathFunctionsTargets.cmake + DESTINATION lib/cmake/MathFunctions +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" + VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion +) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + DESTINATION lib/cmake/MathFunctions + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT MathFunctionsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" +) diff --git a/Help/guide/tutorial/MultiPackage/Config.cmake.in b/Help/guide/tutorial/MultiPackage/Config.cmake.in new file mode 100644 index 0000000..17cbabd --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/Config.cmake.in @@ -0,0 +1,4 @@ + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) diff --git a/Help/guide/tutorial/MultiPackage/License.txt b/Help/guide/tutorial/MultiPackage/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..161ad64 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt @@ -0,0 +1,68 @@ + +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# setup the version numbering +set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0") +set_property(TARGET MathFunctions PROPERTY SOVERSION "1") + +install(TARGETS MathFunctions + DESTINATION lib + EXPORT MathFunctionsTargets) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h b/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h b/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake b/Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake new file mode 100644 index 0000000..403b633 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake @@ -0,0 +1,7 @@ + +include("release/CPackConfig.cmake") + +set(CPACK_INSTALL_CMAKE_PROJECTS + "debug;Tutorial;ALL;/" + "release;Tutorial;ALL;/" + ) diff --git a/Help/guide/tutorial/MultiPackage/TutorialConfig.h.in b/Help/guide/tutorial/MultiPackage/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/MultiPackage/tutorial.cxx b/Help/guide/tutorial/MultiPackage/tutorial.cxx new file mode 100644 index 0000000..4451cbd --- /dev/null +++ b/Help/guide/tutorial/MultiPackage/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step1/CMakeLists.txt b/Help/guide/tutorial/Step1/CMakeLists.txt new file mode 100644 index 0000000..141f0c2 --- /dev/null +++ b/Help/guide/tutorial/Step1/CMakeLists.txt @@ -0,0 +1,3 @@ +project(Tutorial) + +add_executable(Tutorial tutorial.cxx) diff --git a/Help/guide/tutorial/Step1/TutorialConfig.h.in b/Help/guide/tutorial/Step1/TutorialConfig.h.in new file mode 100644 index 0000000..7e4d7fa --- /dev/null +++ b/Help/guide/tutorial/Step1/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Step1/tutorial.cxx b/Help/guide/tutorial/Step1/tutorial.cxx new file mode 100644 index 0000000..f8dd0c6 --- /dev/null +++ b/Help/guide/tutorial/Step1/tutorial.cxx @@ -0,0 +1,20 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <cstdlib> +#include <iostream> +#include <string> + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = atof(argv[1]); + + double outputValue = sqrt(inputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt new file mode 100644 index 0000000..5819272 --- /dev/null +++ b/Help/guide/tutorial/Step10/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# Set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Help/guide/tutorial/Step10/License.txt b/Help/guide/tutorial/Step10/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Step10/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..aafd090 --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt @@ -0,0 +1,61 @@ +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + # state that SqrtLibrary need PIC when the default is shared libraries + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") + if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(SqrtLibrary + PRIVATE "HAVE_LOG" "HAVE_EXP") + endif() + + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Help/guide/tutorial/Step10/TutorialConfig.h.in b/Help/guide/tutorial/Step10/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Help/guide/tutorial/Step10/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Step10/tutorial.cxx b/Help/guide/tutorial/Step10/tutorial.cxx new file mode 100644 index 0000000..42eaab9 --- /dev/null +++ b/Help/guide/tutorial/Step10/tutorial.cxx @@ -0,0 +1,26 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step11/CMakeLists.txt b/Help/guide/tutorial/Step11/CMakeLists.txt new file mode 100644 index 0000000..2e5cb15 --- /dev/null +++ b/Help/guide/tutorial/Step11/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Help/guide/tutorial/Step11/License.txt b/Help/guide/tutorial/Step11/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Step11/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..ea42770 --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt @@ -0,0 +1,60 @@ +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +#building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Help/guide/tutorial/Step11/TutorialConfig.h.in b/Help/guide/tutorial/Step11/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Help/guide/tutorial/Step11/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Step11/tutorial.cxx b/Help/guide/tutorial/Step11/tutorial.cxx new file mode 100644 index 0000000..6acafd2 --- /dev/null +++ b/Help/guide/tutorial/Step11/tutorial.cxx @@ -0,0 +1,26 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt new file mode 100644 index 0000000..1f43b2b --- /dev/null +++ b/Help/guide/tutorial/Step2/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the executable +add_executable(Tutorial tutorial.cxx) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) diff --git a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..8b443a6 --- /dev/null +++ b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt @@ -0,0 +1 @@ +add_library(MathFunctions mysqrt.cxx) diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..7d9379e --- /dev/null +++ b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx @@ -0,0 +1,23 @@ +#include "MathFunctions.h" +#include <iostream> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + double result = x; + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + return result; +} diff --git a/Help/guide/tutorial/Step2/TutorialConfig.h.in b/Help/guide/tutorial/Step2/TutorialConfig.h.in new file mode 100644 index 0000000..7e4d7fa --- /dev/null +++ b/Help/guide/tutorial/Step2/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Step2/tutorial.cxx b/Help/guide/tutorial/Step2/tutorial.cxx new file mode 100644 index 0000000..f2ab446 --- /dev/null +++ b/Help/guide/tutorial/Step2/tutorial.cxx @@ -0,0 +1,24 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + double outputValue = sqrt(inputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt new file mode 100644 index 0000000..966c38a --- /dev/null +++ b/Help/guide/tutorial/Step3/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) + list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions") +endif(USE_MYMATH) + +# add the executable +add_executable(Tutorial tutorial.cxx) + +target_link_libraries(Tutorial ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ${EXTRA_INCLUDES} + ) diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..8b443a6 --- /dev/null +++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt @@ -0,0 +1 @@ +add_library(MathFunctions mysqrt.cxx) diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..7d9379e --- /dev/null +++ b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx @@ -0,0 +1,23 @@ +#include "MathFunctions.h" +#include <iostream> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + double result = x; + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + return result; +} diff --git a/Help/guide/tutorial/Step3/TutorialConfig.h.in b/Help/guide/tutorial/Step3/TutorialConfig.h.in new file mode 100644 index 0000000..e23f521 --- /dev/null +++ b/Help/guide/tutorial/Step3/TutorialConfig.h.in @@ -0,0 +1,4 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH diff --git a/Help/guide/tutorial/Step3/tutorial.cxx b/Help/guide/tutorial/Step3/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step3/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt new file mode 100644 index 0000000..a157bda --- /dev/null +++ b/Help/guide/tutorial/Step4/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) + +# add the executable +add_executable(Tutorial tutorial.cxx) + +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..0515852 --- /dev/null +++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(MathFunctions mysqrt.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..7d9379e --- /dev/null +++ b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx @@ -0,0 +1,23 @@ +#include "MathFunctions.h" +#include <iostream> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + double result = x; + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + return result; +} diff --git a/Help/guide/tutorial/Step4/TutorialConfig.h.in b/Help/guide/tutorial/Step4/TutorialConfig.h.in new file mode 100644 index 0000000..e23f521 --- /dev/null +++ b/Help/guide/tutorial/Step4/TutorialConfig.h.in @@ -0,0 +1,4 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH diff --git a/Help/guide/tutorial/Step4/tutorial.cxx b/Help/guide/tutorial/Step4/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step4/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt new file mode 100644 index 0000000..76b9179 --- /dev/null +++ b/Help/guide/tutorial/Step5/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..b12f27d --- /dev/null +++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(MathFunctions mysqrt.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..7d9379e --- /dev/null +++ b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx @@ -0,0 +1,23 @@ +#include "MathFunctions.h" +#include <iostream> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + double result = x; + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + return result; +} diff --git a/Help/guide/tutorial/Step5/TutorialConfig.h.in b/Help/guide/tutorial/Step5/TutorialConfig.h.in new file mode 100644 index 0000000..e23f521 --- /dev/null +++ b/Help/guide/tutorial/Step5/TutorialConfig.h.in @@ -0,0 +1,4 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH diff --git a/Help/guide/tutorial/Step5/tutorial.cxx b/Help/guide/tutorial/Step5/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step5/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt new file mode 100644 index 0000000..5829891 --- /dev/null +++ b/Help/guide/tutorial/Step6/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..def1140 --- /dev/null +++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(MathFunctions mysqrt.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ) + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..b9ad20a --- /dev/null +++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx @@ -0,0 +1,33 @@ +#include "MathFunctions.h" +#include "TutorialConfig.h" +#include <iostream> + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + double result = x; + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} diff --git a/Help/guide/tutorial/Step6/TutorialConfig.h.in b/Help/guide/tutorial/Step6/TutorialConfig.h.in new file mode 100644 index 0000000..e97ce24 --- /dev/null +++ b/Help/guide/tutorial/Step6/TutorialConfig.h.in @@ -0,0 +1,8 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH + +// does the platform provide exp and log functions? +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP diff --git a/Help/guide/tutorial/Step6/tutorial.cxx b/Help/guide/tutorial/Step6/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step6/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt new file mode 100644 index 0000000..17e6a60 --- /dev/null +++ b/Help/guide/tutorial/Step7/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Help/guide/tutorial/Step7/License.txt b/Help/guide/tutorial/Step7/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Step7/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..3c3a816 --- /dev/null +++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt @@ -0,0 +1,30 @@ +# first we add the executable that generates the table +add_executable(MakeTable MakeTable.cxx) + +# add the command to generate the source code +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..5272f56 --- /dev/null +++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx @@ -0,0 +1,34 @@ +#include "MathFunctions.h" +#include "TutorialConfig.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + + return result; +} diff --git a/Help/guide/tutorial/Step7/TutorialConfig.h.in b/Help/guide/tutorial/Step7/TutorialConfig.h.in new file mode 100644 index 0000000..e97ce24 --- /dev/null +++ b/Help/guide/tutorial/Step7/TutorialConfig.h.in @@ -0,0 +1,8 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH + +// does the platform provide exp and log functions? +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP diff --git a/Help/guide/tutorial/Step7/tutorial.cxx b/Help/guide/tutorial/Step7/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step7/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt new file mode 100644 index 0000000..86725e8 --- /dev/null +++ b/Help/guide/tutorial/Step8/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) +add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +# setup installer +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Help/guide/tutorial/Step8/License.txt b/Help/guide/tutorial/Step8/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Step8/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..3c3a816 --- /dev/null +++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt @@ -0,0 +1,30 @@ +# first we add the executable that generates the table +add_executable(MakeTable MakeTable.cxx) + +# add the command to generate the source code +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step8/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step8/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step8/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..5b862fb --- /dev/null +++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx @@ -0,0 +1,42 @@ +#include "MathFunctions.h" +#include "TutorialConfig.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} diff --git a/Help/guide/tutorial/Step8/TutorialConfig.h.in b/Help/guide/tutorial/Step8/TutorialConfig.h.in new file mode 100644 index 0000000..e97ce24 --- /dev/null +++ b/Help/guide/tutorial/Step8/TutorialConfig.h.in @@ -0,0 +1,8 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH + +// does the platform provide exp and log functions? +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP diff --git a/Help/guide/tutorial/Step8/tutorial.cxx b/Help/guide/tutorial/Step8/tutorial.cxx new file mode 100644 index 0000000..8156a9c --- /dev/null +++ b/Help/guide/tutorial/Step8/tutorial.cxx @@ -0,0 +1,35 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt new file mode 100644 index 0000000..07ab90a --- /dev/null +++ b/Help/guide/tutorial/Step9/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 14) + +# set the version number +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +include(CTest) + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Help/guide/tutorial/Step9/CTestConfig.cmake b/Help/guide/tutorial/Step9/CTestConfig.cmake new file mode 100644 index 0000000..7a927ac --- /dev/null +++ b/Help/guide/tutorial/Step9/CTestConfig.cmake @@ -0,0 +1,15 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## +## # The following are required to submit to the CDash dashboard: +## ENABLE_TESTING() +## INCLUDE(CTest) + +set(CTEST_PROJECT_NAME "CMakeTutorial") +set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Help/guide/tutorial/Step9/License.txt b/Help/guide/tutorial/Step9/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Help/guide/tutorial/Step9/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..c8cd1dd --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt @@ -0,0 +1,36 @@ +# first we add the executable that generates the table +add_executable(MakeTable MakeTable.cxx) + +# add the command to generate the source code +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR} + ) + +# use compile definitions to state if we have enabled USE_MYMATH +# and that anything that links to use will get this define +target_compile_definitions(MathFunctions INTERFACE "USE_MYMATH") + +if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(MathFunctions + PRIVATE "HAVE_LOG" "HAVE_EXP") +endif() + +# install rules +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..8b82141 --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx @@ -0,0 +1,41 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Help/guide/tutorial/Step9/TutorialConfig.h.in b/Help/guide/tutorial/Step9/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Help/guide/tutorial/Step9/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Help/guide/tutorial/Step9/tutorial.cxx b/Help/guide/tutorial/Step9/tutorial.cxx new file mode 100644 index 0000000..3286bc8 --- /dev/null +++ b/Help/guide/tutorial/Step9/tutorial.cxx @@ -0,0 +1,36 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <sstream> +#include <string> + +#include "TutorialConfig.h" + +// should we include the MathFunctions header? +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + // report version + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MINOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + // which square root function should we use? +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst new file mode 100644 index 0000000..db8e7a0 --- /dev/null +++ b/Help/guide/tutorial/index.rst @@ -0,0 +1,758 @@ +CMake Tutorial +************** + +.. only:: html + + .. contents:: + +This tutorial provides a step-by-step guide that covers common build +system issues that CMake helps address. Seeing how various topics all +work together in an example project can be very helpful. This tutorial +can be found in the ``Help/guide/tutorial`` directory of the CMake +source code tree. Each topic has its own subdirectory containing code +that may be used as a starting point for that step. The tutorial +examples are progressive so that each step provides the complete +solution for the previous step. + +A Basic Starting Point (Step 1) +=============================== + +The most basic project is an executable built from source code files. +For simple projects, a two line CMakeLists file is all that is required. +This will be the starting point for our tutorial. The CMakeLists file +looks like: + +.. literalinclude:: Step1/CMakeLists.txt + :language: cmake + +Note that this example uses lower case commands in the CMakeLists file. +Upper, lower, and mixed case commands are supported by CMake. The source +code for ``tutorial.cxx`` will compute the square root of a number and +the first version of it is very simple, as follows: + +.. literalinclude:: Step1/tutorial.cxx + :language: c++ + +Adding a Version Number and Configured Header File +-------------------------------------------------- + +The first feature we will add is to provide our executable and project with a +version number. While we could do this exclusively in the source code, using +CMakeLists provides more flexibility. + +To add a version number we modify the CMakeLists file as follows: + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :start-after: # set the version number + :end-before: # configure a header file + +Since the configured file will be written into the binary tree, we +must add that directory to the list of paths to search for include +files. + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :start-after: # so that we will find TutorialConfig.h + +We then create a ``TutorialConfig.h.in`` file in the source tree with the +following contents: + +.. literalinclude:: Step1/TutorialConfig.h.in + :language: cmake + +When CMake configures this header file the values for +``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be +replaced by the values from the CMakeLists file. Next we modify +``tutorial.cxx`` to include the configured header file and to make use of the +version numbers. The updated source code is listed below. + +.. literalinclude:: Step2/tutorial.cxx + :language: c++ + :start-after: // report version + :end-before: return 1; + +The main changes are the inclusion of the ``TutorialConfig.h`` header +file and printing out a version number as part of the usage message. + +Specify the C++ Standard +------------------------- + +Next let's add some C++11 features to our project. We will need to explicitly +state in the CMake code that it should use the correct flags. The easiest way +to enable C++11 support for CMake is by using the ``CMAKE_CXX_STANDARD`` +variable. + +First, replace ``atof`` with ``std::stod`` in ``tutorial.cxx``. + +Then, set the ``CMAKE_CXX_STANDARD`` variable in the CMakeLists file. + +Which variable can we set in the CMakeLists file to treat the +``CMAKE_CXX_STANDARD`` value as a requirement? + +Build and Test +-------------- + +Run **cmake** or **cmake-gui** to configure the project and then build it +with your chosen build tool. + +cd to the directory where Tutorial was built (likely the make directory or +a Debug or Release build configuration subdirectory) and run these commands: + +.. code-block:: console + + Tutorial 4294967296 + Tutorial 10 + Tutorial + +Adding a Library (Step 2) +========================= + +Now we will add a library to our project. This library will contain our own +implementation for computing the square root of a number. The executable can +then use this library instead of the standard square root function provided by +the compiler. + +For this tutorial we will put the library into a subdirectory +called MathFunctions. It will have the following one line CMakeLists file: + +.. literalinclude:: Step2/MathFunctions/CMakeLists.txt + :language: cmake + +The source file ``mysqrt.cxx`` has one function called ``mysqrt`` that +provides similar functionality to the compiler’s ``sqrt`` function. To make use +of the new library we add an ``add_subdirectory`` call in the top-level +CMakeLists file so that the library will get built. We add the new library to +the executable, and add MathFunctions as an include directory so that the +``mqsqrt.h`` header file can be found. The last few lines of the top-level +CMakeLists file now look like: + +.. code-block:: cmake + + # add the MathFunctions library + add_subdirectory(MathFunctions) + + # add the executable + add_executable(Tutorial tutorial.cxx) + + target_link_libraries(Tutorial MathFunctions) + + # add the binary tree to the search path for include files + # so that we will find TutorialConfig.h + target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/MathFunctions" + ) + +Now let us make the MathFunctions library optional. While for the tutorial +there really isn’t any need to do so, for larger projects this is a common +occurrence. The first step is to add an option to the top-level CMakeLists +file. + +.. literalinclude:: Step3/CMakeLists.txt + :language: cmake + :start-after: # should we use our own math functions + :end-before: # set the version number + +This will show up in the CMake GUI and ccmake with a default value of ON +that can be changed by the user. This setting will be stored in the cache so +that the user does not need to set the value each time they run CMake on this +build directory. + +The next change is to make building and linking the MathFunctions library +conditional. To do this we change the end of the top-level CMakeLists file to +look like the following: + +.. literalinclude:: Step3/CMakeLists.txt + :language: cmake + :start-after: # add the MathFunctions library? + +Note the use of the variables ``EXTRA_LIBS`` and ``EXTRA_INCLUDES`` to collect +up any optional libraries to later be linked into the executable. This is a +classic approach when dealing with many optional components, we will cover the +modern approach in the next step. + +The corresponding changes to the source code are fairly straightforward. First, +include the MathFunctions header if we need it: + +.. literalinclude:: Step3/tutorial.cxx + :language: c++ + :start-after: // should we include the MathFunctions header + :end-before: int main + +Then make which square root function is used dependent on ``USE_MYMATH``: + +.. literalinclude:: Step3/tutorial.cxx + :language: c++ + :start-after: // which square root function should we use? + :end-before: std::cout << "The square root of + +Since the source code now requires ``USE_MYMATH`` we can add it to +``TutorialConfig.h.in`` with the following line: + +.. literalinclude:: Step3/TutorialConfig.h.in + :language: c + :lines: 4 + +Run **cmake** or **cmake-gui** to configure the project and then build it +with your chosen build tool. Then run the built Tutorial executable. + +Which function gives better results, Step1’s sqrt or Step2’s mysqrt? + +Adding Usage Requirements for Library (Step 3) +============================================== + +Usage requirements allow for far better control over a library or executable's +link and include line while also giving more control over the transitive +property of targets inside CMake. The primary commands that leverage usage +requirements are: + + - ``target_compile_definitions`` + - ``target_compile_options`` + - ``target_include_directories`` + - ``target_link_libraries`` + +First up is MathFunctions. We first state that anybody linking to MathFunctions +needs to include the current source directory, while MathFunctions itself +doesn't. So this can become an ``INTERFACE`` usage requirement. + +Remember ``INTERFACE`` means things that consumers require but the producer +doesn't. Update ``MathFunctions/CMakeLists.txt`` with: + +.. literalinclude:: Step4/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # to find MathFunctions.h + +Now that we've specified usage requirements for MathFunctions we can safely +remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level +CMakeLists. + +Once this is done, run **cmake** or **cmake-gui** to configure the project +and then build it with your chosen build tool. + +Installing and Testing (Step 4) +=============================== + +Now we can start adding install rules and testing support to our project. + +Install Rules +------------- + +The install rules are fairly simple for MathFunctions we want to install the +library and header file and for the application we want to install the +executable and configured header. + +So to ``MathFunctions/CMakeLists.txt`` we add: + +.. literalinclude:: Step5/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # install rules + +And the to top-level ``CMakeLists.txt`` we add: + +.. literalinclude:: Step5/CMakeLists.txt + :language: cmake + :start-after: # add the install targets + :end-before: # enable testing + +That is all that is needed to create a basic local install of the tutorial. + +Run **cmake** or **cmake-gui** to configure the project and then build it +with your chosen build tool. Build the ``install`` target by typing +``make install`` from the command line or build the ``INSTALL`` target from +an IDE. This will install the appropriate header files, libraries, and +executables. + +Verify that the installed Tutorial runs. Note: The CMake variable +``CMAKE_INSTALL_PREFIX`` is used to determine the root of where the files will +be installed. + +Testing Support +--------------- + +Next let's test our application. At the end of the top-level CMakeLists file we +can add a number of basic tests to verify that the application is +working correctly. + +.. literalinclude:: Step5/CMakeLists.txt + :language: cmake + :start-after: # enable testing + +The first test simply verifies that the application runs, does not segfault or +otherwise crash, and has a zero return value. This is the basic form of a CTest +test. + +The next test makes use of the ``PASS_REGULAR_EXPRESSION`` test property to +verify that the output of the test contains certain strings, in this case: +verifying that the the usage message is printed when an incorrect number of +arguments are provided. + +Lastly, we have a function called ``do_test`` that runs the application and +verifies that the computed square root is correct for given input. For each +invocation of ``do_test``, another test is added to the project with a name, +input, and expected results based on the passed arguments. + +Rebuild the application and then cd to the binary directory and run +``ctest -N`` and ``ctest -VV``. + +Adding System Introspection (Step 5) +==================================== + +Let us consider adding some code to our project that depends on features the +target platform may not have. For this example, we will add some code that +depends on whether or not the target platform has the ``log`` and ``exp`` +functions. Of course almost every platform has these functions but for this +tutorial assume that they are not common. + +If the platform has ``log`` and ``exp`` then we will use them to compute the +square root in the ``mysqrt`` function. We first test for the availability of +these functions using the ``CheckSymbolExists.cmake`` macro in the top-level +CMakeLists file as follows: + +.. literalinclude:: Step6/CMakeLists.txt + :language: cmake + :start-after: # does this system provide the log and exp functions? + :end-before: # should we use our own math functions + +Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them +from ``mysqrt.cxx``: + +.. literalinclude:: Step6/TutorialConfig.h.in + :language: c + :start-after: // does the platform provide exp and log functions? + +Finally, in the ``mysqrt`` function we can provide an alternate implementation +based on ``log`` and ``exp`` if they are available on the system using the +following code: + +.. literalinclude:: Step6/MathFunctions/mysqrt.cxx + :language: c++ + :start-after: // if we have both log and exp then use them + :end-before: #else + +Run **cmake** or **cmake-gui** to configure the project and then build it +with your chosen build tool. + +You will notice that even though ``HAVE_LOG`` and ``HAVE_EXP`` are both +defined ``mysqrt`` isn't using them. We should realize quickly that we have +forgotten to include ``TutorialConfig.h`` in ``mysqrt.cxx``. + +After making this update, go ahead and build the project again. + +Run the built Tutorial executable. Which function gives better results now, +Step1’s sqrt or Step5’s mysqrt? + +**Exercise**: Why is it important that we configure ``TutorialConfig.h.in`` +after the checks for ``HAVE_LOG`` and ``HAVE_EXP``? What would happen if we +inverted the two? + +**Exercise**: Is there a better place for us to save the ``HAVE_LOG`` and +``HAVE_EXP`` values other than in ``TutorialConfig.h``? + +Adding a Custom Command and Generated File (Step 6) +=================================================== + +In this section, we will add a generated source file into the build process +of an application. For this example, we will create a table of precomputed +square roots as part of the build process, and then compile that +table into our application. + +To accomplish this, we first need a program that will generate the table. In +the MathFunctions subdirectory a new source file named ``MakeTable.cxx`` will +do just that. + +.. literalinclude:: Step7/MathFunctions/MakeTable.cxx + :language: c++ + +Note that the table is produced as valid C++ code and that the output filename +is passed in as an argument. + +The next step is to add the appropriate commands to MathFunctions' CMakeLists +file to build the MakeTable executable and then run it as part of the build +process. A few commands are needed to accomplish this. + +First, the executable for ``MakeTable`` is added as any other executable would +be added. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # first we add the executable that generates the table + :end-before: # add the command to generate the source code + +Then we add a custom command that specifies how to produce ``Table.h`` +by running MakeTable. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add the command to generate the source code + :end-before: # add the main library + +Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated +file ``Table.h``. This is done by adding the generated ``Table.h`` to the list +of sources for the library MathFunctions. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add the main library + :end-before: # state that anybody linking + +We also have to add the current binary directory to the list of include +directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :start-after: # state that we depend on our bin + :end-before: # install rules + +Now let's use the generated table. First, modify ``mysqrt.cxx`` to include +``Table.h``. Next, we can rewrite the mysqrt function to use the table: + +.. literalinclude:: Step7/MathFunctions/mysqrt.cxx + :language: c++ + :start-after: // a hack square root calculation using simple operations + +Run **cmake** or **cmake-gui** to configure the project and then build it +with your chosen build tool. When this project is built it will first build +the ``MakeTable`` executable. It will then run ``MakeTable`` to produce +``Table.h``. Finally, it will compile ``mysqrt.cxx`` which includes +``Table.h`` to produce the MathFunctions library. + +Building an Installer (Step 7) +============================== + +Next suppose that we want to distribute our project to other people so that +they can use it. We want to provide both binary and source distributions on a +variety of platforms. This is a little different from the install we did +previously in `Installing and Testing (Step 4)`_ , where we were +installing the binaries that we had built from the source code. In this +example we will be building installation packages that support binary +installations and package management features. To accomplish this we will use +CPack to create platform specific installers. Specifically we need to add +a few lines to the bottom of our top-level ``CMakeLists.txt`` file. + +.. literalinclude:: Step8/CMakeLists.txt + :language: cmake + :start-after: # setup installer + +That is all there is to it. We start by including +``InstallRequiredSystemLibraries``. This module will include any runtime +libraries that are needed by the project for the current platform. Next we +set some CPack variables to where we have stored the license and version +information for this project. The version information makes use of the +variables we set earlier in this tutorial. Finally we include the CPack +module which will use these variables and some other properties of the system +you are on to setup an installer. + +The next step is to build the project in the usual manner and then run +CPack on it. To build a binary distribution you would run: + +.. code-block:: console + + cpack + +To create a source distribution you would type: + +.. code-block:: console + + cpack -C CPackSourceConfig.cmake + +Alternatively, run ``make package`` or right click the ``Package`` target and +``Build Project`` from an IDE. + +Run the installer executable found in the binary directory. Then run the +installed executable and verify that it works. + +Adding Support for a Dashboard (Step 8) +======================================= + +Adding support for submitting our test results to a dashboard is very easy. We +already defined a number of tests for our project in the earlier steps of this +tutorial. We just have to run those tests and submit them to a dashboard. To +include support for dashboards we include the CTest module in our top-level +``CMakeLists.txt``. + +Replace: + +.. code-block:: cmake + + # enable testing + enable_testing() + +With: + +.. code-block:: cmake + + # enable dashboard scripting + include(CTest) + +The CTest module will automatically call ``enable_testing()``, so +we can remove it from our CMake files. + +We will also need to create a ``CTestConfig.cmake`` file where we can specify +the name of the project and where to submit the dashboard. + +.. literalinclude:: Step9/CTestConfig.cmake + :language: cmake + +CTest will read in this file when it runs. To create a simple dashboard you can +run **cmake** or **cmake-gui** to configure the project, but do not build it +yet. Instead, change directory to the binary tree, and then run: + +.. code-block:: console + + 'ctest [-VV] –D Experimental' + +On Windows, build the EXPERIMENTAL target. + +Ctest will build and test the project and submit the results to the Kitware +public dashboard. The results of your dashboard will be uploaded to Kitware's +public dashboard here: https://my.cdash.org/index.php?project=CMakeTutorial. + +Mixing Static and Shared (Step 9) +================================= + +In this section we will show how by using the ``BUILD_SHARED_LIBS`` variable +we can control the default behavior of ``add_library``, and allow control +over how libraries without an explicit type (STATIC/SHARED/MODULE/OBJECT) are +built. + +To accomplish this we need to add ``BUILD_SHARED_LIBS`` to the top-level +``CMakeLists.txt``. We use the ``option`` command as it allows users to +optionally select if the value should be On or Off. + +Next we are going to refactor MathFunctions to become a real library that +encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling +code to do this logic. This will also mean that ``USE_MYMATH`` will not control +building MathFuctions, but instead will control the behavior of this library. + +The first step is to update the starting section of the top-level +``CMakeLists.txt`` to look like: + +.. literalinclude:: Step10/CMakeLists.txt + :language: cmake + :start-after: set(Tutorial_VERSION_MINOR + :end-before: # add the binary tree + +Now that we have made MathFunctions always be used, we will need to update +the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to +create a SqrtLibrary that will conditionally be built when ``USE_MYMATH`` is +enabled. Now, since this is a tutorial, we are going to explicitly require +that SqrtLibrary is built statically. + +The end result is that ``MathFunctions/CMakeLists.txt`` should look like: + +.. literalinclude:: Step10/MathFunctions/CMakeLists.txt + :language: cmake + :lines: 1-40,46- + +Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and +``detail`` namespaces: + +.. literalinclude:: Step10/MathFunctions/mysqrt.cxx + :language: c++ + +We also need to make some changes in ``tutorial.cxx``, so that it no longer +uses ``USE_MYMATH``: + +#. Always include ``MathFunctions.h`` +#. Always use ``mathfunctions::sqrt`` + +Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: + +.. literalinclude:: Step10/MathFunctions/MathFunctions.h + :language: c++ + +At this point, if you build everything, you will notice that linking fails +as we are combining a static library without position enabled code with a +library that has position enabled code. The solution to this is to explicitly +set the ``POSITION_INDEPENDENT_CODE`` target property of SqrtLibrary to be +True no matter the build type. + +**Exercise**: We modified ``MathFunctions.h`` to use dll export defines. +Using CMake documentation can you find a helper module to simplify this? + +Adding Generator Expressions (Step 10) +====================================== + +Generator expressions are evaluated during build system generation to produce +information specific to each build configuration. + +Generator expressions are allowed in the context of many target properties, +such as ``LINK_LIBRARIES``, ``INCLUDE_DIRECTORIES``, ``COMPILE_DEFINITIONS`` +and others. They may also be used when using commands to populate those +properties, such as ``target_link_libraries()``, +``target_include_directories()``, +``target_compile_definitions()`` and others. + +Generator expressions may be used to enable conditional linking, conditional +definitions used when compiling, conditional include directories and more. +The conditions may be based on the build configuration, target properties, +platform information or any other queryable information. + +There are different types of generator expressions including Logical, +Informational, and Output expressions. + +Logical expressions are used to create conditional output. The basic +expressions are the 0 and 1 expressions. A ``$<0:...>`` results in the empty +string, and ``<1:...>`` results in the content of "...". They can also be +nested. + +For example: + +.. code-block:: cmake + + if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(SqrtLibrary + PRIVATE "HAVE_LOG" "HAVE_EXP") + endif() + +Can be rewritten with generator expressions: + +.. code-block:: cmake + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + +Note that ``${HAVE_LOG}`` is evaluated at CMake configure time while +``$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>`` is evaluated at build system generation +time. + +Adding Export Configuration (Step 11) +===================================== + +During `Installing and Testing (Step 4)`_ of the tutorial we added the ability +for CMake to install the library and headers of the project. During +`Building an Installer (Step 7)`_ we added the ability to package up this +information so it could be distributed to other people. + +The next step is to add the necessary information so that other CMake projects +can use our project, be it from a build directory, a local install or when +packaged. + +The first step is to update our ``install(TARGETS)`` commands to not only +specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword +generates and installs a CMake file containing code to import all targets +listed in the install command from the installation tree. So let's go ahead +and explicitly ``EXPORT`` the MathFunctions library by updating the +``install`` command in ``MathFunctions/CMakeLists.txt`` to look like: + +.. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # install rules + +Now that we have MathFunctions being exported, we also need to explicitly +install the generated ``MathFunctionsTargets.cmake`` file. This is done by +adding the following to the bottom of the top-level ``CMakeLists.txt``: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: # install the configuration targets + :end-before: include(CMakePackageConfigHelpers) + +At this point you should try and run CMake. If everything is setup properly +you will see that CMake will generate an error that looks like: + +.. code-block:: console + + Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains + path: + + "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions" + + which is prefixed in the source directory. + +What CMake is trying to say is that during generating the export information +it will export a path that is intrinsically tied to the current machine and +will not be valid on other machines. The solution to this is to update the +MathFunctions ``target_include_directories`` to understand that it needs +different ``INTERFACE`` locations when being used from within the build +directory and from an install / package. This means converting the +``target_include_directories`` call for MathFunctions to look like: + +.. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # to find MathFunctions.h, while we don't. + :end-before: # should we use our own math functions + +Once this has been updated, we can re-run CMake and see verify that it doesn't +warn anymore. + +At this point, we have CMake properly packaging the target information that is +required but we will still need to generate a ``MathFunctionsConfig.cmake`` so +that the CMake ``find_package command`` can find our project. So let's go +ahead and add a new file to the top-level of the project called +``Config.cmake.in`` with the following contents: + +.. literalinclude:: Complete/Config.cmake.in + +Then, to properly configure and install that file, add the following to the +bottom of the top-level CMakeLists: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: # install the configuration targets + :end-before: # generate the export + +At this point, we have generated a relocatable CMake Configuration for our +project that can be used after the project has been installed or packaged. If +we want our project to also be used from a build directory we only have to add +the following to the bottom of the top level CMakeLists: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: # needs to be after the install(TARGETS ) command + +With this export call we now generate a ``Targets.cmake``, allowing the +configured ``MathFunctionsConfig.cmake`` in the build directory to be used by +other projects, without needing it to be installed. + +Import a CMake Project (Consumer) +================================= + +This examples shows how a project can find other CMake packages that +generate ``Config.cmake`` files. + +It also shows how to state a project's external dependencies when generating +a ``Config.cmake``. + +Packaging Debug and Release (MultiPackage) +========================================== + +By default CMake is model is that a build directory only contains a single +configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. + +But it is possible to setup CPack to bundle multiple build directories at the +same time to build a package that contains multiple configurations of the +same project. + +First we need to ahead and construct a directory called ``multi_config`` this +will contain all the builds that we want to package together. + +Second create a ``debug`` and ``release`` directory underneath +``multi_config``. At the end you should have a layout that looks like: + +─ multi_config + ├── debug + └── release + +Now we need to setup debug and release builds, which would roughly entail +the following: + +.. code-block:: console + + cd debug + cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/ + cmake --build . + cd ../release + cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/ + cmake --build . + cd .. + + +Now that both the debug and release builds are complete we can now use +the custom MultiCPackConfig to package both builds into a single release. + +.. code-block:: console + + cpack --config ../../MultiPackage/MultiCPackConfig.cmake diff --git a/Help/index.rst b/Help/index.rst index a948939..cf1d2f1 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -44,6 +44,14 @@ Reference Manuals /manual/cmake-variables.7 /manual/cpack-generators.7 +Guides +###### + +.. toctree:: + :maxdepth: 1 + + /guide/tutorial/index + .. only:: html or text Release Notes diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index 8cd6e68..d8142a2 100644 --- a/Help/manual/cmake-buildsystem.7.rst +++ b/Help/manual/cmake-buildsystem.7.rst @@ -811,6 +811,10 @@ An *archive* output artifact of a buildsystem target may be: executable target created by the :command:`add_executable` command when its :prop_tgt:`ENABLE_EXPORTS` target property is set. +* On AIX: the linker import file (e.g. ``.imp``) of an executable target + created by the :command:`add_executable` command when its + :prop_tgt:`ENABLE_EXPORTS` target property is set. + The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY` and :prop_tgt:`ARCHIVE_OUTPUT_NAME` target properties may be used to control archive output artifact locations and names in the build tree. diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst index f5aa42d..4b2934a 100644 --- a/Help/manual/cmake-packages.7.rst +++ b/Help/manual/cmake-packages.7.rst @@ -654,8 +654,13 @@ allows one to disable them using the following variables: :command:`export(PACKAGE)` populates the user package registry unless the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable explicitly disables it. -* :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the - User Package Registry in all the :command:`find_package` calls. +* :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` disables the + User Package Registry in all the :command:`find_package` calls when + set to ``FALSE``. +* Deprecated :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the + User Package Registry in all the :command:`find_package` calls when set + to ``TRUE``. This variable is ignored when + :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` has been set. * :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` disables the System Package Registry in all the :command:`find_package` calls. diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 1d023cb..6bdabaf 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -51,6 +51,15 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used to determine whether to report an error on use of deprecated macros or functions. +Policies Introduced by CMake 3.16 +================================= + +.. toctree:: + :maxdepth: 1 + + CMP0096: project() preserves leading zeros in version components. </policy/CMP0096> + CMP0095: RPATH entries are properly escaped in the intermediary CMake install script. </policy/CMP0095> + Policies Introduced by CMake 3.15 ================================= diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 77b1ae8..0beca82 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -331,6 +331,7 @@ Properties on Targets /prop_tgt/VS_DOTNET_REFERENCES /prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL /prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION + /prop_tgt/VS_DPI_AWARE /prop_tgt/VS_GLOBAL_KEYWORD /prop_tgt/VS_GLOBAL_PROJECT_TYPES /prop_tgt/VS_GLOBAL_ROOTNAMESPACE diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 75ddd5d..e0ce6f7 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -98,6 +98,7 @@ Variables that Provide Information /variable/CMAKE_STATIC_LIBRARY_PREFIX /variable/CMAKE_STATIC_LIBRARY_SUFFIX /variable/CMAKE_Swift_MODULE_DIRECTORY + /variable/CMAKE_Swift_NUM_THREADS /variable/CMAKE_TOOLCHAIN_FILE /variable/CMAKE_TWEAK_VERSION /variable/CMAKE_VERBOSE_MAKEFILE @@ -157,6 +158,7 @@ Variables that Change Behavior /variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES /variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT /variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS + /variable/CMAKE_ECLIPSE_RESOURCE_ENCODING /variable/CMAKE_ECLIPSE_VERSION /variable/CMAKE_ERROR_DEPRECATED /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION @@ -180,6 +182,12 @@ Variables that Change Behavior /variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY /variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE /variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM + /variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH + /variable/CMAKE_FIND_USE_CMAKE_PATH + /variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH + /variable/CMAKE_FIND_USE_PACKAGE_REGISTRY + /variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH + /variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH /variable/CMAKE_FRAMEWORK_PATH /variable/CMAKE_IGNORE_PATH /variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 7b5399d..68d88e7 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -604,6 +604,12 @@ Available commands are: .. note:: Path to where ``<new>`` symbolic link will be created has to exist beforehand. +``true`` + Do nothing, with an exit code of 0. + +``false`` + Do nothing, with an exit code of 1. + Windows-specific Command-Line Tools ----------------------------------- diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 5773176..c6b1425 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -443,7 +443,8 @@ this mode include: Specify the name of the project to build. ``--build-makeprogram`` - Override the make program chosen by CTest with a given one. + Specify the explicit make program to be used by CMake when configuring and + building the project. Only applicable for Make and Ninja based generators. ``--build-noclean`` Skip the make clean step. diff --git a/Help/policy/CMP0095.rst b/Help/policy/CMP0095.rst new file mode 100644 index 0000000..4c56a05 --- /dev/null +++ b/Help/policy/CMP0095.rst @@ -0,0 +1,30 @@ +CMP0095 +------- + +``RPATH`` entries are properly escaped in the intermediary CMake install script. + +In CMake 3.15 and earlier, ``RPATH`` entries set via +:variable:`CMAKE_INSTALL_RPATH` or via :prop_tgt:`INSTALL_RPATH` have not been +escaped before being inserted into the ``cmake_install.cmake`` script. Dynamic +linkers on ELF-based systems (e.g. Linux and FreeBSD) allow certain keywords in +``RPATH`` entries, such as ``${ORIGIN}`` (More details are available in the +``ld.so`` man pages on those systems). The syntax of these keywords can match +CMake's variable syntax. In order to not be substituted (usually to an empty +string) already by the intermediary ``cmake_install.cmake`` script, the user had +to double-escape such ``RPATH`` keywords, e.g. +``set(CMAKE_INSTALL_RPATH "\\\${ORIGIN}/../lib")``. Since the intermediary +``cmake_install.cmake`` script is an implementation detail of CMake, CMake 3.16 +and later will make sure ``RPATH`` entries are inserted literally by escaping +any coincidental CMake syntax. + +The ``OLD`` behavior of this policy is to not escape ``RPATH`` entries in the +intermediary ``cmake_install.cmake`` script. The ``NEW`` behavior is to properly +escape coincidental CMake syntax in ``RPATH`` entries when generating the +intermediary ``cmake_install.cmake`` script. + +This policy was introduced in CMake version 3.16. CMake version |release| warns +when the policy is not set and detected usage of CMake-like syntax and uses +``OLD`` behavior. Use the :command:`cmake_policy` command to set it to ``OLD`` +or ``NEW`` explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/policy/CMP0096.rst b/Help/policy/CMP0096.rst new file mode 100644 index 0000000..8eaf0f9 --- /dev/null +++ b/Help/policy/CMP0096.rst @@ -0,0 +1,25 @@ +CMP0096 +------- + +The :command:`project` command preserves leading zeros in version components. + +When a ``VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]`` argument is given +to the :command:`project` command, it stores the version string in the +``PROJECT_VERSION`` variable and stores individual integer version components +in ``PROJECT_VERSION_{MAJOR,MINOR,PATCH,TWEAK}`` variables (see policy +:policy:`CMP0048`). CMake 3.15 and below dropped leading zeros from each +component. CMake 3.16 and higher prefer to preserve leading zeros. This +policy provides compatibility for projects that have not been updated to +expect the new behavior. + +The ``OLD`` behavior of this policy drops leading zeros in all components, +e.g. such that version ``1.07.06`` becomes ``1.7.6``. The ``NEW`` behavior +of this policy preserves the leading zeros in all components, such that +version ``1.07.06`` remains unchanged. + +This policy was introduced in CMake version 3.16. Unlike many policies, CMake +version |release| does *not* warn when this policy is not set and simply uses +the ``OLD`` behavior. Use the :command:`cmake_policy` command to set it to +``OLD`` or ``NEW`` explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_test/SKIP_RETURN_CODE.rst b/Help/prop_test/SKIP_RETURN_CODE.rst index a05fbf3..3d48c2f 100644 --- a/Help/prop_test/SKIP_RETURN_CODE.rst +++ b/Help/prop_test/SKIP_RETURN_CODE.rst @@ -6,4 +6,5 @@ Return code to mark a test as skipped. Sometimes only a test itself can determine if all requirements for the test are met. If such a situation should not be considered a hard failure a return code of the process can be specified that will mark the test as -``Not Run`` if it is encountered. +``Not Run`` if it is encountered. Valid values are in the range of +0 to 255, inclusive. diff --git a/Help/prop_tgt/BUILD_RPATH.rst b/Help/prop_tgt/BUILD_RPATH.rst index 13c9c1d..d978b94 100644 --- a/Help/prop_tgt/BUILD_RPATH.rst +++ b/Help/prop_tgt/BUILD_RPATH.rst @@ -8,3 +8,6 @@ tree. See also the :prop_tgt:`INSTALL_RPATH` target property. This property is initialized by the value of the variable :variable:`CMAKE_BUILD_RPATH` if it is set when a target is created. + +This property supports +:manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/prop_tgt/ENABLE_EXPORTS.rst b/Help/prop_tgt/ENABLE_EXPORTS.rst index 581c2b9..0b1064a 100644 --- a/Help/prop_tgt/ENABLE_EXPORTS.rst +++ b/Help/prop_tgt/ENABLE_EXPORTS.rst @@ -7,16 +7,25 @@ Normally an executable does not export any symbols because it is the final program. It is possible for an executable to export symbols to be used by loadable modules. When this property is set to true CMake will allow other targets to "link" to the executable with the -:command:`TARGET_LINK_LIBRARIES` command. On all platforms a target-level +:command:`target_link_libraries` command. On all platforms a target-level dependency on the executable is created for targets that link to it. -For DLL platforms an import library will be created for the exported -symbols and then used for linking. All Windows-based systems -including Cygwin are DLL platforms. For non-DLL platforms that -require all symbols to be resolved at link time, such as macOS, the -module will "link" to the executable using a flag like -``-bundle_loader``. For other non-DLL platforms the link rule is simply -ignored since the dynamic loader will automatically bind symbols when -the module is loaded. +Handling of the executable on the link lines of the loadable modules +varies by platform: + +* On Windows-based systems (including Cygwin) an "import library" is + created along with the executable to list the exported symbols. + Loadable modules link to the import library to get the symbols. + +* On macOS, loadable modules link to the executable itself using the + ``-bundle_loader`` flag. + +* On AIX, a linker "import file" is created along with the executable + to list the exported symbols for import when linking other targets. + Loadable modules link to the import file to get the symbols. + +* On other platforms, loadable modules are simply linked without + referencing the executable since the dynamic loader will + automatically bind symbols when the module is loaded. This property is initialized by the value of the variable :variable:`CMAKE_ENABLE_EXPORTS` if it is set when a target is created. diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst index 77fb552..c8b6fde 100644 --- a/Help/prop_tgt/IMPORTED_IMPLIB.rst +++ b/Help/prop_tgt/IMPORTED_IMPLIB.rst @@ -3,5 +3,7 @@ IMPORTED_IMPLIB Full path to the import library for an ``IMPORTED`` target. -Set this to the location of the ``.lib`` part of a Windows DLL. Ignored -for non-imported targets. +Set this to the location of the ``.lib`` part of a Windows DLL, or on +AIX set it to an import file created for executables that export symbols +(see the :prop_tgt:`ENABLE_EXPORTS` target property). +Ignored for non-imported targets. diff --git a/Help/prop_tgt/INSTALL_RPATH.rst b/Help/prop_tgt/INSTALL_RPATH.rst index 6403f4c..93b4488 100644 --- a/Help/prop_tgt/INSTALL_RPATH.rst +++ b/Help/prop_tgt/INSTALL_RPATH.rst @@ -7,3 +7,6 @@ A semicolon-separated list specifying the rpath to use in installed targets (for platforms that support it). This property is initialized by the value of the variable :variable:`CMAKE_INSTALL_RPATH` if it is set when a target is created. + +This property supports +:manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/prop_tgt/VS_DPI_AWARE.rst b/Help/prop_tgt/VS_DPI_AWARE.rst new file mode 100644 index 0000000..82640cc --- /dev/null +++ b/Help/prop_tgt/VS_DPI_AWARE.rst @@ -0,0 +1,14 @@ +VS_DPI_AWARE +------------ + +Set the Manifest Tool -> Input and Output -> DPI Awareness in the Visual Studio +target project properties. + +Valid values are ``PerMonitor``, ``ON``, or ``OFF``. + +For example: + +.. code-block:: cmake + + add_executable(myproject myproject.cpp) + set_property(TARGET myproject PROPERTY VS_DPI_AWARE "PerMonitor") diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/CMP0095.rst b/Help/release/dev/CMP0095.rst new file mode 100644 index 0000000..21d0550 --- /dev/null +++ b/Help/release/dev/CMP0095.rst @@ -0,0 +1,5 @@ +CMP0095 +------- + +* ``RPATH`` entries are properly escaped in the intermediary CMake install script. + See policy :policy:`CMP0095`. diff --git a/Help/release/dev/FindPython-FIND_ABI.rst b/Help/release/dev/FindPython-FIND_ABI.rst new file mode 100644 index 0000000..19e3f71 --- /dev/null +++ b/Help/release/dev/FindPython-FIND_ABI.rst @@ -0,0 +1,5 @@ +FindPython-FIND_ABI +------------------- + +* Modules :module:`FindPython3` and :module:`FindPython` gain the capability + to control which ``ABIs`` will be searched. diff --git a/Help/release/dev/add_cmake_find_use_package_registry.rst b/Help/release/dev/add_cmake_find_use_package_registry.rst new file mode 100644 index 0000000..1b02bad --- /dev/null +++ b/Help/release/dev/add_cmake_find_use_package_registry.rst @@ -0,0 +1,11 @@ +add_cmake_find_use_package_registry +----------------------------------- + +* The :command:`find_package` command has learned to check the following + variables to control searching + + * :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` - Controls the searching the + cmake user registry. + +* The :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` has been deprecated. + Instead use :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` diff --git a/Help/release/dev/add_test-expand_lists.rst b/Help/release/dev/add_test-expand_lists.rst new file mode 100644 index 0000000..88d26b7 --- /dev/null +++ b/Help/release/dev/add_test-expand_lists.rst @@ -0,0 +1,6 @@ +add_test-expand_lists +--------------------- + +* The command :command:`add_test` learned the option ``COMMAND_EXPAND_LISTS`` + which causes lists in the ``COMMAND`` argument to be expanded, including + lists created by generator expressions. diff --git a/Help/release/dev/aix.rst b/Help/release/dev/aix.rst new file mode 100644 index 0000000..6919358 --- /dev/null +++ b/Help/release/dev/aix.rst @@ -0,0 +1,20 @@ +aix +--- + +* On AIX, executables using the :prop_tgt:`ENABLE_EXPORTS` target property + now produce a linker import file with a ``.imp`` extension in addition + to the executable file. Plugins (created via :command:`add_library` with + the ``MODULE`` option) that use :command:`target_link_libraries` to link + to the executable for its symbols are now linked using the import file. + The :command:`install(TARGETS)` command now installs the import file as + an ``ARCHIVE`` artifact. + +* On AIX, runtime linking is no longer enabled by default. CMake provides + the linker enough information to resolve all symbols up front. + One may manually enable runtime linking for shared libraries and/or + loadable modules by adding ``-Wl,-G`` to their link flags + (e.g. in the :variable:`CMAKE_SHARED_LINKER_FLAGS` or + :variable:`CMAKE_MODULE_LINKER_FLAGS` variable). + One may manually enable runtime linking for executables by adding + ``-Wl,-brtl`` to their link flags (e.g. in the + :variable:`CMAKE_EXE_LINKER_FLAGS` variable). diff --git a/Help/release/dev/build-install-rpath-genex.rst b/Help/release/dev/build-install-rpath-genex.rst new file mode 100644 index 0000000..644b1b2 --- /dev/null +++ b/Help/release/dev/build-install-rpath-genex.rst @@ -0,0 +1,5 @@ +build-install-rpath-genex +------------------------- + +* :prop_tgt:`BUILD_RPATH` and :prop_tgt:`INSTALL_RPATH` now support + :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/release/dev/cmake-e-true-false.rst b/Help/release/dev/cmake-e-true-false.rst new file mode 100644 index 0000000..173fabd --- /dev/null +++ b/Help/release/dev/cmake-e-true-false.rst @@ -0,0 +1,5 @@ +cmake-e-true-false +------------------ + +* :manual:`cmake(1)` ``-E`` now supports ``true`` and ``false`` commands, which + do nothing while returning exit codes of 0 and 1, respectively. diff --git a/Help/release/dev/cmake-qch-no-version-in-filename.rst b/Help/release/dev/cmake-qch-no-version-in-filename.rst new file mode 100644 index 0000000..3c5cb04 --- /dev/null +++ b/Help/release/dev/cmake-qch-no-version-in-filename.rst @@ -0,0 +1,8 @@ +cmake-qch-no-version-in-filename +-------------------------------- + +* The Qt Compressed Help file is now named ``CMake.qch``, which no longer + contains the release version in the file name. When CMake is upgraded + in-place, the name and location of this file will remain constant. + Tools such as IDEs, help viewers, etc. should now be able to refer to this + file at a fixed location that remains valid across CMake upgrades. diff --git a/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst b/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst new file mode 100644 index 0000000..4465de8 --- /dev/null +++ b/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst @@ -0,0 +1,6 @@ +ctest-build-makeprogram-propagated-configure-pass +------------------------------------------------- + +* :manual:`ctest(1)` ``--build-makeprogram`` now specifies the make program + used when configuring a project with the Ninja and Makefiles generators + in addition to building it. diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst new file mode 100644 index 0000000..440efa9 --- /dev/null +++ b/Help/release/dev/deprecate-policy-old.rst @@ -0,0 +1,8 @@ +deprecate-policy-old +-------------------- + +* An explicit deprecation diagnostic was added for policy ``CMP0067`` + (``CMP0066`` and below were already deprecated). + The :manual:`cmake-policies(7)` manual explains that the OLD behaviors + of all policies are deprecated and that projects should port to the + NEW behaviors. diff --git a/Help/release/dev/eclipse-resource-encoding.rst b/Help/release/dev/eclipse-resource-encoding.rst new file mode 100644 index 0000000..6ceca0c --- /dev/null +++ b/Help/release/dev/eclipse-resource-encoding.rst @@ -0,0 +1,6 @@ +eclipse-resource-encoding +------------------------- + +* The :generator:`Eclipse CDT4` extra generator gained a new + :variable:`CMAKE_ECLIPSE_RESOURCE_ENCODING` option to specify + the resource encoding. diff --git a/Help/release/dev/get-runtime-dependencies.rst b/Help/release/dev/get-runtime-dependencies.rst new file mode 100644 index 0000000..b9dc6e6 --- /dev/null +++ b/Help/release/dev/get-runtime-dependencies.rst @@ -0,0 +1,9 @@ +get-runtime-dependencies +------------------------ + +* The :command:`file` command learned a new sub-command, + ``GET_RUNTIME_DEPENDENCIES``, which allows you to recursively get the list of + libraries linked by an executable or library. This sub-command is intended as + a replacement for :module:`GetPrerequisites`. +* The :module:`GetPrerequisites` module has been deprecated, as it has been + superceded by :command:`file(GET_RUNTIME_DEPENDENCIES)`. diff --git a/Help/release/dev/global-controls-over-find-locations.rst b/Help/release/dev/global-controls-over-find-locations.rst new file mode 100644 index 0000000..79bc869 --- /dev/null +++ b/Help/release/dev/global-controls-over-find-locations.rst @@ -0,0 +1,21 @@ +global-controls-over-find-locations +----------------------------------- + +* The :command:`find_file`, :command:`find_library`, :command:`find_path`, + and :command:`find_program` commands have learned to check the following + variables to control searching + + * :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` - Controls the searching + the cmake-specific environment variables. + + * :variable:`CMAKE_FIND_USE_CMAKE_PATH` - Controls the searching the + cmake-specific cache variables. + + * :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` - Controls the searching + cmake platform specific variables. + + * :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` - Controls the searching of + :variable:`<PackageName>_ROOT` variables. + + * :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH` - Controls the searching + the standard system environment variables. diff --git a/Help/release/dev/project-version-0.rst b/Help/release/dev/project-version-0.rst new file mode 100644 index 0000000..6525522 --- /dev/null +++ b/Help/release/dev/project-version-0.rst @@ -0,0 +1,5 @@ +project-version-0 +----------------- + +* The :command:`project` no longer strips leading zeros in version components. + See policy :policy:`CMP0096`. diff --git a/Help/release/dev/vs-dpi-aware.rst b/Help/release/dev/vs-dpi-aware.rst new file mode 100644 index 0000000..f76f26c --- /dev/null +++ b/Help/release/dev/vs-dpi-aware.rst @@ -0,0 +1,6 @@ +vs-dpi-aware +------------ + +* The :prop_tgt:`VS_DPI_AWARE` target property was added to tell + :ref:`Visual Studio Generators` to set the ``EnableDpiAwareness`` + property in ``.vcxproj`` files. diff --git a/Help/release/index.rst b/Help/release/index.rst index 35a47aa..62032e6 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -7,6 +7,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst index eea2c4f..6d34c5c 100644 --- a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst +++ b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst @@ -4,4 +4,5 @@ CMAKE_CUDA_HOST_COMPILER Executable to use when compiling host code when compiling ``CUDA`` language files. Maps to the ``nvcc -ccbin`` option. Will only be used by CMake on the first configuration to determine a valid host compiler for ``CUDA``. After a valid -host compiler has been found, this value is read-only. +host compiler has been found, this value is read-only. This variable takes +priority over the :envvar:`CUDAHOSTCXX` environment variable. diff --git a/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst new file mode 100644 index 0000000..314efe5 --- /dev/null +++ b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst @@ -0,0 +1,6 @@ +CMAKE_ECLIPSE_RESOURCE_ENCODING +------------------------------- + +This cache variable tells the :generator:`Eclipse CDT4` project generator +to set the resource encoding to the given value in generated project files. +If no value is given, no encoding will be set. diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst index 7ec4d63..8848da1 100644 --- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst +++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst @@ -1,22 +1,8 @@ CMAKE_ENABLE_EXPORTS -------------------- -Specify whether an executable exports symbols for loadable modules. +Specify whether executables export symbols for loadable modules. -Normally an executable does not export any symbols because it is the -final program. It is possible for an executable to export symbols to -be used by loadable modules. When this property is set to true CMake -will allow other targets to ``link`` to the executable with the -:command:`TARGET_LINK_LIBRARIES` command. On all platforms a target-level -dependency on the executable is created for targets that link to it. -For DLL platforms an import library will be created for the exported -symbols and then used for linking. All Windows-based systems -including Cygwin are DLL platforms. For non-DLL platforms that -require all symbols to be resolved at link time, such as macOS, the -module will ``link`` to the executable using a flag like -``-bundle_loader``. For other non-DLL platforms the link rule is simply -ignored since the dynamic loader will automatically bind symbols when -the module is loaded. - -This variable is used to initialize the target property -:prop_tgt:`ENABLE_EXPORTS` for executable targets. +This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target +property for executable targets when they are created by calls to the +:command:`add_executable` command. See the property documentation for details. diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst index 9058471..ffb8a2c 100644 --- a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst +++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst @@ -1,12 +1,23 @@ CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY -------------------------------------- -Skip :ref:`User Package Registry` in :command:`find_package` calls. +.. deprecated:: 3.16 + + Use the :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` variable instead. + +By default this variable is not set. If neither +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` nor +``CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY`` is set, then +:command:`find_package()` will use the `User Package Registry` unless the +`NO_CMAKE_PACKAGE_REGISTRY` option is provided. + +``CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY`` is ignored if +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` is set. In some cases, for example to locate only system wide installations, it is not desirable to use the :ref:`User Package Registry` when searching for packages. If the :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` -variable is enabled, all the :command:`find_package` commands will skip +variable is ``TRUE``, all the :command:`find_package` commands will skip the :ref:`User Package Registry` as if they were called with the ``NO_CMAKE_PACKAGE_REGISTRY`` argument. diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst new file mode 100644 index 0000000..33514a0 --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst @@ -0,0 +1,18 @@ +CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH +------------------------------------- + +Controls the searching the cmake-specific environment variables by the +:command:`find_program`, :command:`find_library`, :command:`find_file`, +and :command:`find_path` commands. +This is useful in cross-compiling environments. + +By default this variable is not set, which is equivalent to it having +a value of ``TRUE``. Explicit options given to the :command:`find_program`, +:command:`find_library`, :command:`find_file`, and :command:`find_path` +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst new file mode 100644 index 0000000..cefc645 --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst @@ -0,0 +1,18 @@ +CMAKE_FIND_USE_CMAKE_PATH +------------------------- + +Controls the searching the cmake-specific cache variables by the +:command:`find_program`, :command:`find_library`, :command:`find_file`, +and :command:`find_path` commands. +This is useful in cross-compiling environments. + +By default this variable is not set, which is equivalent to it having +a value of ``TRUE``. Explicit options given to the :command:`find_program`, +:command:`find_library`, :command:`find_file`, and :command:`find_path` +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst new file mode 100644 index 0000000..2aa544d --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst @@ -0,0 +1,18 @@ +CMAKE_FIND_USE_CMAKE_SYSTEM_PATH +-------------------------------- + +Controls the searching cmake platform specific variables by the +:command:`find_program`, :command:`find_library`, :command:`find_file`, +and :command:`find_path` commands. +This is useful in cross-compiling environments. + +By default this variable is not set, which is equivalent to it having +a value of ``TRUE``. Explicit options given to the :command:`find_program`, +:command:`find_library`, :command:`find_file`, and :command:`find_path` +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst new file mode 100644 index 0000000..75e910f --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst @@ -0,0 +1,29 @@ +CMAKE_FIND_USE_PACKAGE_REGISTRY +------------------------------- + +Controls the searching the :ref:`User Package Registry` by the :command:`find_package` +command. + +By default this variable is not set and the behavior will fall back +to that determined by the deprecated :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` +variable. If that is also not set, then `find_package()` will use the +`User Package Registry` unless the `NO_CMAKE_PACKAGE_REGISTRY` option +is provided. + +This variable takes precedence over :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` +when both are set. + +In some cases, for example to locate only system wide installations, it +is not desirable to use the :ref:`User Package Registry` when searching +for packages. If the :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` +variable is ``FALSE``, all the :command:`find_package` commands will skip +the :ref:`User Package Registry` as if they were called with the +``NO_CMAKE_PACKAGE_REGISTRY`` argument. + +See also :ref:`Disabling the Package Registry`. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst new file mode 100644 index 0000000..899e62e --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst @@ -0,0 +1,18 @@ +CMAKE_FIND_USE_PACKAGE_ROOT_PATH +-------------------------------- + +Controls the searching of :variable:`<PackageName>_ROOT` variables by the +:command:`find_program`, :command:`find_library`, :command:`find_file`, +and :command:`find_path` commands. +This is useful in cross-compiling environments. + +By default this variable is not set, which is equivalent to it having +a value of ``TRUE``. Explicit options given to the :command:`find_program`, +:command:`find_library`, :command:`find_file`, and :command:`find_path` +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`, +and :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` variables. diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst new file mode 100644 index 0000000..604c710 --- /dev/null +++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst @@ -0,0 +1,18 @@ +CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH +-------------------------------------- + +Controls the searching the standard system environment variables by the +:command:`find_program`, :command:`find_library`, :command:`find_file`, +and :command:`find_path` commands. +This is useful in cross-compiling environments. + +By default this variable is not set, which is equivalent to it having +a value of ``TRUE``. Explicit options given to the :command:`find_program`, +:command:`find_library`, :command:`find_file`, and :command:`find_path` +commands take precedence over this variable. + +See also the :variable:`CMAKE_FIND_USE_CMAKE_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`, +:variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`, +:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY`, +and :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` variables. diff --git a/Help/variable/CMAKE_Swift_NUM_THREADS.rst b/Help/variable/CMAKE_Swift_NUM_THREADS.rst new file mode 100644 index 0000000..cb33678 --- /dev/null +++ b/Help/variable/CMAKE_Swift_NUM_THREADS.rst @@ -0,0 +1,8 @@ +CMAKE_Swift_NUM_THREADS +----------------------- + +Number of threads for parallel compilation for Swift targets. + +This variable controls the number of parallel jobs that the swift driver creates +for building targets. If not specified, it will default to the number of +logical CPUs on the host. |