Skip to content

Commit

Permalink
merge all branches for targets episode
Browse files Browse the repository at this point in the history
  • Loading branch information
code4yonglei committed Sep 10, 2024
1 parent 68cb865 commit 433dbdc
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 112 deletions.
1 change: 0 additions & 1 deletion content/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ In this workshop, you will learn
40 min ; :doc:`hello-ctest`
40 min ; :doc:`probing`
40 min ; :doc:`targets`
30 min ; :doc:`targets-new-visibility-levels`
35 min ; :doc:`python-bindings`
20 min ; :doc:`tips-and-tricks`

Expand Down
75 changes: 0 additions & 75 deletions content/targets-new-visibility-levels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,6 @@ Visibility levels (Code from Coderefineary)
-------------------------------------------


Visibility levels ``PRIVATE``, ``PUBLIC``, or ``INTERFACE`` are very powerful and herein we will briefly demonstrate their difference.

In this demo, we split the source code into 3 libraries and all files are available in the ``content/code/xx_visibility-levels/`` folder.

.. code-block:: bash
.
├── CMakeLists.txt
├── greeting
│   ├── greeting.cpp
│   └── greeting.hpp
├── hello_world
│   ├── hello_world.cpp
│   └── hello_world.hpp
├── main.cpp
└── world
├── world.cpp
└── world.hpp
In this source code, the main function links to greeting which links to hello_world which links to world.


.. typealong:: The internal dependency tree

If you have installed ``Graphviz``, you can visualize the dependencies between these targets:

.. code-block:: console
$ cd build
$ cmake --graphviz=project.dot ..
$ dot -T svg project.dot -o graphviz-greeting-hello-world.svg
.. figure:: img/graphviz-greeting-hello-world.svg
:align: center

The dependencies between the four targets in the code example.



Take a look at the ``CMakeLists.txt``:


.. literalinclude:: code/xx_visibility-levels-CR/CMakeLists.txt
:language: cmake
:linenos:
:emphasize-lines: 17


.. exercise:: Testing the 3 different visibility levels

1. Browse, configure, build, and run the code.

2. Uncomment the highlighted line (line 17) with ``target_compile_definitions``, configure into a fresh folder, and build using the commands below. You will see that the definition is used in ``world.cpp`` but nowhere else.

.. code-block:: console
$ cmake -S. -Bbuild_private
$ cmake --build build_private
3. Change the definition to ``PUBLIC``, configure into a fresh folder, and build. You will see that the definition is used both in ``world.cpp`` and ``hello_world.cpp``.

.. code-block:: console
$ cmake -S. -Bbuild_public
$ cmake --build build_public
4. Then change the definition to ``INTERFACE``, configure into a fresh folder, and build. You will see that the definition is used only in ``hello_world.cpp`` but not in ``world.cpp``.

.. code-block:: console
$ cmake -S. -Bbuild_interface
$ cmake --build build_interface



Expand Down
132 changes: 96 additions & 36 deletions content/targets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,55 +94,92 @@ Why it is robust to use targets and properties than using variables? Given a tar

.. typealong:: Understanding visibility levels

Visibility levels ``PRIVATE``, ``PUBLIC``, or ``INTERFACE`` are very powerful and herein we will briefly demonstrate their difference.

In this demo, we want to compile a C++ library and an executable. A complete source code and solution are available in the ``content/code/xx_visibility-levels/`` folder.

* The library code in the ``account`` subfolder consists of one source (account.cpp) and one header file (account.hpp). This header file and the shared library are needed to produce the ``bank`` executable.
* The compiler flag ``-ffast-math`` will be used to propaged throughout the project.
* The executable code is in ``bank.cpp``, which includes the header file ``account.hpp``.

Visibility levels ``PRIVATE``, ``PUBLIC``, or ``INTERFACE`` are very powerful and herein we will briefly demonstrate their difference.

More description about the source code:
In this demo, we split the source code into 3 libraries and all files are available in the ``content/code/xx_visibility-levels/`` folder.

.. code-block:: bash
.
├── CMakeLists.txt
├── greeting
│   ├── greeting.cpp
│   └── greeting.hpp
├── hello_world
│   ├── hello_world.cpp
│   └── hello_world.hpp
├── main.cpp
└── world
├── world.cpp
└── world.hpp
In this source code, the main function links to greeting which links to hello_world which links to world.


.. typealong:: The internal dependency tree

If you have installed ``Graphviz``, you can visualize the dependencies between these targets:

.. code-block:: console
$ cd build
$ cmake --graphviz=project.dot ..
$ dot -T svg project.dot -o graphviz-greeting-hello-world.svg
.. figure:: img/graphviz-greeting-hello-world.svg
:align: center

The dependencies between the four targets in the code example.



Take a look at the ``CMakeLists.txt``:


.. literalinclude:: code/xx_visibility-levels-CR/CMakeLists.txt
:language: cmake
:linenos:
:emphasize-lines: 17


.. exercise:: Testing the 3 different visibility levels

1. Browse, configure, build, and run the code.

2. Uncomment the highlighted line (line 17) with ``target_compile_definitions``, configure into a fresh folder, and build using the commands below. You will see that the definition is used in ``world.cpp`` but nowhere else.

.. code-block:: console
$ cmake -S. -Bbuild_private
$ cmake --build build_private
3. Change the definition to ``PUBLIC``, configure into a fresh folder, and build. You will see that the definition is used both in ``world.cpp`` and ``hello_world.cpp``.

.. code-block:: console
$ cmake -S. -Bbuild_public
$ cmake --build build_public
4. Then change the definition to ``INTERFACE``, configure into a fresh folder, and build. You will see that the definition is used only in ``hello_world.cpp`` but not in ``world.cpp``.

.. code-block:: console
$ cmake -S. -Bbuild_interface
$ cmake --build build_interface
1. The ``account`` target declares the ``account.cpp`` source file as ``PRIVATE`` since it is only needed to produce the shared library.
.. code-block:: cmake
target_sources(account
PRIVATE
account.cpp
)
2. The ``-ffast-math`` is instead ``PUBLIC`` as it needs to be propagated to all targets consuming ``account``.
.. code-block:: cmake
target_compile_options(account
PUBLIC
"-ffast-math"
)
3. The ``account`` folder is an include directory with ``INTERFACE`` visibility because only targets consuming ``account`` need to know where ``account.hpp`` is located.
.. code-block:: cmake
target_include_directories(account
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
.. callout:: Rule of thumb for visibility settings
When working out which visibility settings to use for the properties of your targets you can refer to the following table:
============== ================ ============
Who needs? Others
-------------- -----------------------------
Target **YES** **NO**
============== ================ ============
**YES** ``PUBLIC`` ``PRIVATE``
**NO** ``INTERFACE`` N/A
============== ================ ============
Expand Down Expand Up @@ -171,5 +208,28 @@ For a complete list of properties known to CMake:
You can get the current value of any property with ``get_property`` and set the value of any property with ``set_property``.



Multiple folders
----------------






















0 comments on commit 433dbdc

Please sign in to comment.