Skip to content

Commit 0306178

Browse files
authored
Merge pull request #3718 from conan-io/release/2.3
Sync develop2 with latest release
2 parents bebfd46 + 3cc43da commit 0306178

File tree

13 files changed

+354
-1
lines changed

13 files changed

+354
-1
lines changed

examples/dev_flow.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Developer tools and flows
77
:maxdepth: 2
88

99
dev_flow/debug/step_into_dependencies
10+
dev_flow/debug/debugging_visual
11+
dev_flow/tool_requires/mingw
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
.. _examples_dev_flow_debug_visual:
2+
3+
4+
Debugging shared libraries with Visual Studio
5+
=============================================
6+
7+
In the previous example we discussed how to debug dependencies in Visual Studio, but when using Conan dependencies in a project it is
8+
possible that the original build folder and build files don't exist. Conan packages don't contain the necessary
9+
information for debugging libraries with Visual Studio by default, this information is stored in PDBs that are
10+
generated during the compilation of the libraries. When using Conan these PDBs are generated in the build folder,
11+
which is only needed during the building of the libraries. For that reason it's a common operation to clean the Conan
12+
cache with ``conan cache clean`` to remove the build folder and save disk space.
13+
14+
For these cases where the build folder is not present we created a hook that copies the PDBs generated in the build folder to the
15+
package folder. This behavior can't be forced by default because PDB files are usually larger than the whole package,
16+
and it would greatly increase the package sizes.
17+
18+
This section will follow some examples on how to debug a project in different cases to show how users can make use of
19+
the PDB hook.
20+
21+
22+
Creating a project and debugging as usual
23+
-----------------------------------------
24+
25+
First we will debug our project as usual, as it is explained in more detail in the :ref:`previous example <examples_dev_flow_debug_step_into>`
26+
We can start building our dependencies from sources as in the previous section, only this time we will build them as
27+
shared. To begin with, clone the sources needed for the example from the `examples2 repository <https://github.com/conan-io/examples2>`_
28+
in GitHub and create the project.
29+
30+
.. code-block:: bash
31+
32+
$ git clone https://github.com/conan-io/examples2.git
33+
$ cd examples2/tutorial/consuming_packages/simple_cmake_project
34+
$ conan install . -o="*:shared=True" -s build_type=Debug --build="zlib/*"
35+
...
36+
Install finished successfully
37+
38+
# CMake presets require CMake>=3.23
39+
$ cmake --preset=conan-default
40+
41+
.. note::
42+
43+
We will only cover the case where the dependencies are built as shared because the PDBs and how they are linked
44+
to the libraries works differently for static libraries.
45+
46+
We can now open the solution ``compressor.sln`` to open our project in Visual Studio and debug it as explained in the
47+
previous example. Setting a breakpoint in line 22, running the debugger and using the step into will allow us to debug
48+
inside our dependency file ``deflate.c``.
49+
50+
.. image:: ../../../images/examples/dev_flow/debug_with_build_files.png
51+
:alt: Debugging with build files in cache
52+
53+
In this case the original build files were all present so the debugger worked as usual. Next we will see how the
54+
debugger works after removing the build files from the Conan cache.
55+
56+
57+
Removing build files from the Conan cache
58+
-----------------------------------------
59+
60+
There are multiple reasons that can cause the build files to not be present after the dependencies are compiled. We
61+
will clean our build files from the cache to simulate one of those cases using ``conan cache clean``. The ``--build``
62+
flag makes sure that we only remove the build files, as we will need our source files for this example.
63+
64+
.. code-block:: bash
65+
66+
$ conan list zlib/1.2.11:*
67+
$ conan cache path --folder build zlib/1.2.11:17b26a16efb893750e4481f98a154db2934ead88
68+
$ conan cache clean zlib/1.2.11 --build
69+
$ conan cache path --folder build zlib/1.2.11:17b26a16efb893750e4481f98a154db2934ead88
70+
71+
After closing and reopening our solution in Visual Studio, we can try to debug again. If you try to step into the
72+
dependency, with the breakpoint on line 22, you will notice it will directly skip over to the next line as Visual Studio
73+
doesn't have any information on the dependencies to debug.
74+
75+
76+
Installing a hook to copy the PDBs to the package folder
77+
--------------------------------------------------------
78+
79+
To solve the issue of not having the PDBs in the package folder, we created a hook that copies the PDBs from the build
80+
folder to the package folder.
81+
The hook is available in the `conan-extensions repository <https://github.com/conan-io/conan-extensions>`_.
82+
Installing the whole repository will work, but we recommend to only install the hooks folder from the
83+
``conan-extensions`` repository with:
84+
85+
.. code-block:: text
86+
87+
$ conan config install https://github.com/conan-io/conan-extensions.git -sf=extensions/hooks -tf=extensions/hooks
88+
89+
The hook is made so it won't run by default, as it can increase the package size significantly. As explained in the
90+
:ref:`hooks documentation <reference_extensions_hooks>`, we need to change the name of our hook to start with ``hook_``.
91+
To locate the path where the hook was placed, run the command ``conan config home`` to find
92+
your local cache path and go to the ``extensions/hooks`` folder to rename the ``_hook_copy_pdbs_to_package.py`` file.
93+
Be aware that this hook will run everytime a ``package()`` method is run, to disable the hook just rename the hook back
94+
to start with ``_hook_``.
95+
96+
The hook is implemented as a post-package hook, which means that it will execute after the package is created through the
97+
``package()`` method of a recipe. This avoids any potential issue, as the order will be as follows:
98+
99+
- The ``build()`` method of the recipe is executed, generating the DLLs and PDBs
100+
- The ``package()`` method of the recipe is executed, copying the necessary files to the package folder (in this case the DLLs but not the PDBs)
101+
- The hook is executed copying the PDBs from the build folder next to its DLL for every DLL in the package
102+
103+
The hook makes use of the ``dumpbin`` tool which is included in the Visual Studio installation. This tool allows us
104+
to get information of a DLL, in this case the path where its associated PDB is located. It will be used for every DLL
105+
in the package to locate its PDB to copy it to the package folder.
106+
107+
For more information on how PDBs work with Visual and how we used it to create the hook can be found in the
108+
`hook readme <https://github.com/conan-io/conan-extensions/blob/main/hooks/README.md>`_.
109+
110+
Debugging without build files
111+
-----------------------------
112+
113+
After installing the hook we will create again the project from sources so the hook can now copy the PDBs to the package
114+
folder alongside the package DLLs so they can be found by the debugger.
115+
116+
.. code-block:: bash
117+
118+
$ conan install . -o="*:shared=True" -s build_type=Debug --build="zlib/*"
119+
...
120+
zlib/1.2.11: Calling package()
121+
...
122+
[HOOK - hook_copy_pdbs_to_package.py] post_package(): PDBs post package hook running
123+
...
124+
Install finished successfully
125+
126+
# CMake presets require CMake>=3.23
127+
$ cmake --preset=conan-default
128+
129+
Notice that when running the conan install now you will see the outputs of the hook running after the call to ``package()``.
130+
To test the hook we can clean the cache again to remove the build files, this includes the sources used to build the
131+
library and the PDBs that were originally generated.
132+
133+
.. code-block:: bash
134+
135+
$ conan cache clean zlib/1.2.11 --build
136+
137+
Open the solution in Visual Studio again and start the debugger. When you try to step into the dependency in line 22, an error
138+
message will pop up telling us the file was not found and it will ask where the file is located. We can close this window
139+
and it will give the option to view the disassembly which can be debugged thanks to the PDB. The PDB only contains the
140+
debugging information but Visual Studio is missing the source files, so it won't be able to debug over those as it did
141+
initially.
142+
143+
.. image:: ../../../images/examples/dev_flow/source_file_not_found.png
144+
:alt: Debugging without build files in cache
145+
146+
147+
Locating the sources path for the debugger
148+
------------------------------------------
149+
150+
Visual Studio won't be able to find te source files by itself after deleting the original build files. To be able to
151+
debug over the source files, there's an option to manually set the source folder path so that it's possible to debug over the source files. This
152+
requires that the source files for the dependency exist. In our case we can get the location of this source files
153+
by running a ```conan cache path``.
154+
155+
.. code-block::
156+
157+
$ conan cache path --folder source zlib/1.2.11
158+
159+
In case this source path is not present we can use a config to download the sources again.
160+
161+
.. code-block::
162+
163+
$ conan install . -o="*:shared=True" -s build_type=Debug -c:a="tools.build:download_source=True"
164+
165+
Once we have the source path we can set it in Visual Studio so the debugger can find the source files. Right click on
166+
the solution in the Solution Explorer and select Properties. Go to Debug Source Files in the Common Properties section
167+
and add our source path.
168+
169+
.. image:: ../../../images/examples/dev_flow/add_path_to_debug_source_files.png
170+
:alt: Setting source path
171+
172+
Starting the debugger again will allow to step into the code of the dependency as in the first example we did.
173+
174+
.. note::
175+
176+
If there are patches to the source files we won't be able to debug over the modified files, as we are using the
177+
files from the source folder and the patches are applied in a later step right before being compiled in the build folder.
178+
179+
Any modification to the source files will not allow debugging over them, as Visual Studio does a checksum check, so
180+
they need to be the exact same files as when the libraries were compiled.
181+
182+
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
.. _examples_dev_flow_tool_requires_mingw:
2+
3+
Using a MinGW as tool_requires to build with gcc in Windows
4+
-----------------------------------------------------------
5+
6+
If we had MinGW installed in our environment, we could define a profile like:
7+
8+
.. code-block::
9+
10+
[settings]
11+
os=Windows
12+
compiler=gcc
13+
compiler.version=12
14+
compiler.libcxx=libstdc++11
15+
compiler.threads=posix
16+
compiler.exception=sjlj
17+
arch=x86_64
18+
build_type=Release
19+
20+
[buildenv]
21+
PATH+=(path)C:/path/to/mingw/bin
22+
# other environment we might need like
23+
CXX=C:/path/to/mingw/bin/g++
24+
# etc
25+
26+
[conf]
27+
# some configuration like 'tools.build:compiler_executables' might be needed for some cases
28+
29+
30+
But we can also use a Conan package that contains a copy of the MinGW compiler and use it
31+
as a ``tool_requires`` instead:
32+
33+
.. code-block::
34+
:caption: mingw-profile.txt
35+
36+
[settings]
37+
os=Windows
38+
compiler=gcc
39+
compiler.version=12
40+
compiler.libcxx=libstdc++11
41+
compiler.threads=posix
42+
compiler.exception=seh
43+
arch=x86_64
44+
build_type=Release
45+
46+
47+
[tool_requires]
48+
mingw-builds/12.2.0
49+
50+
51+
With this profile we can for example create a package in Windows with:
52+
53+
54+
.. code-block:: bash
55+
56+
# Using a basic template project
57+
$ conan new cmake_lib -d name=mypkg -d version=0.1
58+
$ conan create . -pr=mingw
59+
...
60+
-- The CXX compiler identification is GNU 12.2.0
61+
...
62+
63+
64+
======== Testing the package: Executing test ========
65+
mypkg/0.1 (test package): Running test()
66+
mypkg/0.1 (test package): RUN: .\example
67+
mypkg/0.1: Hello World Release!
68+
mypkg/0.1: _M_X64 defined
69+
mypkg/0.1: __x86_64__ defined
70+
mypkg/0.1: _GLIBCXX_USE_CXX11_ABI 1
71+
mypkg/0.1: MSVC runtime: MultiThreadedDLL
72+
mypkg/0.1: __cplusplus201703
73+
mypkg/0.1: __GNUC__12
74+
mypkg/0.1: __GNUC_MINOR__2
75+
mypkg/0.1: __MINGW32__1
76+
mypkg/0.1: __MINGW64__1
77+
mypkg/0.1 test_package
78+
79+
80+
.. seealso::
81+
82+
- The ConanCenter web page for the `mingw-builds package <https://conan.io/center/recipes/mingw-builds>`_
83+
- The ``conan-center-index`` `mingw-builds Github repo recipe <https://github.com/conan-io/conan-center-index/tree/master/recipes/mingw-builds/all>`_

