[build2] Issues when explicitely setting headers to install or not install
Klaim - Joël Lamotte
mjklaim at gmail.com
Mon Jan 7 01:16:00 UTC 2019
Repro cases: https://github.com/Klaim/build2-repro-header-install
See `buildfile` and `observed_output.md` for details.
The goal is to specify what to install or not explicitely.
The linked project builds and install fine, but if you look at the
buildfile, you will see a sequence of scenario leading to some errors
when trying to use `hxx{someheader} : install = some/path`.
These issues were found while trying to build lua, as it's
documentation specifies a specific list of headers to be installed,
even when not used by the lua library itself.
Some of the cases might be because I misunderstand some concepts,
though I assume that there is at least one bug happening and adding to
my confusion here.
I observed other weird behaviors but I think they are all related
to/side-effects of case 1, 2 and 6 below so I didn't not them.
Observed on both windows and ubuntu.
Below is a raw copy of the the report from
https://github.com/Klaim/build2-repro-header-install/blob/master/observed_output.md
(it's easier to read there)
A. Joël Lamotte
-------------------------------
Observed Output:
================
> b --version
build2 0.9.0-a.0.ba8ce9226af0
libbutl 0.9.0-a.0.3bf1846063ad
host x86_64-microsoft-win32-msvc14.1
Copyright (c) 2014-2018 Code Synthesis Ltd
This is free software released under the MIT license.
Note that between each case, we remove the previous case's
modification and use `b clean`.
All the modifications are relative to situation 0 (which is what you
get if you clone this repository).
0 - Library definition (common part)
------------------------------------
`buildfile` is only 2 lines:
./: {*/ -build/} manifest lib{repro}
lib{repro} : hxx{public private}
The headers exist but only have `#pragma once` as content.
There is also a `foruseronly.hxx` header for a later test.
> b
info: ..\build-repro\dir{repro_install_headers\} is up to date
> b install config.install.root=../install/repro/
install manifest{manifest}@..\build-repro\repro_install_headers\
install hxx{public}@..\build-repro\repro_install_headers\
install hxx{private}@..\build-repro\repro_install_headers\
install ..\build-repro\repro_install_headers\pca{repro}
install ..\build-repro\repro_install_headers\pcs{repro}
Both `public.hxx` and `private.hxx` headers are installed, as expected.
1 - Don't install the private header
------------------------------------
We add this line to the buildfile:
hxx{private} : install = false
Then try to build and install:
> b
error: no rule to update ..\build-repro\repro_install_headers\hxx{private}
info: re-run with --verbose 4 for more information
info: while applying rule cxx.link to update
..\build-repro\repro_install_headers\libs{repro}
info: while applying rule bin.lib to update
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule alias to update
..\build-repro\dir{repro_install_headers\}
info: failed to update ..\build-repro\dir{repro_install_headers\}
> b install config.install.root=../install/repro/
install manifest{manifest}@..\build-repro\repro_install_headers\
install hxx{public}@..\build-repro\repro_install_headers\
install ..\build-repro\repro_install_headers\pca{repro}
install ..\build-repro\repro_install_headers\pcs{repro}
As expected, `b install` will not install `private.hxx`, only `public.hxx`.
However we get a weird error when building.
Note also that apparently, updating was not part of installing, which
might be a different bug.
2 - Explicitely state that publich header should be installed
-------------------------------------------------------------
We remove the previous test's line and start again this time with:
hxx{public} : install = include/repro/
This is redundant with the default because we already made this header
a requirement of the library, which implies that this header is
installed by default.
> b
error: no rule to update ..\build-repro\repro_install_headers\hxx{public}
info: re-run with --verbose 4 for more information
info: while applying rule cxx.link to update
..\build-repro\repro_install_headers\liba{repro}
info: while applying rule bin.lib to update
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule alias to update
..\build-repro\dir{repro_install_headers\}
info: failed to update ..\build-repro\dir{repro_install_headers\}
> b install config.install.root=../install/repro/
error: no rule to update (for install)
..\build-repro\repro_install_headers\hxx{public}
info: re-run with --verbose 4 for more information
info: while applying rule install.file to update (for install)
..\build-repro\repro_install_headers\hxx{public}
info: while applying rule cxx.install to update (for install)
..\build-repro\repro_install_headers\liba{repro}
info: while applying rule bin.lib to update (for install)
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule install.alias to update (for install)
..\build-repro\dir{repro_install_headers\}
info: failed to update (for install) ..\build-repro\dir{repro_install_headers\}
Explicitely stating that a header should be installed seems to trigger
this error.
3 - Explicitely state which header to publish or not
----------------------------------------------------
This time we try with a combination, that matches my initial attempt
at making some headers public and some other headers private
explicitely:
hxx{public} : install = include/repro/
hxx{private} : install = false
Then:
> b
error: no rule to update ..\build-repro\repro_install_headers\hxx{public}
info: re-run with --verbose 4 for more information
info: while applying rule cxx.link to update
..\build-repro\repro_install_headers\liba{repro}
info: while applying rule bin.lib to update
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule alias to update
..\build-repro\dir{repro_install_headers\}
error: no rule to update ..\build-repro\repro_install_headers\hxx{private}
info: re-run with --verbose 4 for more information
info: while applying rule cxx.link to update
..\build-repro\repro_install_headers\libs{repro}
info: while applying rule bin.lib to update
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule alias to update
..\build-repro\dir{repro_install_headers\}
info: failed to update ..\build-repro\dir{repro_install_headers\}
> b install config.install.root=../install/repro/
error: no rule to update (for install)
..\build-repro\repro_install_headers\hxx{public}
info: re-run with --verbose 4 for more information
info: while applying rule install.file to update (for install)
..\build-repro\repro_install_headers\hxx{public}
info: while applying rule cxx.install to update (for install)
..\build-repro\repro_install_headers\liba{repro}
info: while applying rule bin.lib to update (for install)
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule install.alias to update (for install)
..\build-repro\dir{repro_install_headers\}
info: failed to update (for install) ..\build-repro\dir{repro_install_headers\}
Both operation fails, but the install seems to fail only for the
public header. This matches previous cases.
4 - Install a header that should only be used by the user
---------------------------------------------------------
This time we keep the default (all headers published, situation 0) but
want to add a header to the install, without it being available to
build the library (some libraries does that, though it's not always an
issue to add these headers to the library requirements):
hxx{foruseronly} : install = include/repro/
Then:
> b
info: ..\build-repro\dir{repro_install_headers\} is up to date
> b install config.install.root=../install/repro/
install manifest{manifest}@..\build-repro\repro_install_headers\
install hxx{public}@..\build-repro\repro_install_headers\
install hxx{private}@..\build-repro\repro_install_headers\
install ..\build-repro\repro_install_headers\pca{repro}
install ..\build-repro\repro_install_headers\pcs{repro}
The header `foruseronly.hxx` is not installed.
I am currently assuming that this is on purpose as the file is never
refered by the build requirements of the directory.
As it is not possible to add a `hxx{somefile}` in the directory
requirement, I suspect the best way to do this is simply to make a
header-only library:
./: {*/ -build/} manifest lib{repro} lib{additional_headers}
lib{repro} : hxx{public private}
lib{additional_headers} : hxx{foruseronly}
In this case all headers are installed.
So this is not a real problem, though I wanted to point it because it
might not be obvious at first attempt to express this.
5 - Install a header with a different extension
-----------------------------------------------
This is required by projects like Lua for example.
Now we want to be able to install a file that is not part of the build.
As we know (see 4.), if we don't require that header, it will not be installed.
lib{repro} : hxx{someapi.hpp}
This works as expected: the file is installed as a header. However we
didn't want to make this file available to the library compilation.
Alternatively:
lib{repro} : file{someapi.hpp}
file{someapi.hpp} : install = include/repro/
Then:
> b
error: no rule to update ..\build-repro\repro_install_headers\file{someapi.hpp}
info: re-run with --verbose 4 for more information
info: while applying rule cxx.link to update
..\build-repro\repro_install_headers\libs{repro}
info: while applying rule bin.lib to update
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule alias to update
..\build-repro\dir{repro_install_headers\}
info: failed to update ..\build-repro\dir{repro_install_headers\}
> b install config.install.root=../install/repro/
error: no rule to update (for install)
..\build-repro\repro_install_headers\file{someapi.hpp}
info: re-run with --verbose 4 for more information
info: while applying rule install.file to update (for install)
..\build-repro\repro_install_headers\file{someapi.hpp}
info: while applying rule cxx.install to update (for install)
..\build-repro\repro_install_headers\liba{repro}
info: while applying rule bin.lib to update (for install)
..\build-repro\repro_install_headers\lib{repro}
info: while applying rule install.alias to update (for install)
..\build-repro\dir{repro_install_headers\}
info: failed to update (for install) ..\build-repro\dir{repro_install_headers\}
This seems to be just a variant of the previous issues.
6 - Install a header with the wrong extension (required by lua) - Take 2
------------------------------------------------------------------------
My first attempts actually were sligthly more sophisticated but still
failing and here is an example:
Let's asssume that we want `someapi.hpp` installed but express it as
in the requirements of the library.
lib{repro} : file{someapi.hpp}
lib{repro} : file{someapi.hpp} : install = include/repro/
Then:
> b
info: ..\build-repro\dir{repro_install_headers\} is up to date
> b install config.install.root=../install/repro/
install manifest{manifest}@..\build-repro\repro_install_headers\
install hxx{public}@..\build-repro\repro_install_headers\
install hxx{private}@..\build-repro\repro_install_headers\
install ..\build-repro\repro_install_headers\pca{repro}
install ..\build-repro\repro_install_headers\pcs{repro}
No error, but `someapi.hpp` not installed.
More information about the users
mailing list