All of lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [RFCv2 0/7] Per-package SDK and target directories
@ 2017-11-24 16:46 Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 1/7] pkgconf: use relative path to STAGING_DIR instead of absolute path Thomas Petazzoni
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

Hello,

Here is a second iteration of the per-package SDK and target directory
implementation. This is definitely not ready for merging, but it
already works enough to give it some exposure. I'm sending it early so
that:

 - Interested people can take the patches, try them on their
   configurations, and report me the problems that they face.

 - Interested people start reviewing the patch series will it is still
   small and simple, because I'm sure it will grow quite a bit before
   it gets to a point where it can be merged.

If you're interested in testing it, you can find the patch series at:

  http://git.free-electrons.com/users/thomas-petazzoni/buildroot/log/?h=ppsh-v2

Note: in the following discussion, we use the terminology "SDK" to
refer to the combination of HOST_DIR and STAGING_DIR, i.e the
cross-compiler and its sysroot with target libraries/headers, and a
bunch of other native programs. Since STAGING_DIR is included inside
HOST_DIR, the SDK directory is in essence just HOST_DIR.

Changes since v1
================

 - Rebased on the latest Buildroot next branch

 - The pkg-config changes are reworked according to Arnout's comments:
   only @STAGING_SUBDIR@ is replaced in pkg-config.in to generate
   pkg-config, the rest of the logic is internal to the script.

 - New patch to move the "host skeleton" logic into a proper
   host-skeleton package.

 - New patch to have the CMake related files generated as part of the
   toolchain package.

 - New patch to add a new "install" step that depends on the different
   install steps (target, staging, images, host). This is needed to
   later add some logic that is executed once all install steps of a
   package have been done.

 - Fix the approach to solve the RPATH logic: instead of using
   LD_LIBRARY_PATH, we actually fix with patchelf the RPATH of host
   binaries right after their installation.

 - Misc other improvements in the per-package SDK implementation.

What is per-package SDK and target?
===================================

Currently, output/host (SDK) and output/target are global directories:
all packages use files installed by other packages in those global
directories, and in turn into those global directories.

The idea of per-package SDK and target is that instead of having such
global directories, we would have one SDK directory and one target
directory per-package, containing just what this package needs
(dependencies), and in which the package installs its files.

Why do we want per-package SDK and target?
==========================================

There are two main motivations for per-package SDK and target
directories, which are related:

 1. Since the SDK directory is global, a package can currently see
    libraries/headers that it has not explicitly expressed a
    dependency on. So package A may not have a dependency on package
    B, but if package B happens to have been installed before, and
    package A "configure" script automaticatically detects a library
    installed by package B, it will use it. We have added tons of
    conditional dependencies in Buildroot to make such situations less
    problematic, but it is an endless fight, as upstream developers
    constantly add more optional dependencies to their software.

    Using per-package SDK, a given package uses as its SDK a directory
    that only contains the libraries/headers from packages explicitly
    listed in its dependencies. So it cannot mistakenly see a
    library/header installed by another package.

 2. Top-level parallel build (building multiple packages in parallel)
    is currently not enabled because we have global SDK and target
    directories.

    Let's imagine package A configure script auto-detects a library
    provided by package B, but Buildroot does not encode this
    dependency in package A's .mk file. Package A and package B are
    therefore totally independent from a build dependency point of
    view.

    Without top-level parallel build (current situation), you have a
    guarantee on the build order: either A is always built before B,
    or B is always built before A. So at least, every build gives the
    same result: A is built with B's functionality or without it, but
    it is consistent accross rebuilds.

    If you enable top-level parallel build, because A and B are
    totally independent, you can get A built before B or B built
    before A depending on the build scheduling. This can change at
    every build! This means that for a given configuration, A will
    sometimes be built with B's functionality, sometimes not. Totally
    unacceptable.

    And of course, this extends to case where package B gets installed
    while package A is being configured. So package A configure script
    will see some parts of B being installed, other parts not
    installed, causing all sort of weird and difficult to debug race
    conditions.

    By having per-package SDK directories, we ensure that package A
    will only see the dependencies its has explicitly expressed, and
    that no other package gets installed in parallel in the same SDK
    directory.

How is it implemented?
======================

The basic idea is pretty simple:

 - For each package, we have:

   output/per-package/<package>/host, which is the specific SDK
   directory for <package>.

   output/per-package/<package>/target, which is the specific target
   directory for <package>.

 - Before <package> is configured, we copy into its specific SDK and
   target directories the SDK and target directories from its direct
   dependencies. This basically populates its SDK with the
   cross-compiler and all libraries that <package> needs. This copy is
   done using rsync with hard links, so it is very fast and cheap from
   a storage consumption point of view.

 - While <package> is being built, HOST_DIR, STAGING_DIR and
   TARGET_DIR are tweaked to point to the current <package> specific
   SDK and target directories. I.e, HOST_DIR no longer points to
   output/host, but to output/per-package/<package>/host/.

And this is basically enough to get things working!

There are of course a few additional things to do:

 - At the end of the build, we still want a global target directory
   (to generate the filesystem images) and a global SDK. Therefore, in
   target-finalize, we assemble such global directories by copying the
   per-package SDK and target directories from all packages listed in
   the $(PACKAGES) variable.

 - We need to fix our pkg-config wrapper script so that it uses
   relative path instead of absolute paths. This allows the wrapper
   script to work regardless of which per-package SDK directory it is
   installed in.

 - We need to move away from using absolute RPATH for host binaries,
   and to achieve that we fix the RPATH to $ORIGIN/../lib in host
   binaries right after the installation of each package.

What remains to be done?
========================

 - Completely get rid of the global HOST_DIR, TARGET_DIR and
   STAGING_DIR definitions, so that nothing uses them, and they really
   become per-package variables.

 - While the toolchain sysroot, pkg-config paths and host RPATHs are
   properly handled, there are quite certainly a lot of other places
   that have absolute paths that won't work well with per-package SDK,
   and that need to be adjusted.

 - Perhaps use a temporary per-package SDK and target directory when
   building a package, and rename it to the final name once the
   package has finished building. This would allow to detect
   situations where the per-package SDK directory of package A
   contains absolute paths referring to the per-package SDK directory
   of package B. Such absolute paths are wrong, but we currently don't
   see them because the per-package SDK directory for package B still
   exists.

 - Think about what needs to be done about the output/images/
   folder. Should it also be per-package like we do for output/target?

 - Handle host-lzip, host-tar and host-ccache properly, as well as
   PATCH_DEPENDENCIES.

 - Many other issues that I'm sure people will report.

Comparison with Gustavo's patch series
======================================

