Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   dh    ( 1 )

секвенсор команд debhelper (debhelper command sequencer)

  Name  |  Synopsis  |  Description  |    Override and hook targets    |  Options  |  Examples  |  Debhelper provided dh addons  |  Internals  |  See also  |

OVERRIDE AND HOOK TARGETS

A debian/rules file using dh can override the command that is run at any step in a sequence, by defining an override target. It is also possible to inject a command before or after any step without affecting the step itself.

Injecting commands before or after a step Note: This feature requires debhelper 12.8 or later plus the package must use compatibility mode 10 or later.

To inject commands before dh_command, add a target named execute_before_dh_command to the rules files. Similarly, if you want to inject commands after dh_command, add the target execute_after_dh_command. Both targets can be used for the same dh_command and also even if the command is overridden (as described in "Overriding a command" below).

When these targets are defined, dh will call the targets respectively before or after it would invoke dh_command (or its override target).

Overriding a command To override dh_command, add a target named override_dh_command to the rules file. When it would normally run dh_command, dh will instead call that target. The override target can then run the command with additional options, or run entirely different commands instead. See examples below.

Architecture dependent/independent override and hook targets The override and hook targets can also be defined to run only when building architecture dependent or architecture independent packages. Use targets with names like override_dh_command-arch and execute_afterdh_command-indep.

This feature is available since debhelper 8.9.7 (for override targets) and 12.8 (for hook targets).

Completely empty targets As a special optimization, dh will skip a target if it is completely empty. This is mostly useful for override targets, where the command will simply be skipped without the overhead of invoking a dummy target.

Note that the target has to be completely empty for this to work:

# Skip dh_bar - the good and optimized way # Some rationale for skipping dh_bar goes here override_dh_bar:

# Skip dh_foo - the slow way override_dh_foo: # Some rationale for skipping dh_foo goes here # (these comments causes a dummy target to be run)

Verifying targets are picked up by dh If you want to confirm that dh has seen an override or a hook target, you can use the following command as an example:

$ dh binary --no-act | grep dh_install | head -n5 dh_installdirs dh_install debian/rules execute_after_dh_install dh_installdocs dh_installchangelogs

The debian/rules execute_after_dh_install in the output, which signals that dh registered a execute_after_dh_install target and would run it directly after dh_install(1).

Note that "Completely empty targets" will be omitted in the listing above. This makes it a bit harder to spot as you are looking for the omission of a command name. But otherwise, the principle remains the same.

Caveats with hook targets and makefile conditionals If you choose to wrap a hook target in makefile conditionals, please be aware that dh computes all the hook targets a head of time and caches the result for that run. Furthermore, the conditionals will be invoked again when dh calls the hook target later and will assume the answer did not change.

The parsing and caching often happens before dh knows whether it will build arch:any (-a) or/and arch:all (-i) packages, which can produce confusing results - especially when dh_listpackages(1) is part of the conditional.

Most of the problems can be avoided by making the hook target unconditional and then have the "body" be partially or completely conditional. As an example:

# SIMPLE: It is well-defined what happens. The hook target # is always considered. The "maybe run this" bit is # conditional but dh_foo is definitely skipped. # # Note: The conditional is evaluated "twice" where its # influences what happens. Once when dh check which hook # targets exist and once when the override_dh_foo hook target # is run. If *either* times return false, "maybe run this" # is skipped. override_dh_foo: ifneq (...) maybe run this endif

# SIMPLE: This is also well-defined. The hook target is always # run and dh_bar is skipped. The "maybe run this" bit is # conditional as one might expect. # # Note: The conditional is still evaluated multiple times (in # different process each time). However, only the evaluation # that happens when the hook target is run influences what # happens. override_dh_bar: : # Dummy command to force the target to always be run ifneq (...) maybe run this endif

# COMPLICATED: This case can be non-trivial and have sharp edges. # Use at your own peril if dh_listpackages in the conditional. # # Here, either dh_baz is run normally OR "maybe run this" is run # instead. # # And it gets even more complicated to reason about if dh needs to # recurse into debian/rules because you have an "explicit" # standard target (e.g. a "build-arch:" target separate from "%:"). ifneq (...) override_dh_baz: maybe run this endif

These recipes are also relevant for conditional dependency targets, which are often seen in a variant of the following example:

COND_TASKS = ifneq (...) COND_TASKS += maybe-run-this endif ...

maybe-run-this: ...

# SIMPLE: It is well-defined what happens. Either the # $(COND_TASKS) are skipped or run. # # Note: The conditional is evaluated "twice" where its # influences what happens. Once when dh check which hook # targets exist and once when the override_dh_foo hook target # is run. If *either* times return false, $(COND_TASKS) # is skipped. override_dh_foo: $(COND_TASKS)

# SIMPLE: This is also well-defined. The hook target is always # run and dh_bar is skipped. The $(COND_TASKS) bit is # conditional as one might expect. # # Note: The conditional is still evaluated multiple times (in # different process each time). However, only the evaluation # that happens when the hook target is run influences what # happens. override_dh_bar: $(COND_TASKS) : # Dummy command to force the target to always be run

# COMPLICATED: This case can be non-trivial and have sharp edges. # Use at your own peril if dh_listpackages in the conditional. # ifneq (...) override_dh_baz: $(COND_TASKS) endif

When in doubt, pick the relevant SIMPLE case in the examples above that match your need.