examples/runners.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Conan runners examples
44
======================
55

6+
.. include:: ../common/experimental_warning.inc
7+
68
.. toctree::
79
:maxdepth: 2
810

examples/runners/docker/basic.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Creating a Conan package using a Docker runner
44
==============================================
55

6+
.. include:: ../../../common/experimental_warning.inc
7+
68
In this example we are going to see how to create the ``zlib/1.3.1`` Conan packge inside Docker using a runner. Let’s create two profiles and a Dockerfile inside our project folder.
79

810
.. code-block:: bash

examples/runners/docker/configfile_build_args.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Using a docker runner configfile to parameterize a Dockerfile
44
=============================================================
55

6+
.. include:: ../../../common/experimental_warning.inc
7+
68
In this example we are going to see how to use a docker runner configfile to define our Dockerfile base image. Let’s create two profiles and a Dockerfile inside our project folder.
79

810
.. code-block:: bash
Loading
Loading
Loading

reference/commands/create.rst

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,82 @@ The same happens for lockfiles created with ``--lockfile-out`` argument. The loc
6464
dependencies, you can control their build using the ``--build-test`` argument.
6565

6666

67+
Methods execution order
68+
-----------------------
69+
70+
The ``conan create`` executes :ref:`methods <reference_conanfile_methods>` of a *conanfile.py* in the following order:
71+
72+
#. Export recipe to the cache
73+
#. ``init()``
74+
#. ``set_name()``
75+
#. ``set_version()``
76+
#. ``export()``
77+
#. ``export_sources()``
78+
#. Compute dependency graph
79+
#. ``ìnit()``
80+
#. ``config_options()``
81+
#. ``configure()``
82+
#. ``requirements()``
83+
#. ``build_requirements()``
84+
#. Compute necessary packages
85+
#. ``validate_build()``
86+
#. ``validate()``
87+
#. ``package_id()``
88+
#. ``layout()``
89+
#. ``system_requirements()``
90+
#. Install packages
91+
#. ``source()``
92+
#. ``build_id()``
93+
#. ``generate()``
94+
#. ``build()``
95+
#. ``package()``
96+
#. ``package_info()``
97+
98+
Steps ``generate()``, ``build()``, ``package()`` from *Install packages* step will not be called if the package
99+
is not being built from sources.
100+
101+
After that, if you have a folder named *test_package* in your project or you call the ``conan create`` command with the
102+
``--test-folder`` flag, the command will invoke the methods of the *conanfile.py* file inside the folder in the following order:
103+
104+
#. Launch test_package
105+
#. (test package) ``init()``
106+
#. (test package) ``set_name()``
107+
#. (test package) ``set_version()``
108+
#. Compute dependency graph
109+
#. (test package) ``config_options()``
110+
#. (test package) ``configure()``
111+
#. (test package) ``requirements()``
112+
#. (test package) ``build_requirements()``
113+
#. ``ìnit()``
114+
#. ``config_options()``
115+
#. ``configure()``
116+
#. ``requirements()``
117+
#. ``build_requirements()``
118+
#. Compute necessary packages
119+
#. ``validate_build()``
120+
#. ``validate()``
121+
#. ``package_id()``
122+
#. ``layout()``
123+
#. (test package) ``validate_build()``
124+
#. (test package) ``validate()``
125+
#. (test package) ``package_id()``
126+
#. (test package) ``layout()``
127+
#. ``system_requirements()``
128+
#. (test package) ``system_requirements()``
129+
#. Install packages
130+
#. ``build_id()``
131+
#. ``generate()``
132+
#. ``build()``
133+
#. ``package_info()``
134+
#. Test the package
135+
#. (test package) ``build()``
136+
#. (test package) ``test()``
137+
138+
The functions with *(test package)* belong to the *conanfile.py* in the *test_package* folder. The steps
139+
``build_id()``, ``generate()``, ``build()`` inside the *Install packages* step will be skipped if the project is
140+
already installed. Typically, it should be installed just as it was installed in the previous "install packages" step.
141+
142+
67143
.. seealso::
68144

69145
- Read more about creating packages in the :ref:`dedicated

reference/runners.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Runners
44
=======
55

6+
.. include:: ../common/experimental_warning.inc
7+
68
Runners provide a seamless method to execute Conan on remote build environments like Docker ones, directly from your local setup by simply configuring your host profile.
79

810
- Installing a version of Conan with runner dependencies ``pip install conan[runners]``.

0 commit comments

Comments
 (0)