Gustavo Zacarias did a previous implementation of this, available in
http://repo.or.cz/buildroot-gz.git/shortlog/refs/heads/pps3-next. Compared
to Gustavo's patch series, this patch series:

 - Implement per-package SDK and target directories, while Gustavo was
   only doing per-package staging.

 - Gustavo had several patches to pass BR_TOOLCHAIN_SYSROOT to the
   toolchain wrapper to pass the location of the current sysroot.

   This is no longer needed, because 1/ we're doing a full per-package
   SDK directory rather than per-package staging, which means the
   sysroot is always at the same relative location compared to the
   cross-compiler binary and 2/ the toolchain wrapper derives the
   sysroot location relatively to the wrapper location. Thanks to
   this, the following patches from Gustavo are (I believe) not
   needed:

   http://repo.or.cz/buildroot-gz.git/commitdiff/1ef6e798064649726d396bcb581ddbe4573c2460
   http://repo.or.cz/buildroot-gz.git/commitdiff/d15f6c6917b555bbbbbf97c292fad4db9d4007d4
   http://repo.or.cz/buildroot-gz.git/commitdiff/95900b65c29a010d85a769c9c6374cf3835f2169
   http://repo.or.cz/buildroot-gz.git/commitdiff/7ed53a5437ab09b85bf6d1953f6ff6049dfcc114

 - Gustavo had a patch to make our pkg-config wrapper script look at
   BR_TOOLCHAIN_SYSROOT, in order to find the
   /usr/{lib,share}/pkgconfig folders of the current sysroot. Just
   like for the toolchain-wrapper, such a change is no longer needed,
   and a simple change to our pkg-config script to use relative paths
   is sufficient.

 - I haven't integrated Gustavo patches that move from $(shell ...) to
   using backticks to delay the evaluation of
   STAGING_DIR/HOST_DIR/TARGET_DIR:

   http://repo.or.cz/buildroot-gz.git/commitdiff/0c11c60865f1445830643bb404f92c20d563260c
   http://repo.or.cz/buildroot-gz.git/commitdiff/207d2248ec8542293b6201b5c86f971021a3a591
   http://repo.or.cz/buildroot-gz.git/commitdiff/7f6a69819fbb176e29a1c3a53b4a76efe87dad15
   http://repo.or.cz/buildroot-gz.git/commitdiff/3328a9745eee555f5e5ef7df835afc26612ecd7b
   http://repo.or.cz/buildroot-gz.git/commitdiff/45a9d8c2aa6f3c0d2d8ed989d843890025faa3e8

 - I haven't looked at Qt specific issues, such as the ones fixed by
   Gustavo in:

   http://repo.or.cz/buildroot-gz.git/commitdiff/643e982e635f4386ccefcda9da4b84536af84d04

 - I am not doing all the .la files, *-config, *.prl, etc. tweaks that
   Gustavo is doing in:

   http://repo.or.cz/buildroot-gz.git/commitdiff/3f7b227b4c8e4514df6e5d54f88fcfb3a3a4bae0

   It is part of the "remaining absolute paths that need to be fixed"
   item that I mentionned above.

Best regards,

Thomas

Thomas Petazzoni (7):
  pkgconf: use relative path to STAGING_DIR instead of absolute path
  toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN
  Makefile, skeleton: move the host skeleton logic to host-skeleton
    package
  pkg-cmake: install CMake files as part of a package
  pkg-generic: add .stamp_installed step
  core: change host RPATH handling
  core: implement per-package SDK and target

 Makefile                                           | 34 +++++------
 package/Makefile.in                                |  2 +-
 package/pkg-cmake.mk                               | 12 ++--
 package/pkg-generic.mk                             | 71 ++++++++++++++--------
 package/pkgconf/pkg-config.in                      |  5 +-
 package/pkgconf/pkgconf.mk                         |  3 +-
 package/skeleton/skeleton.mk                       | 12 ++++
 support/scripts/fix-rpath                          | 31 ++++++----
 .../toolchain-external/pkg-toolchain-external.mk   |  2 +-
 toolchain/toolchain/toolchain.mk                   |  3 -
 10 files changed, 108 insertions(+), 67 deletions(-)

-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 1/7] pkgconf: use relative path to STAGING_DIR instead of absolute path
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 2/7] toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN Thomas Petazzoni
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

The pkg-config wrapper script is currently generated with absolute
paths to $(STAGING_DIR). However, this will not work properly with
per-package SDK, and each package will be built with a different
STAGING_DIR value.

In order to fix this, we adjust how the pkg-config wrapper script is
generated, so that it uses a relative path to itself: the sysroot (i.e
STAGING_DIR) is always located in $(path of
pkg-config)/../$(STAGING_SUBDIR).

This change is independent from the per-package SDK work, and could be
applied independently from it.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
Changes since v1:
 - As suggested by Arnout, simplify the generation of the pkg-config
   script by doing only a replacement on @STAGING_SUBDIR@, the rest
   being encoded inside the pkg-config script.
---
 package/pkgconf/pkg-config.in | 5 ++++-
 package/pkgconf/pkgconf.mk    | 3 +--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/package/pkgconf/pkg-config.in b/package/pkgconf/pkg-config.in
index 4dec48789a..b9ce0935cc 100644
--- a/package/pkgconf/pkg-config.in
+++ b/package/pkgconf/pkg-config.in
@@ -1,2 +1,5 @@
 #!/bin/sh
-PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:- at PKG_CONFIG_LIBDIR@} PKG_CONFIG_SYSROOT_DIR=${PKG_CONFIG_SYSROOT_DIR:- at STAGING_DIR@} $(dirname $0)/pkgconf @STATIC@ $@
+PKGCONFDIR=$(dirname $0)
+DEFAULT_PKG_CONFIG_LIBDIR=${PKGCONFDIR}/../@STAGING_SUBDIR@/usr/lib/pkgconfig:${PKGCONFDIR}/../@STAGING_SUBDIR@/usr/share/pkgconfig
+DEFAULT_PKG_CONFIG_SYSROOT_DIR=${PKGCONFDIR}/../@STAGING_SUBDIR@
+PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:-${DEFAULT_PKG_CONFIG_LIBDIR}} PKG_CONFIG_SYSROOT_DIR=${PKG_CONFIG_SYSROOT_DIR:-${DEFAULT_PKG_CONFIG_SYSROOT_DIR}} ${PKGCONFDIR}/pkgconf @STATIC@ $@
diff --git a/package/pkgconf/pkgconf.mk b/package/pkgconf/pkgconf.mk
index cc190d26da..00b2d017ee 100644
--- a/package/pkgconf/pkgconf.mk
+++ b/package/pkgconf/pkgconf.mk
@@ -19,8 +19,7 @@ endef
 define HOST_PKGCONF_INSTALL_WRAPPER
 	$(INSTALL) -m 0755 -D package/pkgconf/pkg-config.in \
 		$(HOST_DIR)/bin/pkg-config
-	$(SED) 's, at PKG_CONFIG_LIBDIR@,$(STAGING_DIR)/usr/lib/pkgconfig:$(STAGING_DIR)/usr/share/pkgconfig,' \
-		-e 's, at STAGING_DIR@,$(STAGING_DIR),' \
+	$(SED) 's, at STAGING_SUBDIR@,$(STAGING_SUBDIR),g' \
 		$(HOST_DIR)/bin/pkg-config
 endef
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 2/7] toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 1/7] pkgconf: use relative path to STAGING_DIR instead of absolute path Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package Thomas Petazzoni
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

