mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 02:39:48 -06:00
Tutorial: Improve "MultiPackage" example
Rename to Step 12 and ensure that it follows Step 11
This commit is contained in:
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.15)
|
||||
# set the project name and version
|
||||
project(Tutorial VERSION 1.0)
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX d)
|
||||
|
||||
add_library(tutorial_compiler_flags INTERFACE)
|
||||
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
|
||||
|
||||
@@ -37,6 +39,8 @@ add_subdirectory(MathFunctions)
|
||||
|
||||
# add the executable
|
||||
add_executable(Tutorial tutorial.cxx)
|
||||
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
target_link_libraries(Tutorial PUBLIC MathFunctions)
|
||||
|
||||
# add the binary tree to the search path for include files
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
include("release/CPackConfig.cmake")
|
||||
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS
|
||||
@@ -1,6 +1,5 @@
|
||||
// A simple program that computes the square root of a number
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "MathFunctions.h"
|
||||
@@ -9,6 +8,7 @@
|
||||
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;
|
||||
@@ -18,8 +18,8 @@ int main(int argc, char* argv[])
|
||||
// convert input to double
|
||||
const double inputValue = std::stod(argv[1]);
|
||||
|
||||
// calculate square root
|
||||
const double outputValue = mathfunctions::sqrt(inputValue);
|
||||
|
||||
std::cout << "The square root of " << inputValue << " is " << outputValue
|
||||
<< std::endl;
|
||||
return 0;
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# set the project name and version
|
||||
project(Tutorial VERSION 1.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
add_library(tutorial_compiler_flags INTERFACE)
|
||||
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
|
||||
|
||||
# add compiler warning flags just when building this project via
|
||||
# the BUILD_INTERFACE genex
|
||||
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
|
||||
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
|
||||
target_compile_options(tutorial_compiler_flags INTERFACE
|
||||
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
|
||||
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
|
||||
)
|
||||
|
||||
# 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
|
||||
7
Help/guide/tutorial/Step12/CTestConfig.cmake
Normal file
7
Help/guide/tutorial/Step12/CTestConfig.cmake
Normal file
@@ -0,0 +1,7 @@
|
||||
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)
|
||||
@@ -17,6 +17,7 @@ if(USE_MYMATH)
|
||||
|
||||
# first we add the executable that generates the table
|
||||
add_executable(MakeTable MakeTable.cxx)
|
||||
target_link_libraries(MakeTable tutorial_compiler_flags)
|
||||
|
||||
# add the command to generate the source code
|
||||
add_custom_command(
|
||||
@@ -41,19 +42,18 @@ if(USE_MYMATH)
|
||||
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
|
||||
)
|
||||
|
||||
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
|
||||
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
|
||||
endif()
|
||||
|
||||
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
|
||||
|
||||
# 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
|
||||
install(TARGETS MathFunctions tutorial_compiler_flags
|
||||
DESTINATION lib
|
||||
EXPORT MathFunctionsTargets)
|
||||
install(FILES MathFunctions.h DESTINATION include)
|
||||
@@ -17,11 +17,10 @@ double mysqrt(double x)
|
||||
// use the table to help find an initial value
|
||||
double result = x;
|
||||
if (x >= 1 && x < 10) {
|
||||
std::cout << "Use the table to help find an initial value " << std::endl;
|
||||
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) {
|
||||
@@ -1,3 +1,3 @@
|
||||
// the configured version number
|
||||
// the configured options and settings for Tutorial
|
||||
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
|
||||
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
|
||||
@@ -8,6 +8,7 @@
|
||||
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;
|
||||
@@ -15,7 +16,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// convert input to double
|
||||
double inputValue = std::stod(argv[1]);
|
||||
const double inputValue = std::stod(argv[1]);
|
||||
|
||||
const double outputValue = mathfunctions::sqrt(inputValue);
|
||||
|
||||
@@ -830,7 +830,7 @@ different ``INTERFACE`` locations when being used from within the build
|
||||
directory and from an install / package. This means converting the
|
||||
:command:`target_include_directories` call for MathFunctions to look like:
|
||||
|
||||
.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
|
||||
.. literalinclude:: Step12/MathFunctions/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: # to find MathFunctions.h, while we don't.
|
||||
:end-before: # should we use our own math functions
|
||||
@@ -844,12 +844,12 @@ that the CMake :command:`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
|
||||
.. literalinclude:: Step12/Config.cmake.in
|
||||
|
||||
Then, to properly configure and install that file, add the following to the
|
||||
bottom of the top-level ``CMakeLists.txt``:
|
||||
|
||||
.. literalinclude:: Complete/CMakeLists.txt
|
||||
.. literalinclude:: Step12/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: # install the configuration targets
|
||||
:end-before: # generate the export
|
||||
@@ -859,7 +859,7 @@ 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.txt``:
|
||||
|
||||
.. literalinclude:: Complete/CMakeLists.txt
|
||||
.. literalinclude:: Step12/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: # needs to be after the install(TARGETS ) command
|
||||
|
||||
@@ -867,55 +867,81 @@ 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)
|
||||
=================================
|
||||
Packaging Debug and Release (Step 12)
|
||||
=====================================
|
||||
|
||||
This example shows how a project can find other CMake packages that
|
||||
generate ``Config.cmake`` files.
|
||||
**Note:** This example is valid for single-configuration generators and will
|
||||
not work for multi-configuration generators (e.g. Visual Studio).
|
||||
|
||||
It also shows how to state a project's external dependencies when generating
|
||||
a ``Config.cmake``.
|
||||
By default, CMake's model is that a build directory only contains a single
|
||||
configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is
|
||||
possible, however, to setup CPack to bundle multiple build directories and
|
||||
construct a package that contains multiple configurations of the same project.
|
||||
|
||||
Packaging Debug and Release (MultiPackage)
|
||||
==========================================
|
||||
First, we want to ensure that the debug and release builds use different names
|
||||
for the executables and libraries that will be installed. Let's use `d` as the
|
||||
postfix for the debug executable and libraries.
|
||||
|
||||
By default CMake's model is that a build directory only contains a single
|
||||
configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo.
|
||||
Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
|
||||
``CMakeLists.txt`` file:
|
||||
|
||||
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.
|
||||
.. literalinclude:: Complete/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: project(Tutorial VERSION 1.0)
|
||||
:end-before: target_compile_features(tutorial_compiler_flags
|
||||
|
||||
First we need to construct a directory called ``multi_config``, which
|
||||
will contain all the builds that we want to package together.
|
||||
And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:
|
||||
|
||||
Second create a ``debug`` and ``release`` directory underneath
|
||||
``multi_config``. At the end you should have a layout that looks like:
|
||||
.. literalinclude:: Complete/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: # add the executable
|
||||
:end-before: # add the binary tree to the search path for include files
|
||||
|
||||
Let's also add version numbering to the MathFunctions library. In
|
||||
``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and
|
||||
:prop_tgt:`SOVERSION` properties:
|
||||
|
||||
.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
|
||||
:language: cmake
|
||||
:start-after: # setup the version numbering
|
||||
:end-before: # install rules
|
||||
|
||||
From the ``Step12`` directory, create ``debug`` and ``release``
|
||||
subbdirectories. The layout will look like:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
─ multi_config
|
||||
├── debug
|
||||
└── release
|
||||
- Step12
|
||||
└── debug
|
||||
└── release
|
||||
|
||||
Now we need to setup debug and release builds, which would roughly entail
|
||||
the following:
|
||||
Now we need to setup debug and release builds. We can use
|
||||
:variable:`CMAKE_BUILD_TYPE` to set the configuration type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd debug
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
cmake --build .
|
||||
cd ../release
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build .
|
||||
cd ..
|
||||
|
||||
Now that both the debug and release builds are complete, we can use a custom
|
||||
configuration file to package both builds into a single release. In the
|
||||
``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this
|
||||
file, first include the default configuration file that was created by the
|
||||
:manual:`cmake <cmake(1)>` executable.
|
||||
|
||||
Now that both the debug and release builds are complete, we can use
|
||||
a custom ``MultiCPackConfig.cmake`` file to package both builds into a single
|
||||
release.
|
||||
Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
|
||||
projects to install. In this case, we want to install both debug and release.
|
||||
|
||||
.. literalinclude:: Complete/MultiCPackConfig.cmake
|
||||
:language: cmake
|
||||
|
||||
From the ``Step12`` directory, run :manual:`cpack <cpack(1)>` specifying our
|
||||
custom configuration file with the ``config`` option:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cpack --config ../../MultiPackage/MultiCPackConfig.cmake
|
||||
cpack --config MultiCPackConfig.cmake
|
||||
|
||||
@@ -1595,6 +1595,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
set(tutorial_build_options -DUSE_MYMATH:BOOL=OFF)
|
||||
endif()
|
||||
add_test(${tutorial_test_name} ${CMAKE_CTEST_COMMAND}
|
||||
-C "Release"
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Help/guide/tutorial/${step_name}"
|
||||
${tutorial_build_dir}_Build
|
||||
@@ -1606,11 +1607,11 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
endfunction()
|
||||
|
||||
if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
||||
foreach(STP RANGE 2 11)
|
||||
foreach(STP RANGE 2 12)
|
||||
add_tutorial_test(Step${STP} TRUE)
|
||||
endforeach()
|
||||
add_tutorial_test(Complete TRUE)
|
||||
foreach(STP RANGE 3 11)
|
||||
foreach(STP RANGE 3 12)
|
||||
add_tutorial_test(Step${STP} FALSE)
|
||||
endforeach()
|
||||
add_tutorial_test(Complete FALSE)
|
||||
|
||||
Reference in New Issue
Block a user