mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 13:20:47 -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
|
# set the project name and version
|
||||||
project(Tutorial VERSION 1.0)
|
project(Tutorial VERSION 1.0)
|
||||||
|
|
||||||
|
set(CMAKE_DEBUG_POSTFIX d)
|
||||||
|
|
||||||
add_library(tutorial_compiler_flags INTERFACE)
|
add_library(tutorial_compiler_flags INTERFACE)
|
||||||
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
|
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
|
||||||
|
|
||||||
@@ -37,6 +39,8 @@ add_subdirectory(MathFunctions)
|
|||||||
|
|
||||||
# add the executable
|
# add the executable
|
||||||
add_executable(Tutorial tutorial.cxx)
|
add_executable(Tutorial tutorial.cxx)
|
||||||
|
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||||
|
|
||||||
target_link_libraries(Tutorial PUBLIC MathFunctions)
|
target_link_libraries(Tutorial PUBLIC MathFunctions)
|
||||||
|
|
||||||
# add the binary tree to the search path for include files
|
# add the binary tree to the search path for include files
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
include("release/CPackConfig.cmake")
|
include("release/CPackConfig.cmake")
|
||||||
|
|
||||||
set(CPACK_INSTALL_CMAKE_PROJECTS
|
set(CPACK_INSTALL_CMAKE_PROJECTS
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
// A simple program that computes the square root of a number
|
// A simple program that computes the square root of a number
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "MathFunctions.h"
|
#include "MathFunctions.h"
|
||||||
@@ -9,6 +8,7 @@
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
// report version
|
||||||
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
|
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
|
||||||
<< Tutorial_VERSION_MINOR << std::endl;
|
<< Tutorial_VERSION_MINOR << std::endl;
|
||||||
std::cout << "Usage: " << argv[0] << " number" << std::endl;
|
std::cout << "Usage: " << argv[0] << " number" << std::endl;
|
||||||
@@ -18,8 +18,8 @@ int main(int argc, char* argv[])
|
|||||||
// convert input to double
|
// convert input to double
|
||||||
const double inputValue = std::stod(argv[1]);
|
const double inputValue = std::stod(argv[1]);
|
||||||
|
|
||||||
// calculate square root
|
|
||||||
const double outputValue = mathfunctions::sqrt(inputValue);
|
const double outputValue = mathfunctions::sqrt(inputValue);
|
||||||
|
|
||||||
std::cout << "The square root of " << inputValue << " is " << outputValue
|
std::cout << "The square root of " << inputValue << " is " << outputValue
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
# set the project name and version
|
# set the project name and version
|
||||||
project(Tutorial VERSION 1.0)
|
project(Tutorial VERSION 1.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
add_library(tutorial_compiler_flags INTERFACE)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
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
|
# 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
|
# 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
|
# first we add the executable that generates the table
|
||||||
add_executable(MakeTable MakeTable.cxx)
|
add_executable(MakeTable MakeTable.cxx)
|
||||||
|
target_link_libraries(MakeTable tutorial_compiler_flags)
|
||||||
|
|
||||||
# add the command to generate the source code
|
# add the command to generate the source code
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
@@ -41,19 +42,18 @@ if(USE_MYMATH)
|
|||||||
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
|
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
|
||||||
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
|
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
|
||||||
|
|
||||||
# define the symbol stating we are using the declspec(dllexport) when
|
# define the symbol stating we are using the declspec(dllexport) when
|
||||||
# building on windows
|
# building on windows
|
||||||
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
|
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 rules
|
||||||
install(TARGETS MathFunctions
|
install(TARGETS MathFunctions tutorial_compiler_flags
|
||||||
DESTINATION lib
|
DESTINATION lib
|
||||||
EXPORT MathFunctionsTargets)
|
EXPORT MathFunctionsTargets)
|
||||||
install(FILES MathFunctions.h DESTINATION include)
|
install(FILES MathFunctions.h DESTINATION include)
|
||||||
@@ -17,11 +17,10 @@ double mysqrt(double x)
|
|||||||
// use the table to help find an initial value
|
// use the table to help find an initial value
|
||||||
double result = x;
|
double result = x;
|
||||||
if (x >= 1 && x < 10) {
|
if (x >= 1 && x < 10) {
|
||||||
|
std::cout << "Use the table to help find an initial value " << std::endl;
|
||||||
result = sqrtTable[static_cast<int>(x)];
|
result = sqrtTable[static_cast<int>(x)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have both log and exp then use them
|
|
||||||
|
|
||||||
// do ten iterations
|
// do ten iterations
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if (result <= 0) {
|
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_MAJOR @Tutorial_VERSION_MAJOR@
|
||||||
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
|
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
// report version
|
||||||
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
|
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
|
||||||
<< Tutorial_VERSION_MINOR << std::endl;
|
<< Tutorial_VERSION_MINOR << std::endl;
|
||||||
std::cout << "Usage: " << argv[0] << " number" << std::endl;
|
std::cout << "Usage: " << argv[0] << " number" << std::endl;
|
||||||
@@ -15,7 +16,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// convert input to double
|
// convert input to double
|
||||||
double inputValue = std::stod(argv[1]);
|
const double inputValue = std::stod(argv[1]);
|
||||||
|
|
||||||
const double outputValue = mathfunctions::sqrt(inputValue);
|
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
|
directory and from an install / package. This means converting the
|
||||||
:command:`target_include_directories` call for MathFunctions to look like:
|
:command:`target_include_directories` call for MathFunctions to look like:
|
||||||
|
|
||||||
.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
|
.. literalinclude:: Step12/MathFunctions/CMakeLists.txt
|
||||||
:language: cmake
|
:language: cmake
|
||||||
:start-after: # to find MathFunctions.h, while we don't.
|
:start-after: # to find MathFunctions.h, while we don't.
|
||||||
:end-before: # should we use our own math functions
|
: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
|
ahead and add a new file to the top-level of the project called
|
||||||
``Config.cmake.in`` with the following contents:
|
``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
|
Then, to properly configure and install that file, add the following to the
|
||||||
bottom of the top-level ``CMakeLists.txt``:
|
bottom of the top-level ``CMakeLists.txt``:
|
||||||
|
|
||||||
.. literalinclude:: Complete/CMakeLists.txt
|
.. literalinclude:: Step12/CMakeLists.txt
|
||||||
:language: cmake
|
:language: cmake
|
||||||
:start-after: # install the configuration targets
|
:start-after: # install the configuration targets
|
||||||
:end-before: # generate the export
|
: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
|
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``:
|
the following to the bottom of the top level ``CMakeLists.txt``:
|
||||||
|
|
||||||
.. literalinclude:: Complete/CMakeLists.txt
|
.. literalinclude:: Step12/CMakeLists.txt
|
||||||
:language: cmake
|
:language: cmake
|
||||||
:start-after: # needs to be after the install(TARGETS ) command
|
: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
|
configured ``MathFunctionsConfig.cmake`` in the build directory to be used by
|
||||||
other projects, without needing it to be installed.
|
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
|
**Note:** This example is valid for single-configuration generators and will
|
||||||
generate ``Config.cmake`` files.
|
not work for multi-configuration generators (e.g. Visual Studio).
|
||||||
|
|
||||||
It also shows how to state a project's external dependencies when generating
|
By default, CMake's model is that a build directory only contains a single
|
||||||
a ``Config.cmake``.
|
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
|
Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
|
||||||
configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo.
|
``CMakeLists.txt`` file:
|
||||||
|
|
||||||
But it is possible to setup CPack to bundle multiple build directories at the
|
.. literalinclude:: Complete/CMakeLists.txt
|
||||||
same time to build a package that contains multiple configurations of the
|
:language: cmake
|
||||||
same project.
|
: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
|
And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:
|
||||||
will contain all the builds that we want to package together.
|
|
||||||
|
|
||||||
Second create a ``debug`` and ``release`` directory underneath
|
.. literalinclude:: Complete/CMakeLists.txt
|
||||||
``multi_config``. At the end you should have a layout that looks like:
|
: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
|
.. code-block:: none
|
||||||
|
|
||||||
─ multi_config
|
- Step12
|
||||||
├── debug
|
└── debug
|
||||||
└── release
|
└── release
|
||||||
|
|
||||||
Now we need to setup debug and release builds, which would roughly entail
|
Now we need to setup debug and release builds. We can use
|
||||||
the following:
|
:variable:`CMAKE_BUILD_TYPE` to set the configuration type:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
cd debug
|
cd debug
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/
|
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
cmake --build .
|
cmake --build .
|
||||||
cd ../release
|
cd ../release
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/
|
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||||
cmake --build .
|
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
|
Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
|
||||||
a custom ``MultiCPackConfig.cmake`` file to package both builds into a single
|
projects to install. In this case, we want to install both debug and release.
|
||||||
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
|
.. 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)
|
set(tutorial_build_options -DUSE_MYMATH:BOOL=OFF)
|
||||||
endif()
|
endif()
|
||||||
add_test(${tutorial_test_name} ${CMAKE_CTEST_COMMAND}
|
add_test(${tutorial_test_name} ${CMAKE_CTEST_COMMAND}
|
||||||
|
-C "Release"
|
||||||
--build-and-test
|
--build-and-test
|
||||||
"${CMake_SOURCE_DIR}/Help/guide/tutorial/${step_name}"
|
"${CMake_SOURCE_DIR}/Help/guide/tutorial/${step_name}"
|
||||||
${tutorial_build_dir}_Build
|
${tutorial_build_dir}_Build
|
||||||
@@ -1606,11 +1607,11 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
||||||
foreach(STP RANGE 2 11)
|
foreach(STP RANGE 2 12)
|
||||||
add_tutorial_test(Step${STP} TRUE)
|
add_tutorial_test(Step${STP} TRUE)
|
||||||
endforeach()
|
endforeach()
|
||||||
add_tutorial_test(Complete TRUE)
|
add_tutorial_test(Complete TRUE)
|
||||||
foreach(STP RANGE 3 11)
|
foreach(STP RANGE 3 12)
|
||||||
add_tutorial_test(Step${STP} FALSE)
|
add_tutorial_test(Step${STP} FALSE)
|
||||||
endforeach()
|
endforeach()
|
||||||
add_tutorial_test(Complete FALSE)
|
add_tutorial_test(Complete FALSE)
|
||||||
|
|||||||
Reference in New Issue
Block a user