The upcoming per-package SDK functionality is heavily based on the
fact that HOST_DIR, STAGING_DIR and TARGET_DIR are evaluated during
the configure/build/install steps of the packages. Therefore, any
evaluation-during-assignment using := is going to cause problems, and
need to be turned into evaluation-during-use using =.

This patch fix up one such instance in the external toolchain code.

This change is independent from the per-package SDK functionality, and
could be applied separately.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes since v1:
 - Added Arnout Reviewed-by.
---
 toolchain/toolchain-external/pkg-toolchain-external.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/toolchain/toolchain-external/pkg-toolchain-external.mk b/toolchain/toolchain-external/pkg-toolchain-external.mk
index dc0588c536..b9ad1720a1 100644
--- a/toolchain/toolchain-external/pkg-toolchain-external.mk
+++ b/toolchain/toolchain-external/pkg-toolchain-external.mk
@@ -77,7 +77,7 @@ ifneq ($(TOOLCHAIN_EXTERNAL_PREFIX),)
 TOOLCHAIN_EXTERNAL_BIN := $(dir $(shell which $(TOOLCHAIN_EXTERNAL_PREFIX)-gcc))
 endif
 else
-TOOLCHAIN_EXTERNAL_BIN := $(TOOLCHAIN_EXTERNAL_INSTALL_DIR)/bin
+TOOLCHAIN_EXTERNAL_BIN = $(TOOLCHAIN_EXTERNAL_INSTALL_DIR)/bin
 endif
 
 # If this is a buildroot toolchain, it already has a wrapper which we want to
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 1/7] pkgconf: use relative path to STAGING_DIR instead of absolute path Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 2/7] toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-25 19:46   ` Baruch Siach
  2017-11-24 16:46 ` [Buildroot] [RFCv2 4/7] pkg-cmake: install CMake files as part of a package Thomas Petazzoni
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

As part of the per-package SDK work, we want to avoid having logic
that installs files to the global HOST_DIR, and instead do it inside
packages. One thing that gets installed to the global HOST_DIR is the
minimal "skeleton" that we create in host:

 - the "usr" symbolic link for backward compatibility

 - the "lib" directory, and its lib64 or lib32 symbolic links

This commit moves this logic to a new host-skeleton package, and makes
all packages (except itself) depend on it. We also make sure that this
host-skeleton package doesn't depend on host-patchelf, because
host-patchelf depends on host-skeleton.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
Changes since v1:
 - New patch
---
 Makefile                     | 13 +------------
 package/pkg-generic.mk       |  4 ++++
 package/skeleton/skeleton.mk | 12 ++++++++++++
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile
index 55409b99af..193864a0df 100644
--- a/Makefile
+++ b/Makefile
@@ -544,7 +544,7 @@ endif
 
 .PHONY: dirs
 dirs: $(BUILD_DIR) $(STAGING_DIR) $(TARGET_DIR) \
-	$(HOST_DIR) $(HOST_DIR)/usr $(HOST_DIR)/lib $(BINARIES_DIR)
+	$(HOST_DIR) $(BINARIES_DIR)
 
 $(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG)
 	$(MAKE1) $(EXTRAMAKEARGS) HOSTCC="$(HOSTCC_NOCCACHE)" HOSTCXX="$(HOSTCXX_NOCCACHE)" silentoldconfig
@@ -563,17 +563,6 @@ sdk: world
 	$(INSTALL) -m 755 $(TOPDIR)/support/misc/relocate-sdk.sh $(HOST_DIR)/relocate-sdk.sh
 	echo $(HOST_DIR) > $(HOST_DIR)/share/buildroot/sdk-location
 
-# Compatibility symlink in case a post-build script still uses $(HOST_DIR)/usr
-$(HOST_DIR)/usr: $(HOST_DIR)
-	@ln -snf . $@
-
-$(HOST_DIR)/lib: $(HOST_DIR)
-	@mkdir -p $@
-	@case $(HOSTARCH) in \
-		(*64) ln -snf lib $(@D)/lib64;; \
-		(*)   ln -snf lib $(@D)/lib32;; \
-	esac
-
 # Populating the staging with the base directories is handled by the skeleton package
 $(STAGING_DIR):
 	@mkdir -p $(STAGING_DIR)
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index 0e28675fbe..574a5861d0 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -564,6 +564,10 @@ $(2)_DEPENDENCIES += toolchain
 endif
 endif
 
+ifneq ($(1),host-skeleton)
+$(2)_DEPENDENCIES += host-skeleton
+endif
+
 # Eliminate duplicates in dependencies
 $(2)_FINAL_DEPENDENCIES = $$(sort $$($(2)_DEPENDENCIES))
 $(2)_FINAL_PATCH_DEPENDENCIES = $$(sort $$($(2)_PATCH_DEPENDENCIES))
diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk
index d380f41649..a32bacd0b3 100644
--- a/package/skeleton/skeleton.mk
+++ b/package/skeleton/skeleton.mk
@@ -11,4 +11,16 @@
 SKELETON_ADD_TOOLCHAIN_DEPENDENCY = NO
 SKELETON_ADD_SKELETON_DEPENDENCY = NO
 
+# We create a compatibility symlink in case a post-build script still
+# uses $(HOST_DIR)/usr
+define HOST_SKELETON_INSTALL_CMDS
+	@ln -snf . $(HOST_DIR)/usr
+	@mkdir -p $(HOST_DIR)/lib
+	@case $(HOSTARCH) in \
+		(*64) ln -snf lib $(HOST_DIR)/lib64;; \
+		(*)   ln -snf lib $(HOST_DIR)/lib32;; \
+	esac
+endef
+
 $(eval $(virtual-package))
+$(eval $(host-generic-package))
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 4/7] pkg-cmake: install CMake files as part of a package
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
                   ` (2 preceding siblings ...)
  2017-11-24 16:46 ` [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 5/7] pkg-generic: add .stamp_installed step Thomas Petazzoni
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

Currently, the toolchainfile.cmake and Buildroot.cmake files are
installed outside of any package, just triggered by the toolchain
target.

As part of the per-package SDK effort, we are trying to avoid anything
that installs to the global $(HOST_DIR), and this is one of the
remaining files installed in $(HOST_DIR) outside of any package. We
fix this by installing such files as part of the toolchain package
post-install staging hooks.

Yes, a post-install staging hook to install things to $(HOST_DIR) is a
bit weird, but the toolchain infrastructure is made of target packages
only, and they all install a lot of stuff to $(HOST_DIR) already.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
Changes since v1:
 - New patch
---
 package/pkg-cmake.mk             | 12 +++++++-----
 toolchain/toolchain/toolchain.mk |  3 ---
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/package/pkg-cmake.mk b/package/pkg-cmake.mk
index db78d897d8..07980a1eb1 100644
--- a/package/pkg-cmake.mk
+++ b/package/pkg-cmake.mk
@@ -244,8 +244,8 @@ endif
 # based on the toolchainfile.cmake file's location: $(HOST_DIR)/share/buildroot
 # In all the other variables, HOST_DIR will be replaced by RELOCATED_HOST_DIR,
 # so we have to strip "$(HOST_DIR)/" from the paths that contain it.
-$(HOST_DIR)/share/buildroot/toolchainfile.cmake:
-	@mkdir -p $(@D)
+define TOOLCHAIN_CMAKE_INSTALL_FILES
+	@mkdir -p $(HOST_DIR)/share/buildroot
 	sed \
 		-e 's#@@STAGING_SUBDIR@@#$(call qstrip,$(STAGING_SUBDIR))#' \
 		-e 's#@@TARGET_CFLAGS@@#$(call qstrip,$(TARGET_CFLAGS))#' \
@@ -259,7 +259,9 @@ $(HOST_DIR)/share/buildroot/toolchainfile.cmake:
 		-e 's#@@TOOLCHAIN_HAS_FORTRAN@@#$(if $(BR2_TOOLCHAIN_HAS_FORTRAN),1,0)#' \
 		-e 's#@@CMAKE_BUILD_TYPE@@#$(if $(BR2_ENABLE_DEBUG),Debug,Release)#' \
 		$(TOPDIR)/support/misc/toolchainfile.cmake.in \
-		> $@
+		> $(HOST_DIR)/share/buildroot/toolchainfile.cmake
+	$(Q)$(INSTALL) -D -m 0644 support/misc/Buildroot.cmake \
+		$(HOST_DIR)/share/buildroot/Platform/Buildroot.cmake
+endef
 
-$(HOST_DIR)/share/buildroot/Platform/Buildroot.cmake:
-	$(Q)$(INSTALL) -D -m 0644 support/misc/Buildroot.cmake $(@)
+TOOLCHAIN_POST_INSTALL_STAGING_HOOKS += TOOLCHAIN_CMAKE_INSTALL_FILES
diff --git a/toolchain/toolchain/toolchain.mk b/toolchain/toolchain/toolchain.mk
index b55b0c712c..283e0a74ee 100644
--- a/toolchain/toolchain/toolchain.mk
+++ b/toolchain/toolchain/toolchain.mk
@@ -38,6 +38,3 @@ TOOLCHAIN_INSTALL_STAGING = YES
 endif
 
 $(eval $(virtual-package))
-
-toolchain: $(HOST_DIR)/share/buildroot/toolchainfile.cmake
-toolchain: $(HOST_DIR)/share/buildroot/Platform/Buildroot.cmake
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 5/7] pkg-generic: add .stamp_installed step
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
                   ` (3 preceding siblings ...)
  2017-11-24 16:46 ` [Buildroot] [RFCv2 4/7] pkg-cmake: install CMake files as part of a package Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 6/7] core: change host RPATH handling Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 7/7] core: implement per-package SDK and target Thomas Petazzoni
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

The installation to target, staging and images as well as the host
installation are all done in 4 different make targets. We don't have
any place currently to run something at the end of a package
installation, i.e once all of target/staging/images (for target) or
host (for host) installation have completed.

We will need such a step to fix the RPATH of binaries in the host
directory. Indeed, while normally only host packages should install
things in $(HOST_DIR), in practice a number of target packages (ex:
qt4, qt5base) do install things in $(HOST_DIR).

Therefore, we want to run our RPATH fixing logic at the end of all
installation steps. To achieve this, this commit introduces a new make
target, .stamp_installed, which depends on
.stamp_{target,staging,images}_installed for target packages and
.stamp_host_installed for host packages.

This new step currently doesn't do anything, but the actual logic is
added in a follow-up commit.

This change in fact makes the overall step sequencing more logical:
for all steps the dependencies were done on the stamp file targets,
except for the install step where we were using phony targets to make
$(1)-install depends on $(1)-install-{target,staging,images,host}. So
now, the phony targets $(1)-install-{target,staging,images,host} are
only human-readable targets that are shortcuts to the corresponding
stamp file targets, and not usded anymore for the step
sequencing. This makes them more consistent with the other phony
$(1)-{build,configure,patch,...} phony targets.

It also makes $(1)-install-host more consistent with other phony
targets: $(1)-install-target only existed if the package had
<pkg>_INSTALL_TARGET = YES, but $(1)-install-host existed
unconditionally. Now it only exists if it's a host package.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
Changes since v1:
 - New patch.
---
 package/pkg-generic.mk | 44 +++++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index 574a5861d0..28bd4ba6a8 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -327,6 +327,12 @@ $(BUILD_DIR)/%/.stamp_target_installed:
 	@$(call step_end,install-target)
 	$(Q)touch $@
 
+# Finalize installation
+$(BUILD_DIR)/%/.stamp_installed:
+	@$(call step_start,install)
+	@$(call step_end,install)
+	$(Q)touch $@
+
 # Remove package sources
 $(BUILD_DIR)/%/.stamp_dircleaned:
 	rm -Rf $(@D)
@@ -582,6 +588,7 @@ $(2)_TARGET_INSTALL_TARGET =	$$($(2)_DIR)/.stamp_target_installed
 $(2)_TARGET_INSTALL_STAGING =	$$($(2)_DIR)/.stamp_staging_installed
 $(2)_TARGET_INSTALL_IMAGES =	$$($(2)_DIR)/.stamp_images_installed
 $(2)_TARGET_INSTALL_HOST =      $$($(2)_DIR)/.stamp_host_installed
+$(2)_TARGET_INSTALL =      	$$($(2)_DIR)/.stamp_installed
 $(2)_TARGET_BUILD =		$$($(2)_DIR)/.stamp_built
 $(2)_TARGET_CONFIGURE =		$$($(2)_DIR)/.stamp_configured
 $(2)_TARGET_RSYNC =	        $$($(2)_DIR)/.stamp_rsynced
@@ -629,38 +636,40 @@ $(2)_ROOTFS_POST_CMD_HOOKS      ?=
 # human-friendly targets and target sequencing
 $(1):			$(1)-install
 
+$(1)-install:			$$($(2)_TARGET_INSTALL)
+
 ifeq ($$($(2)_TYPE),host)
-$(1)-install:	        $(1)-install-host
-else
-$(1)-install:		$(1)-install-staging $(1)-install-target $(1)-install-images
-endif
+
+$(1)-install-host:		$$($(2)_TARGET_INSTALL_HOST)
+$$($(2)_TARGET_INSTALL):	$$($(2)_TARGET_INSTALL_HOST)
+
+else # host vs. target
 
 ifeq ($$($(2)_INSTALL_TARGET),YES)
 $(1)-install-target:		$$($(2)_TARGET_INSTALL_TARGET)
-$$($(2)_TARGET_INSTALL_TARGET):	$$($(2)_TARGET_BUILD)
-else
-$(1)-install-target:
+$$($(2)_TARGET_INSTALL):	$$($(2)_TARGET_INSTALL_TARGET)
 endif
 
 ifeq ($$($(2)_INSTALL_STAGING),YES)
