From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
To: buildroot@busybox.net
Subject: [Buildroot] [RFCv1 4/4] core: implement per-package SDK and target
Date: Wed, 8 Nov 2017 00:11:39 +0100 [thread overview]
Message-ID: <20171108001139.0071f3b5@windsurf> (raw)
In-Reply-To: <ab34a9ea-90a0-fc39-273d-0bd08a2c72b0@mind.be>
Hello,
Thanks a lot for the suggestions, I'll take them into account for the
next version. Just a few comments/questions below.
On Tue, 7 Nov 2017 23:50:52 +0100, Arnout Vandecappelle wrote:
> > 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 would have been good to mention somewhere in the commit log the problem of 2
> packages writing the same file...
True. I believe the work Yann has done to detect packages overwriting
files installed by other packages is definitely a pre-requisite for
this work, so I was kind of assuming that the "packages don't overwrite
each other" would already be a rule by the time my per-package SDK
patches get merged. But I should make this explicit in the cover letter
at least.
> Also, is there a good reason not to do the rsync at the end of package
> installation? I don't know how robust rsync is against race conditions in
> directory or hardlink creation... OK, so I did a test and it races pretty badly
> :-) So, could you add this to the commit log? Like:
>
> 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.
I didn't think at all about doing this in parallel. To me, the creation
of the final/common HOST_DIR/TARGET_DIR/STAGING_DIR is not at
all something that needs to be done while the build is on-going. And I
could go even further: unless you call "make sdk", we technically don't
really need to create the final/common HOST_DIR/STAGING_DIR. Only a
TARGET_DIR is needed, and perhaps even we could avoid a global one, and
instead have a per-filesystem image one, in order to avoid the parallel
filesystem image creation problem.
> > [Note: in fact, output/host is not completely empty, even though they
> > should be. It contains the following files:
> > output/host/
> > output/host/lib64
> > output/host/usr
> > output/host/share
> > output/host/share/buildroot
> > output/host/share/buildroot/Platform
> > output/host/share/buildroot/Platform/Buildroot.cmake
> > output/host/share/buildroot/toolchainfile.cmake
> > output/host/lib
> > Perhaps those files should be installed by some package instead,
> > perhaps the 'toolchain' package.]
>
> If we go that way: perhaps the .cmake files should be installed by some package
> like 'host-cmake-infra' that is added to the dependencies from cmake-package.
That was my thinking: perhaps those files should all be installed by
packages.
> > .PHONY: target-finalize
> > target-finalize: $(PACKAGES)
> > + @$(call MESSAGE,"Creating global target directory")
> > + $(foreach dir,$(ALL_PACKAGES_TARGET_DIRS),\
> > + rsync -au --link-dest=$(dir) $(dir) $(TARGET_DIR)$(sep))
>
> Why -u? Since we're not actually copying anything, there is no reason to not
> overwrite files that already exist, right?
I just borrowed parts of Gustavo patches, including those rsync
invocations. Indeed -u is not needed.
> Also, shouldn't there be a / behind $(dir)? Otherwise, if TARGET_DIR exists
> already, rsync will create $(dir) as a subdirectory of $(TARGET_DIR), no?
I'll fix.
> > diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
> > index 82f8c06821..aee4011f63 100644
> > --- a/package/pkg-generic.mk
> > +++ b/package/pkg-generic.mk
> > @@ -158,6 +158,7 @@ $(BUILD_DIR)/%/.stamp_actual_downloaded:
> > $(BUILD_DIR)/%/.stamp_extracted:
> > @$(call step_start,extract)
> > @$(call MESSAGE,"Extracting")
> > + @mkdir -p $(HOST_DIR) $(TARGET_DIR) $(STAGING_DIR)
>
> Why do you create them here? It would make more sense to do it just before the
> rsync, no?
I don't remember, I'll have to check again. I don't immediately see a
reason why they would be needed before the rsync.
> Given the possible host-tar and host-lzip dependencies, the rsync should be
> done here already, not in the configure step. Ouch, that's not good, because the
> dependencies are only evaluated for the configure step... There are
> PATCH_DEPENDENCIES, but those are only before patch. Well, I guess that's a
> reason to keep host-tar and host-lzip as DEPENDENCIES_HOST_PREREQ :-)
These are all topics that I haven't looked at yet. So thanks for
pointing them out. I should probably collect a TODO list on per-package
SDK to not forget about all the things people have mentioned as things
to look at.
> > + $(foreach dir,$($(PKG)_FINAL_DEPENDENCIES_HOST_DIRS),\
> > + rsync -au --link-dest=$(dir) $(dir) $(HOST_DIR)$(sep))
>
> Shouldn't there be a $Q somewhere?
Yes. Seeing the rsync commands was useful for debugging, as you can
imagine :)
> > +$(2)_TARGET_DIR = $$(PER_PACKAGE_DIR)/$(1)/target/
>
> Ah, here is the trailing slash, that explains why it worked. I don't really
> like it when you have to rely on a trailing slash in the variable definition...
OK.
>
> > +$(2)_HOST_DIR = $$(PER_PACKAGE_DIR)/$(1)/host/
> > +$(2)_STAGING_DIR = $$(PER_PACKAGE_DIR)/$(1)/host/$(STAGING_SUBDIR)
>
> I hate adding more per-package variables. Can't you use the expanded values,
> substituting $($(PKG)_NAME) for $(1)? Or maybe even better, change the
> definition of TARGET_DIR etc:
>
> TARGET_DIR = $(if
> $(PKG),$(PER_PACKAGE_DIR)/$($(PKG)_RAWNAME)/target,$(BASE_DIR)/target)
>
> That way you also don't need to pass those variables to each individual stamp rule.
I didn't think about this, sounds like a good idea, I'll try that.
However, I'm actually planning to drop entirely having TARGET_DIR
defined outside of package rules. What I want to have ultimately is:
- TARGET_DIR points to the current package per-package target
directory. If we're outside of a package rule, TARGET_DIR has no
value (or possibly a bogus value such as /this/is/a/bogus/thing/).
Indeed, we really don't want things to directly install/mess with
the global/common target directory.
- Have something like COMMON_TARGET_DIR that points to
$(BASE_DIR)/target, and we carefully change the places that should
access the COMMON_TARGET_DIR (i.e mainly target-finalize and some
filesystem generation stuff).
> > # Keep the package version that may contain forward slashes in the _DL_VERSION
> > # variable, then replace all forward slashes ('/') by underscores ('_') to
> > # sanitize the package version that is used in paths, directory and file names.
> > @@ -561,6 +570,13 @@ $(2)_FINAL_DEPENDENCIES = $$(sort $$($(2)_DEPENDENCIES))
> > $(2)_FINAL_PATCH_DEPENDENCIES = $$(sort $$($(2)_PATCH_DEPENDENCIES))
> > $(2)_FINAL_ALL_DEPENDENCIES = $$(sort $$($(2)_FINAL_DEPENDENCIES) $$($(2)_FINAL_PATCH_DEPENDENCIES))
> >
> > +$(2)_FINAL_DEPENDENCIES_HOST_DIRS = \
> > + $$(foreach dep,$$($(2)_FINAL_DEPENDENCIES),\
> > + $$($$(call UPPERCASE,$$(dep))_HOST_DIR))
> > +$(2)_FINAL_DEPENDENCIES_TARGET_DIRS = \
> > + $$(foreach dep,$$($(2)_FINAL_DEPENDENCIES),\
> > + $$($$(call UPPERCASE,$$(dep))_TARGET_DIR))
>
> I may be overengineering things, but perhaps things can be simplified as
> follows (with the definition of TARGET_DIR etc as above):
>
> define RSYNC_HOST_DIRS
> $(foreach pkg,$(1),\
> $(Q)dir=$(PER_PACKAGE_DIR)/$(pkg)/host;\
> rsync -au --link-dest=$$dir $$dir/ $(HOST_DIR)$(sep))
> endef
>
> define RSYNC_TARGET_DIRS
> $(foreach pkg,$(1),\
> $(Q)dir=$(PER_PACKAGE_DIR)/$(pkg)/target;\
> rsync -au --link-dest=$$dir $$dir/ $(TARGET_DIR)$(sep))
> endef
>
> (as always, completely untested). These macros can be used both in the config
> stamp rule and in the finalize rule. I even considered leaving out the argument
> and instead defaulting $(1) to
> $(if $(PKG),$($(PKG)_FINAL_DEPENDENCIES),$(PACKAGES))
> but that probably just makes things harder to understand.
I'll think about this suggestion.
Thanks again for the detailed review.
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
next prev parent reply other threads:[~2017-11-07 23:11 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-03 16:06 [Buildroot] [RFCv1 0/4] Per-package SDK and target directories Thomas Petazzoni
2017-11-03 16:06 ` [Buildroot] [RFCv1 1/4] pkgconf: use relative path to STAGING_DIR instead of absolute path Thomas Petazzoni
2017-11-07 21:05 ` Arnout Vandecappelle
2017-11-03 16:06 ` [Buildroot] [RFCv1 2/4] core: change host RPATH handling Thomas Petazzoni
2017-11-05 8:57 ` Yann E. MORIN
2017-11-05 14:44 ` Thomas Petazzoni
2017-11-05 14:48 ` Arnout Vandecappelle
2017-11-07 22:41 ` Thomas Petazzoni
2017-11-07 23:50 ` Arnout Vandecappelle
2017-11-08 8:55 ` Thomas Petazzoni
2017-11-08 10:55 ` Arnout Vandecappelle
2017-11-08 12:30 ` Thomas Petazzoni
2017-11-08 12:38 ` Arnout Vandecappelle
2017-11-07 21:15 ` Arnout Vandecappelle
2017-11-07 21:22 ` Thomas Petazzoni
2017-11-07 23:45 ` Arnout Vandecappelle
2017-11-03 16:06 ` [Buildroot] [RFCv1 3/4] toolchain: post-pone evaluation of TOOLCHAIN_EXTERNAL_BIN Thomas Petazzoni
2017-11-07 21:23 ` Arnout Vandecappelle
2017-11-07 21:33 ` Thomas Petazzoni
2017-11-07 23:49 ` Arnout Vandecappelle
2017-11-03 16:06 ` [Buildroot] [RFCv1 4/4] core: implement per-package SDK and target Thomas Petazzoni
2017-11-07 22:50 ` Arnout Vandecappelle
2017-11-07 23:11 ` Thomas Petazzoni [this message]
2017-11-07 23:57 ` Arnout Vandecappelle
2017-11-24 14:49 ` Thomas Petazzoni
2017-11-24 14:43 ` Thomas Petazzoni
2017-11-25 17:30 ` Arnout Vandecappelle
2017-11-25 20:01 ` Thomas Petazzoni
2017-11-27 14:23 ` Yann E. MORIN
2017-11-07 23:21 ` [Buildroot] [RFCv1 0/4] Per-package SDK and target directories Arnout Vandecappelle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171108001139.0071f3b5@windsurf \
--to=thomas.petazzoni@free-electrons.com \
--cc=buildroot@busybox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox