1

I'm trying to make a Debian package for a cmake project that, in single-threaded mode, takes 3 hours to compile. I'm trying to get a parallel build, but failing.

I've tried setting parallel=4 in my control file like so:

#!/usr/bin/make -f
export DEB_BUILD_OPTIONS="parallel=4"

%: dh $@ --parallel

Based on the accepted answer on this previous question, but I get the following warning:

dh: warning: invalid flag in DEB_BUILD_OPTIONS: "parallel=4"

And debhelper still invokes make -j1.

I've tried variations on the theme based on other suggestions/comments I've found online, DEB_BUILD_OPTIONS="-j=4", DEB_BUILD_OPTIONS="-j4" etc to no effect. I've tried setting debian/compat to 10. Always the result is invalid flag. How can I make debhelper honor this setting?

I'm doing the build in an Ubuntu Focal x86_64 docker container, and my version of debhelper is 12.10ubuntu1.

Dan
  • 383

2 Answers2

2

Note: OP solved the issue, it is documented in his own answer. I left this answer which give a hint for the ones using custom build steps (override_dh_*). As they have to map the variable.

Documentation you referenced debian/rules and DEB_BUILD_OPTIONS, mentions that it should be mapped/implemented in the lower level too.

The following makefile snippet is an example of how one may implement the build options; you will probably have to massage this example in order to make it work for your package.

...
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
    NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
    MAKEFLAGS += -j$(NUMJOBS)
endif
...

While the doc gives a make example, in this case an equivalent one should be used for cmake. It will not be hard finding a template from source of another package or from launchpad directly.

This is an example from cmake package itself, mapping the flag inside debian/rules directly (so still Makefile syntax):

ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
    NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
    BOOTSTRAP_FLAGS += --parallel=$(NUMJOBS)
endif

override_dh_auto_configure: $(BUILD_FLAGS_FILE) rm -rf Build && mkdir -p Build cd Build && ../bootstrap $(BOOTSTRAP_FLAGS)

Source: Any native source archive cmake*.tar.xz from Daily build of upstream cmake - Launchpad project

user.dz
  • 49,176
1

Turns out, I had the Makefile syntax wrong.

The error message I was seeing came from a regular expression in dpkg itself excerpted here:

         unless (/^([a-z][a-z0-9_-]*)(?:=(\S*))?$/) {
             warning(g_('invalid flag in %s: %s'), $source, $_);
             next;
         }

I re-read that regular expression a million times before I realized that the second %s in the warning does not have quotes around it, which means in the error message:

dh: warning: invalid flag in DEB_BUILD_OPTIONS: "parallel=4"

The quotes around "parallel=4" are coming from the environment variable itself not from the format string.

The fix, is to change

export DEB_BUILD_OPTIONS="parallel=4"

to

export DEB_BUILD_OPTIONS = parallel=4

because when setting the environment variable, make is preserving the quotes in the first version. When make is doing the string interpolation, it makes no practical difference because the quotes get eaten by the shell, but when a subprocess reads the value from an environment, the " characters are preserved.

#!/usr/bin/make -f
export WITH_QUOTES="parallel=3"
export WITHOUT_QUOTES = parallel=3

all: bash -c 'printf "WITH_QUOTES=%q\n" "$$WITH_QUOTES"' bash -c 'printf "WITHOUT_QUOTES=%q\n" "$$WITHOUT_QUOTES"'

bash -c 'printf "WITH_QUOTES=%q\n" "$WITH_QUOTES"'
WITH_QUOTES=\"parallel=3\"
bash -c 'printf "WITHOUT_QUOTES=%q\n" "$WITHOUT_QUOTES"'
WITHOUT_QUOTES=parallel=3

Having the actual value of the environment variable be "parallel=4" not parallel=4 both triggered the warning, and broke this regular expression that dh uses to parse it (note leading ^):

        if ($opt =~ /^parallel=(-?\d+)$/ && $wanted eq 'parallel') {
            return $1;
        }
Dan
  • 383