-$(1)-install-staging:			$$($(2)_TARGET_INSTALL_STAGING)
-$$($(2)_TARGET_INSTALL_STAGING):	$$($(2)_TARGET_BUILD)
-# Some packages use install-staging stuff for install-target
-$$($(2)_TARGET_INSTALL_TARGET):		$$($(2)_TARGET_INSTALL_STAGING)
-else
-$(1)-install-staging:
+$(1)-install-staging:		$$($(2)_TARGET_INSTALL_STAGING)
+$$($(2)_TARGET_INSTALL):	$$($(2)_TARGET_INSTALL_STAGING)
 endif
 
 ifeq ($$($(2)_INSTALL_IMAGES),YES)
 $(1)-install-images:		$$($(2)_TARGET_INSTALL_IMAGES)
-$$($(2)_TARGET_INSTALL_IMAGES):	$$($(2)_TARGET_BUILD)
-else
-$(1)-install-images:
+$$($(2)_TARGET_INSTALL):	$$($(2)_TARGET_INSTALL_IMAGES)
 endif
 
-$(1)-install-host:		$$($(2)_TARGET_INSTALL_HOST)
+endif # host vs.target
+
+$$($(2)_TARGET_INSTALL_TARGET):	$$($(2)_TARGET_BUILD)
+$$($(2)_TARGET_INSTALL_STAGING):$$($(2)_TARGET_BUILD)
+$$($(2)_TARGET_INSTALL_IMAGES):	$$($(2)_TARGET_BUILD)
 $$($(2)_TARGET_INSTALL_HOST):	$$($(2)_TARGET_BUILD)
 
+# Some packages use install-staging stuff for install-target
+$$($(2)_TARGET_INSTALL_TARGET):		$$($(2)_TARGET_INSTALL_STAGING)
+
 $(1)-build:		$$($(2)_TARGET_BUILD)
 $$($(2)_TARGET_BUILD):	$$($(2)_TARGET_CONFIGURE)
 
@@ -800,6 +809,7 @@ $(1)-reconfigure:	$(1)-clean-for-reconfigure $(1)
 
 # define the PKG variable for all targets, containing the
 # uppercase package variable prefix
