Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Help / guide / tutorial / Selecting Static or Shared Libraries.rst
1 Step 10: Selecting Static or Shared Libraries
2 =============================================
3
4 In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can
5 be used to control the default behavior of :command:`add_library`,
6 and allow control over how libraries without an explicit type (``STATIC``,
7 ``SHARED``, ``MODULE`` or ``OBJECT``) are built.
8
9 To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
10 top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
11 users to optionally select if the value should be ``ON`` or ``OFF``.
12
13 Next we are going to refactor ``MathFunctions`` to become a real library that
14 encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
15 code to do this logic. This will also mean that ``USE_MYMATH`` will not control
16 building ``MathFunctions``, but instead will control the behavior of this
17 library.
18
19 The first step is to update the starting section of the top-level
20 ``CMakeLists.txt`` to look like:
21
22 .. literalinclude:: Step11/CMakeLists.txt
23   :caption: CMakeLists.txt
24   :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
25   :language: cmake
26   :end-before: # add the binary tree
27
28 Now that we have made ``MathFunctions`` always be used, we will need to update
29 the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
30 create a SqrtLibrary that will conditionally be built and installed when
31 ``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
32 explicitly require that SqrtLibrary is built statically.
33
34 The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
35
36 .. literalinclude:: Step11/MathFunctions/CMakeLists.txt
37   :caption: MathFunctions/CMakeLists.txt
38   :name: MathFunctions/CMakeLists.txt-add_library-STATIC
39   :language: cmake
40   :lines: 1-36,42-
41
42 Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
43 ``detail`` namespaces:
44
45 .. literalinclude:: Step11/MathFunctions/mysqrt.cxx
46   :caption: MathFunctions/mysqrt.cxx
47   :name: MathFunctions/mysqrt.cxx-namespace
48   :language: c++
49
50 We also need to make some changes in ``tutorial.cxx``, so that it no longer
51 uses ``USE_MYMATH``:
52
53 #. Always include ``MathFunctions.h``
54 #. Always use ``mathfunctions::sqrt``
55 #. Don't include ``cmath``
56
57 Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
58
59 .. literalinclude:: Step11/MathFunctions/MathFunctions.h
60   :caption: MathFunctions/MathFunctions.h
61   :name: MathFunctions/MathFunctions.h
62   :language: c++
63
64 At this point, if you build everything, you may notice that linking fails
65 as we are combining a static library without position independent code with a
66 library that has position independent code. The solution to this is to
67 explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
68 SqrtLibrary to be ``True`` no matter the build type.
69
70 .. literalinclude:: Step11/MathFunctions/CMakeLists.txt
71   :caption: MathFunctions/CMakeLists.txt
72   :name: MathFunctions/CMakeLists.txt-POSITION_INDEPENDENT_CODE
73   :language: cmake
74   :lines: 37-42
75
76 **Exercise**: We modified ``MathFunctions.h`` to use dll export defines.
77 Using CMake documentation can you find a helper module to simplify this?