Selecting Static or Shared Libraries.rst 3.1 KB

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