+$$($(2)_TARGET_INSTALL):		PKG=$(2)
 $$($(2)_TARGET_INSTALL_TARGET):		PKG=$(2)
 $$($(2)_TARGET_INSTALL_STAGING):	PKG=$(2)
 $$($(2)_TARGET_INSTALL_IMAGES):		PKG=$(2)
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 6/7] core: change host RPATH handling
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
                   ` (4 preceding siblings ...)
  2017-11-24 16:46 ` [Buildroot] [RFCv2 5/7] pkg-generic: add .stamp_installed step Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  2017-11-24 16:46 ` [Buildroot] [RFCv2 7/7] core: implement per-package SDK and target Thomas Petazzoni
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

Currently, our strategy for the RPATH of host binaries is as follows:

 - During the build, we force an absolute RPATH to be encoded into
   binaries, by passing -Wl,-rpath,$(HOST_DIR)/lib. This ensures that
   host binaries will find their libraries.

 - In the "make sdk" target, when preparing the SDK to be relocatable,
   we use patchelf to replace those absolute RPATHs by relative RPATHs
   that use $ORIGIN.

Unfortunately, the use of absolute RPATH during the build is not
compatible with the move to per-package SDK, where a different host
directory is used for the build of each package. Therefore, we need to
move to a different strategy for RPATH handling.

The new strategy is as follows:

 - We no longer pass -Wl,-rpath,$(HOST_DIR)/lib when building
   packages, so the host binaries no longer have any rpath encoded.

 - At the end of the installation of every package, we just the
   fix-rpath logic on the host binaries, so that all host binaries
   that don't already have $ORIGIN/../lib as their RPATH are updated
   to have such a RPATH.

In order to achieve this, the following changes are made:

 - HOST_LDFLAGS no longer contains -Wl,-rpath,$(HOST_DIR)

 - The hook that ran at the end of every package installation
   (check_host_rpath) to verify that our hardcoded RPATH is indeed
   present in all binaries is removed, as it is no longer needed: we
   will force $ORIGIN/../LIB as an RPATH in all binaries.

 - host-patchelf is added as a dependency of all packages, except
   itself. This is necessary as all packages now need to run patchelf
   at the end of their installation process.

   TODO: things like host-tar, host-lzip and host-ccache will have to
   be handled properly.

 - "fix-rpath host" is called at the end of the package installation,
   in the recently introduced .stamp_installed, which guarantees to be
   executed after all of target, staging, images and host
   installations have completed. Indeed, while in theory only host
   packages install files into $(HOST_DIR), in practice a number of
   target packages also install host binaries. So to be reliable, we
   do the "fix-rpath host" logic at the end of the installation of
   every package.

 - The fix-rpath script is modified:

   * The "host" target now simply hardcodes setting $ORIGIN/../lib as
     an RPATH, instead of using --relative-to-file

   * We simply exclude the patchelf program instead of making a copy
     of it: since patchelf depends only on the C/C++ libraries, it
     doesn't need to have a RPATH set to $ORIGIN/../lib

   * Also, in order to avoid re-writing host binaries over and over
     again, we only set the RPATH if it is not already set.

This change is independent from the per-package SDK functionality, and
could be applied separately.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
NOTE: an alternative to running "fix-rpath host" at the end of every
package installation would be to run it only for host packages
(unconditionally) and have a special flag that target packages can use
to indicate that they have installed things to $(HOST_DIR). Not sure
if this is worth the complexity, though.

NOTE2: is it OK to force $ORIGIN/../lib as the RPATH of all host
binaries? This is OK for binaries in host/{bin,sbin} of course, but do
we have host binaries in other places, for which this $ORIGIN/../lib
RPATH wouldn't be appropriate?

Changes since v1:
 - Following the feedback from Yann and Arnout, the approach in v2 was
   completely changed: instead of using LD_LIBRARY_PATH, we now run
   patchelf at the end of each package installation to fix the RPATH.
---
 Makefile                  |  1 -
 package/Makefile.in       |  2 +-
 package/pkg-generic.mk    | 14 ++++++--------
 support/scripts/fix-rpath | 31 +++++++++++++++++++------------
 4 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/Makefile b/Makefile
index 193864a0df..f32fde7a68 100644
--- a/Makefile
+++ b/Makefile
@@ -558,7 +558,6 @@ world: target-post-image
 .PHONY: sdk
 sdk: world
 	@$(call MESSAGE,"Rendering the SDK relocatable")
-	$(TOPDIR)/support/scripts/fix-rpath host
 	$(TOPDIR)/support/scripts/fix-rpath staging
 	$(INSTALL) -m 755 $(TOPDIR)/support/misc/relocate-sdk.sh $(HOST_DIR)/relocate-sdk.sh
 	echo $(HOST_DIR) > $(HOST_DIR)/share/buildroot/sdk-location
diff --git a/package/Makefile.in b/package/Makefile.in
index a1a5316051..e94a75c230 100644
--- a/package/Makefile.in
+++ b/package/Makefile.in
@@ -220,7 +220,7 @@ HOST_CPPFLAGS  = -I$(HOST_DIR)/include
 HOST_CFLAGS   ?= -O2
 HOST_CFLAGS   += $(HOST_CPPFLAGS)
 HOST_CXXFLAGS += $(HOST_CFLAGS)
-HOST_LDFLAGS  += -L$(HOST_DIR)/lib -Wl,-rpath,$(HOST_DIR)/lib
+HOST_LDFLAGS  += -L$(HOST_DIR)/lib
 
 # The macros below are taken from linux 4.11 and adapted slightly.
 # Copy more when needed.
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index 28bd4ba6a8..5b32bdf722 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -105,14 +105,6 @@ endef
 
 GLOBAL_INSTRUMENTATION_HOOKS += check_bin_arch
 
-# This hook checks that host packages that need libraries that we build
-# have a proper DT_RPATH or DT_RUNPATH tag
-define check_host_rpath
-	$(if $(filter install-host,$(2)),\
-		$(if $(filter end,$(1)),support/scripts/check-host-rpath $(3) $(HOST_DIR)))
-endef
-GLOBAL_INSTRUMENTATION_HOOKS += check_host_rpath
-
 define step_check_build_dir_one
 	if [ -d $(2) ]; then \
 		printf "%s: installs files in %s\n" $(1) $(2) >&2; \
@@ -330,6 +322,8 @@ $(BUILD_DIR)/%/.stamp_target_installed:
 # Finalize installation
 $(BUILD_DIR)/%/.stamp_installed:
 	@$(call step_start,install)
+	$(if $(filter host-patchelf,$($(PKG)_FINAL_DEPENDENCIES)), \
+		$(TOPDIR)/support/scripts/fix-rpath host)
 	@$(call step_end,install)
 	$(Q)touch $@
 
@@ -574,6 +568,10 @@ ifneq ($(1),host-skeleton)
 $(2)_DEPENDENCIES += host-skeleton
 endif
 
+ifeq ($(filter host-patchelf host-skeleton,$(1)),)
+$(2)_DEPENDENCIES += host-patchelf
+endif
+
 # Eliminate duplicates in dependencies
 $(2)_FINAL_DEPENDENCIES = $$(sort $$($(2)_DEPENDENCIES))
 $(2)_FINAL_PATCH_DEPENDENCIES = $$(sort $$($(2)_PATCH_DEPENDENCIES))
diff --git a/support/scripts/fix-rpath b/support/scripts/fix-rpath
index 15705a3b0d..5b2f24ed32 100755
--- a/support/scripts/fix-rpath
+++ b/support/scripts/fix-rpath
@@ -61,7 +61,7 @@ main() {
     local rootdir
     local tree="${1}"
     local find_args=( )
-    local sanitize_extra_args=( )
+    local sanitize_args=( )
 
     if ! "${PATCHELF}" --version > /dev/null 2>&1; then
 	echo "Error: can't execute patchelf utility '${PATCHELF}'"
@@ -84,12 +84,14 @@ main() {
                 find_args+=( "-path" "${HOST_DIR}""${excludepath}" "-prune" "-o" )
             done
 
-            # do not process the patchelf binary but a copy to work-around "file in use"
+            # do not process the patchelf binary, as it is ourselves
+            # (and it doesn't need a rpath as it doesn't use libraries
+            # from HOST_DIR)
             find_args+=( "-path" "${PATCHELF}" "-prune" "-o" )
-            cp "${PATCHELF}" "${PATCHELF}.__to_be_patched"
 
             # we always want $ORIGIN-based rpaths to make it relocatable.
-            sanitize_extra_args+=( "--relative-to-file" )
+            sanitize_args+=( "--set-rpath" )
+            sanitize_args+=( "\$ORIGIN/../lib" )
             ;;
 
         staging)
@@ -101,14 +103,18 @@ main() {
             done
 
             # should be like for the target tree below
-            sanitize_extra_args+=( "--no-standard-lib-dirs" )
+            sanitize_args+=( "--no-standard-lib-dirs" )
+            sanitize_args+=( "--make-rpath-relative" )
+            sanitize_args+=( "${rootdir}" )
             ;;
 
         target)
             rootdir="${TARGET_DIR}"
             # we don't want $ORIGIN-based rpaths but absolute paths without rootdir.
             # we also want to remove rpaths pointing to /lib or /usr/lib.
-            sanitize_extra_args+=( "--no-standard-lib-dirs" )
+            sanitize_args+=( "--no-standard-lib-dirs" )
+            sanitize_args+=( "--make-rpath-relative" )
+            sanitize_args+=( "${rootdir}" )
             ;;
 
         *)
@@ -120,20 +126,21 @@ main() {
     find_args+=( "-type" "f" "-print" )
 
     while read file ; do
-        # check if it's an ELF file
-        if ${PATCHELF} --print-rpath "${file}" > /dev/null 2>&1; then
+        rpath=$(${PATCHELF} --print-rpath "${file}" 2>/dev/null)
+        if test $? -eq 0; then
+            # For host binaries, if the rpath is already correct, skip
+            if test "${tree}" = "host" -a "${rpath}" = "\$ORIGIN/../lib" ; then
+                continue
+            fi
             # make files writable if necessary
             changed=$(chmod -c u+w "${file}")
             # call patchelf to sanitize the rpath
-            ${PATCHELF} --make-rpath-relative "${rootdir}" ${sanitize_extra_args[@]} "${file}"
+            ${PATCHELF} ${sanitize_args[@]} "${file}"
             # restore the original permission
             test "${changed}" != "" && chmod u-w "${file}"
         fi
     done < <(find "${rootdir}" ${find_args[@]})
 
-    # Restore patched patchelf utility
-    test "${tree}" = "host" && mv "${PATCHELF}.__to_be_patched" "${PATCHELF}"
-
     # ignore errors
     return 0
 }
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 7/7] core: implement per-package SDK and target
  2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
                   ` (5 preceding siblings ...)
  2017-11-24 16:46 ` [Buildroot] [RFCv2 6/7] core: change host RPATH handling Thomas Petazzoni
@ 2017-11-24 16:46 ` Thomas Petazzoni
  6 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-24 16:46 UTC (permalink / raw)
  To: buildroot

This commit implemnts the core of the move to per-package SDK and
target directories. The main idea is that instead of having a global
output/host and output/target in which all packages install files, we
switch to per-package host and target folders, that only contain their
explicit dependencies.

There are two main benefits:

 - Packages will no longer discover dependencies that they do not
   explicitly indicate in their <pkg>_DEPENDENCIES variable.

 - We can support top-level parallel build properly, because a package
   only "sees" its own host directory and target directory, isolated
   from the build of other packages that can happen in parallel.

It works as follows:

 - A new output/per-package/ folder is created, which will contain one
   sub-folder per package, and inside it, a "host" folder and a
   "target" folder:

   output/per-package/busybox/target
   output/per-package/busybox/host
   output/per-package/host-fakeroot/target
   output/per-package/host-fakeroot/host

   This output/per-package/ folder is PER_PACKAGE_DIR.

 - The global TARGET_DIR and HOST_DIR variable now automatically point
   to the per-package directory when PKG is defined. So whenever a
   package references $(HOST_DIR) or $(TARGET_DIR) in its build
   process, it effectively references the per-package host/target
   directories. Note that STAGING_DIR is a sub-dir of HOST_DIR, so it
   is handled as well.

 - Of course, packages have dependencies, so those dependencies must
   be installed in the per-package host and target folders before
   configuring the package. To do so, we simply rsync (using hard
   links to save space and time) the host and target folders of the
   direct dependencies of the package to the current package host and
   target folders.

   We only need to take care of direct dependencies (and not
   recursively all dependencies), because we accumulate into those
   per-package host and target folders the files installed by the
   dependencies. Note that this only works because we make the
   assumption that one package does *not* overwrite files installed by
   another package.

This is basically enough to make per-package SDK and target work. The
only gotcha is that at the end of the build, output/target and
output/host are empty, which means that:

 - The filesystem image creation code cannot work.

 - We don't have a SDK to build code outside of Buildroot.

In order to fix this, this commit extends the target-finalize step so
that it starts by populating output/target and output/host by
rsync-ing into them the target and host directories of all packages
listed in the $(PACKAGES) variable. It is necessary to do this
sequentially in the target-finalize step and not in each
package. Doing it in package installation means that it can be done in
parallel. In that case, there is a chance that two rsyncs are creating
the same hardlink or directory at the same time, which makes one of
them fail.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
Changes since v1:
 - Remove the LD_LIBRARY_PATH change since we're now longer relying on
   LD_LIBRARY_PATH to allow host programs to find their libraries.
 - Improve commit log according to Arnout suggestions
 - Remove -u option from rsync calls in the main Makefile, suggested
   by Arnout
 - Drop entirely the definitions of <pkg>_TARGET_DIR,
   <pkg>_STAGING_DIR and <pkg>_HOST_DIR, and instead make the global
   TARGET_DIR, HOST_DIR variables point to the per-package directories
   when PKG is defined. Suggested by Arnout.
---
 Makefile               | 20 ++++++++++++++++----
 package/pkg-generic.mk |  9 +++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index f32fde7a68..339f8cc291 100644
--- a/Makefile
+++ b/Makefile
@@ -215,7 +215,9 @@ BR_GRAPH_OUT := $(or $(BR2_GRAPH_OUT),pdf)
 
 BUILD_DIR := $(BASE_DIR)/build
 BINARIES_DIR := $(BASE_DIR)/images
-TARGET_DIR := $(BASE_DIR)/target
+PER_PACKAGE_DIR := $(BASE_DIR)/per-package
+TARGET_DIR = $(if $(PKG),$(PER_PACKAGE_DIR)/$($(PKG)_NAME)/target,$(BASE_DIR)/target)
+
 # initial definition so that 'make clean' works for most users, even without
 # .config. HOST_DIR will be overwritten later when .config is included.
 HOST_DIR := $(BASE_DIR)/host
@@ -237,7 +239,7 @@ LEGAL_REPORT = $(LEGAL_INFO_DIR)/README
 # dependencies anywhere else
 #
 ################################################################################
-$(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIST_SOURCES_DIR_TARGET) $(REDIST_SOURCES_DIR_HOST):
+$(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIST_SOURCES_DIR_TARGET) $(REDIST_SOURCES_DIR_HOST) $(PER_PACKAGE_DIR):
 	@mkdir -p $@
 
 BR2_CONFIG = $(CONFIG_DIR)/.config
@@ -437,7 +439,7 @@ LZCAT := $(call qstrip,$(BR2_LZCAT))
 TAR_OPTIONS = $(call qstrip,$(BR2_TAR_OPTIONS)) -xf
 
 # packages compiled for the host go here
-HOST_DIR := $(call qstrip,$(BR2_HOST_DIR))
+HOST_DIR = $(if $(PKG),$(PER_PACKAGE_DIR)/$($(PKG)_NAME)/host,$(call qstrip,$(BR2_HOST_DIR)))
 
 # Quotes are needed for spaces and all in the original PATH content.
 BR_PATH = "$(HOST_DIR)/bin:$(HOST_DIR)/sbin:$(PATH)"
@@ -666,6 +668,16 @@ $(TARGETS_ROOTFS): target-finalize
 
 .PHONY: target-finalize
 target-finalize: $(PACKAGES)
+	@$(call MESSAGE,"Creating global target directory")
+	$(foreach pkg,$(PACKAGES),\
+		rsync -a --link-dest=$(PER_PACKAGE_DIR)/$(pkg)/target/ \
+		$(PER_PACKAGE_DIR)/$(pkg)/target/ \
+		$(TARGET_DIR)$(sep))
+	@$(call MESSAGE,"Creating global host directory")
+	$(foreach pkg,$(PACKAGES),\
+		rsync -a --link-dest=$(PER_PACKAGE_DIR)/$(pkg)/host/ \
+		$(PER_PACKAGE_DIR)/$(pkg)/host/ \
+		$(HOST_DIR)$(sep))
 	@$(call MESSAGE,"Finalizing target directory")
 	$(foreach hook,$(TARGET_FINALIZE_HOOKS),$($(hook))$(sep))
 	rm -rf $(TARGET_DIR)/usr/include $(TARGET_DIR)/usr/share/aclocal \
@@ -958,7 +970,7 @@ printvars:
 clean:
 	rm -rf $(TARGET_DIR) $(BINARIES_DIR) $(HOST_DIR) \
 		$(BUILD_DIR) $(BASE_DIR)/staging \
-		$(LEGAL_INFO_DIR) $(GRAPHS_DIR)
+		$(LEGAL_INFO_DIR) $(GRAPHS_DIR) $(PER_PACKAGE_DIR)
 
 .PHONY: distclean
 distclean: clean
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index 5b32bdf722..6fde618a74 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -215,6 +215,15 @@ $(foreach dir,$(call qstrip,$(BR2_GLOBAL_PATCH_DIR)),\
 $(BUILD_DIR)/%/.stamp_configured:
 	@$(call step_start,configure)
 	@$(call MESSAGE,"Configuring")
+	@mkdir -p $(HOST_DIR) $(TARGET_DIR) $(STAGING_DIR)
+	$(foreach pkg,$($(PKG)_FINAL_DEPENDENCIES),\
+		rsync -a --link-dest=$(PER_PACKAGE_DIR)/$(pkg)/host/ \
+		$(PER_PACKAGE_DIR)/$(pkg)/host/ \
+		$(HOST_DIR)$(sep))
+	$(foreach pkg,$($(PKG)_FINAL_DEPENDENCIES),\
+		rsync -a --link-dest=$(PER_PACKAGE_DIR)/$(pkg)/target/ \
+		$(PER_PACKAGE_DIR)/$(pkg)/target/ \
+		$(TARGET_DIR)$(sep))
 	$(foreach hook,$($(PKG)_PRE_CONFIGURE_HOOKS),$(call $(hook))$(sep))
 	$($(PKG)_CONFIGURE_CMDS)
 	$(foreach hook,$($(PKG)_POST_CONFIGURE_HOOKS),$(call $(hook))$(sep))
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package
  2017-11-24 16:46 ` [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package Thomas Petazzoni
@ 2017-11-25 19:46   ` Baruch Siach
  2017-11-25 19:54     ` Thomas Petazzoni
  0 siblings, 1 reply; 10+ messages in thread
From: Baruch Siach @ 2017-11-25 19:46 UTC (permalink / raw)
  To: buildroot

Hi Thomas,

On Fri, Nov 24, 2017 at 05:46:06PM +0100, Thomas Petazzoni wrote:
> As part of the per-package SDK work, we want to avoid having logic
> that installs files to the global HOST_DIR, and instead do it inside
> packages. One thing that gets installed to the global HOST_DIR is the
> minimal "skeleton" that we create in host:
> 
>  - the "usr" symbolic link for backward compatibility
> 
>  - the "lib" directory, and its lib64 or lib32 symbolic links
> 
> This commit moves this logic to a new host-skeleton package, and makes
> all packages (except itself) depend on it. We also make sure that this
> host-skeleton package doesn't depend on host-patchelf, because
> host-patchelf depends on host-skeleton.

AFAICS, host-patchelf becomes a dependency of all packages only in patch #6. 
Maybe this last sentence should move there.

baruch

> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
> Changes since v1:
>  - New patch
> ---
>  Makefile                     | 13 +------------
>  package/pkg-generic.mk       |  4 ++++
>  package/skeleton/skeleton.mk | 12 ++++++++++++
>  3 files changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index 55409b99af..193864a0df 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -544,7 +544,7 @@ endif
>  
>  .PHONY: dirs
>  dirs: $(BUILD_DIR) $(STAGING_DIR) $(TARGET_DIR) \
> -	$(HOST_DIR) $(HOST_DIR)/usr $(HOST_DIR)/lib $(BINARIES_DIR)
> +	$(HOST_DIR) $(BINARIES_DIR)
>  
>  $(BUILD_DIR)/buildroot-config/auto.conf: $(BR2_CONFIG)
>  	$(MAKE1) $(EXTRAMAKEARGS) HOSTCC="$(HOSTCC_NOCCACHE)" HOSTCXX="$(HOSTCXX_NOCCACHE)" silentoldconfig
> @@ -563,17 +563,6 @@ sdk: world
>  	$(INSTALL) -m 755 $(TOPDIR)/support/misc/relocate-sdk.sh $(HOST_DIR)/relocate-sdk.sh
>  	echo $(HOST_DIR) > $(HOST_DIR)/share/buildroot/sdk-location
>  
> -# Compatibility symlink in case a post-build script still uses $(HOST_DIR)/usr
> -$(HOST_DIR)/usr: $(HOST_DIR)
> -	@ln -snf . $@
> -
> -$(HOST_DIR)/lib: $(HOST_DIR)
> -	@mkdir -p $@
> -	@case $(HOSTARCH) in \
> -		(*64) ln -snf lib $(@D)/lib64;; \
> -		(*)   ln -snf lib $(@D)/lib32;; \
> -	esac
> -
>  # Populating the staging with the base directories is handled by the skeleton package
>  $(STAGING_DIR):
>  	@mkdir -p $(STAGING_DIR)
> diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
> index 0e28675fbe..574a5861d0 100644
> --- a/package/pkg-generic.mk
> +++ b/package/pkg-generic.mk
> @@ -564,6 +564,10 @@ $(2)_DEPENDENCIES += toolchain
>  endif
>  endif
>  
> +ifneq ($(1),host-skeleton)
> +$(2)_DEPENDENCIES += host-skeleton
> +endif
> +
>  # Eliminate duplicates in dependencies
>  $(2)_FINAL_DEPENDENCIES = $$(sort $$($(2)_DEPENDENCIES))
>  $(2)_FINAL_PATCH_DEPENDENCIES = $$(sort $$($(2)_PATCH_DEPENDENCIES))
> diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk
> index d380f41649..a32bacd0b3 100644
> --- a/package/skeleton/skeleton.mk
> +++ b/package/skeleton/skeleton.mk
> @@ -11,4 +11,16 @@
>  SKELETON_ADD_TOOLCHAIN_DEPENDENCY = NO
>  SKELETON_ADD_SKELETON_DEPENDENCY = NO
>  
> +# We create a compatibility symlink in case a post-build script still
> +# uses $(HOST_DIR)/usr
> +define HOST_SKELETON_INSTALL_CMDS
> +	@ln -snf . $(HOST_DIR)/usr
> +	@mkdir -p $(HOST_DIR)/lib
> +	@case $(HOSTARCH) in \
> +		(*64) ln -snf lib $(HOST_DIR)/lib64;; \
> +		(*)   ln -snf lib $(HOST_DIR)/lib32;; \
> +	esac
> +endef
> +
>  $(eval $(virtual-package))
> +$(eval $(host-generic-package))

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package
  2017-11-25 19:46   ` Baruch Siach
@ 2017-11-25 19:54     ` Thomas Petazzoni
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Petazzoni @ 2017-11-25 19:54 UTC (permalink / raw)
  To: buildroot

Hello,

On Sat, 25 Nov 2017 21:46:50 +0200, Baruch Siach wrote:
> Hi Thomas,
> 
> On Fri, Nov 24, 2017 at 05:46:06PM +0100, Thomas Petazzoni wrote:
> > As part of the per-package SDK work, we want to avoid having logic
> > that installs files to the global HOST_DIR, and instead do it inside
> > packages. One thing that gets installed to the global HOST_DIR is the
> > minimal "skeleton" that we create in host:
> > 
> >  - the "usr" symbolic link for backward compatibility
> > 
> >  - the "lib" directory, and its lib64 or lib32 symbolic links
> > 
> > This commit moves this logic to a new host-skeleton package, and makes
> > all packages (except itself) depend on it. We also make sure that this
> > host-skeleton package doesn't depend on host-patchelf, because
> > host-patchelf depends on host-skeleton.  
> 
> AFAICS, host-patchelf becomes a dependency of all packages only in patch #6. 
> Maybe this last sentence should move there.

True. This patch originally was *after* the change of the RPATH
strategy, and I decided to move it earlier in t he patch series, hoping
that it could be merged earlier than the bigger/more controversial
changes.

I'll fix that in v3.

Thanks for the review!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-11-25 19:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-24 16:46 [Buildroot] [RFCv2 0/7] Per-package SDK and target directories Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 1/7] pkgconf: use relative path to STAGING_DIR instead of absolute path Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 2/7] toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 3/7] Makefile, skeleton: move the host skeleton logic to host-skeleton package Thomas Petazzoni
2017-11-25 19:46   ` Baruch Siach
2017-11-25 19:54     ` Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 4/7] pkg-cmake: install CMake files as part of a package Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 5/7] pkg-generic: add .stamp_installed step Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 6/7] core: change host RPATH handling Thomas Petazzoni
2017-11-24 16:46 ` [Buildroot] [RFCv2 7/7] core: implement per-package SDK and target Thomas Petazzoni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.