diff mbox

[v3,1/1] Makefile: add target to clean targetfs

Message ID 1430095555-8484-1-git-send-email-emeric.vigier@savoirfairelinux.com
State Changes Requested
Headers show

Commit Message

Émeric Vigier April 27, 2015, 12:45 a.m. UTC
If you had some files added to the targetfs (fs-overlay, new packages,
...) and you no longer need them, buildroot does not offer a simple way
to remove these items from the output/target directory. The rule added
by this commit allows you to clean the targetfs. Issuing 'make'
afterward will generate a new and clean targetfs.

A section in the documentation is also added. It describes few examples
when developers could need it. 'make help' is also updated accordingly.
And full-rebuild section of the documentation is updated with content
and links.

Change-Id: I42b640e845bb4195fb7b160281b16ee40883f01f
Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
---
Changes v2 -> v3
  - rename clean-target into target-clean (sugg. Jerome Oufella)
  - print a big fat warning at the end of target-clean (sugg. Arnout
    Vandecappelle)
  - mention the new rule in full-rebuild manual section (sugg. Ryan
    Barnett)

Changes v1 -> v2
  - remove non-existent .built and deprecated .stamp_installed
    references (suggested by Baruch Siach)
  - mention the new target in 'make help'
---
 Makefile                                | 13 +++++++++++
 docs/manual/advanced.txt                |  2 ++
 docs/manual/clean-target-filesystem.txt | 39 +++++++++++++++++++++++++++++++++
 docs/manual/rebuilding-packages.txt     | 29 ++++++++++++++----------
 4 files changed, 71 insertions(+), 12 deletions(-)
 create mode 100644 docs/manual/clean-target-filesystem.txt

Comments

Baruch Siach April 27, 2015, 4:11 a.m. UTC | #1
Hi Emeric,

Thanks for following up on this. A few comments below.

On Sun, Apr 26, 2015 at 08:45:55PM -0400, Emeric Vigier wrote:
> If you had some files added to the targetfs (fs-overlay, new packages,
> ...) and you no longer need them, buildroot does not offer a simple way
> to remove these items from the output/target directory. The rule added
> by this commit allows you to clean the targetfs. Issuing 'make'
> afterward will generate a new and clean targetfs.
> 
> A section in the documentation is also added. It describes few examples
> when developers could need it. 'make help' is also updated accordingly.
> And full-rebuild section of the documentation is updated with content
> and links.
> 
> Change-Id: I42b640e845bb4195fb7b160281b16ee40883f01f

This Gerrit specific line is not useful for upstream Buildroot. Please remove.

> Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>

[snip]

> diff --git a/docs/manual/clean-target-filesystem.txt 
> b/docs/manual/clean-target-filesystem.txt
> new file mode 100644
> index 0000000..3e8181e
> --- /dev/null
> +++ b/docs/manual/clean-target-filesystem.txt
> @@ -0,0 +1,39 @@
> +// -*- mode:doc; -*-
> +// vim: set syntax=asciidoc:
> +
> +[[clean-target-filesystem]]
> +==== Clean target filesystem
> +
> +There are various cases where you would like to clean the target
> +filesystem. Especially once you understood that buildroot does not
> +have rules to uninstall files. Let's take some examples:
> +
> +1. You enabled +PACKAGE_OPENSSH+ to have a SSH server running on your
> +   board. But you figure out that +sshd+ does not run well on your
> +   target's architecture. Thus you decide to disable +PACKAGE_OPENSSH+
> +   and enable +PACKAGE_DROPBEAR+ instead. You run +make+: +dropbear+
> +   gets built and installed, fine. But +openssh+ files are still present
> +   in +output/target+!
> +
> +2. You enabled +PACKAGE_NTPD+ and set the local timezone to
> +   +America/Montreal+ with +BR2_TARGET_LOCALTIME+ config. Then you find
> +   out that +Montreal+ local has been replaced by +Toronto+ (French
> +   looks like a rogue language). You enter +make menuconfig+, make the
> +   change, save, and run +make+ again. Problem:
> +   +output/target/etc/timezone+ still has +America/Montreal+ content!
> +
> +Solution to this is either to identify which package to reconfigure, or
> +remove files manually, or destroy the target filesystem and recreate it.
> +This latter option is convenient: you don't have to care about which
> +packages to rebuild, and it is quite fast. Here is how to recreate your
> +target filesystem, and get rid of filesystem _stains_:
> +
> +------------------
> +make target-clean
> +make
> +------------------
> +
> ++target-clean+ removes +output/target+. That tells buildroot to recreate
> +the target skeleton, and install each package again. This is a
> +convenient way to rebuild your target filesystem cleanly without
> +rebuilding everything.

The warning is worth repeating here, I think.

> diff --git a/docs/manual/rebuilding-packages.txt b/docs/manual/rebuilding-packages.txt
> index 6faa67a..82385ae 100644
> --- a/docs/manual/rebuilding-packages.txt
> +++ b/docs/manual/rebuilding-packages.txt
> @@ -39,17 +39,22 @@ can help you understand how to work with Buildroot:
>     you would like to have SSL support in +ctorrent+, so you enable the
>     +openssl+ package in Buildroot configuration and restart the
>     build. Buildroot will detect that +openssl+ should be built and
> -   will be build it, but it will not detect that +ctorrent+ should be
> -   rebuilt to benefit from +openssl+ to add OpenSSL support. You will
> -   either have to do a full rebuild, or rebuild +ctorrent+ itself.
> +   will build it, but it will not detect that +ctorrent+ should be
> +   rebuilt to benefit from +openssl+ support. You will either have to
> +   do a full rebuild, or rebuild +ctorrent+ itself.

This is an unrelated fix. Please submit in a separate patch.

baruch
Andreas Naumann April 27, 2015, 8:28 a.m. UTC | #2
Am 27.04.2015 um 02:45 schrieb Emeric Vigier:
> If you had some files added to the targetfs (fs-overlay, new packages,
> ...) and you no longer need them, buildroot does not offer a simple way
> to remove these items from the output/target directory. The rule added
> by this commit allows you to clean the targetfs. Issuing 'make'
> afterward will generate a new and clean targetfs.
>
> A section in the documentation is also added. It describes few examples
> when developers could need it. 'make help' is also updated accordingly.
> And full-rebuild section of the documentation is updated with content
> and links.
>

Hi Emeric,

this is very helpful, in fact i have a similar patch running for quite 
some time where I remove target/ and images/ and the corresponding 
stamps. There are some problems though and I want to share my findings 
with you.
To begin with i was not 100% sure if the recreated target is the same as 
after a clean build. So I wrote a small check script which compares the 
original with the re-installed target trees. Here's the comparison i do:

   rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude 
'tmp/ldconfig/aux-cache' output/target/ target.orig/

As you see it already has some files excluded that are always recreated 
differently.
In addition I need to delete .stamp_host_installed from host-gcc-final* 
to force reinstall of libstdc++ into target (using external linaro 
toolchain).

Another problem that showed up was that some of the package install 
steps dont seem separated very well. E.g. qt5 examples copies everything 
from a certain staging-dir/* to target/..
A later qt5 module also creates files in that staging-dir, so next round 
there's more files in target.

I realize this is due to my way of not deleteing the staging dir any 
longer - I used to in the beginning. If I recall correctly this is 
because I noticed some packages copy files into staging/ during compile 
and these files are then missing after a reinstall. I'm not entirely 
sure though.

So my question is, in your approach, are you certain the re-installed 
staging/ is the same as the original for all packages? Maybe you can run 
some comparison like my rsync line for staging as well.


regards,
Andreas
Émeric Vigier April 28, 2015, 2:36 p.m. UTC | #3
On 15-04-27 12:11 AM, Baruch Siach wrote:
> Hi Emeric,

Hi Baruch,

>>
>> Change-Id: I42b640e845bb4195fb7b160281b16ee40883f01f
>
> This Gerrit specific line is not useful for upstream Buildroot. Please remove.

Sure.

>
>> Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
>
> [snip]
>
>> diff --git a/docs/manual/clean-target-filesystem.txt
>> b/docs/manual/clean-target-filesystem.txt
>> new file mode 100644
>> index 0000000..3e8181e
>> --- /dev/null
>> +++ b/docs/manual/clean-target-filesystem.txt
>> @@ -0,0 +1,39 @@
>> +// -*- mode:doc; -*-
>> +// vim: set syntax=asciidoc:
>> +
>> +[[clean-target-filesystem]]
>> +==== Clean target filesystem
>> +
>> +There are various cases where you would like to clean the target
>> +filesystem. Especially once you understood that buildroot does not
>> +have rules to uninstall files. Let's take some examples:
>> +
>> +1. You enabled +PACKAGE_OPENSSH+ to have a SSH server running on your
>> +   board. But you figure out that +sshd+ does not run well on your
>> +   target's architecture. Thus you decide to disable +PACKAGE_OPENSSH+
>> +   and enable +PACKAGE_DROPBEAR+ instead. You run +make+: +dropbear+
>> +   gets built and installed, fine. But +openssh+ files are still present
>> +   in +output/target+!
>> +
>> +2. You enabled +PACKAGE_NTPD+ and set the local timezone to
>> +   +America/Montreal+ with +BR2_TARGET_LOCALTIME+ config. Then you find
>> +   out that +Montreal+ local has been replaced by +Toronto+ (French
>> +   looks like a rogue language). You enter +make menuconfig+, make the
>> +   change, save, and run +make+ again. Problem:
>> +   +output/target/etc/timezone+ still has +America/Montreal+ content!
>> +
>> +Solution to this is either to identify which package to reconfigure, or
>> +remove files manually, or destroy the target filesystem and recreate it.
>> +This latter option is convenient: you don't have to care about which
>> +packages to rebuild, and it is quite fast. Here is how to recreate your
>> +target filesystem, and get rid of filesystem _stains_:
>> +
>> +------------------
>> +make target-clean
>> +make
>> +------------------
>> +
>> ++target-clean+ removes +output/target+. That tells buildroot to recreate
>> +the target skeleton, and install each package again. This is a
>> +convenient way to rebuild your target filesystem cleanly without
>> +rebuilding everything.
>
> The warning is worth repeating here, I think.

I don't like to repeat things. I suggest to move the warning here and 
put emphasis on the link from full-rebuild to here.

>
>> diff --git a/docs/manual/rebuilding-packages.txt b/docs/manual/rebuilding-packages.txt
>> index 6faa67a..82385ae 100644
>> --- a/docs/manual/rebuilding-packages.txt
>> +++ b/docs/manual/rebuilding-packages.txt
>> @@ -39,17 +39,22 @@ can help you understand how to work with Buildroot:
>>      you would like to have SSL support in +ctorrent+, so you enable the
>>      +openssl+ package in Buildroot configuration and restart the
>>      build. Buildroot will detect that +openssl+ should be built and
>> -   will be build it, but it will not detect that +ctorrent+ should be
>> -   rebuilt to benefit from +openssl+ to add OpenSSL support. You will
>> -   either have to do a full rebuild, or rebuild +ctorrent+ itself.
>> +   will build it, but it will not detect that +ctorrent+ should be
>> +   rebuilt to benefit from +openssl+ support. You will either have to
>> +   do a full rebuild, or rebuild +ctorrent+ itself.
>
> This is an unrelated fix. Please submit in a separate patch.

Sure.

>
> baruch

thanks for your review,
Émeric Vigier April 28, 2015, 3:06 p.m. UTC | #4
On 15-04-27 04:28 AM, Andreas Naumann wrote:
>
>
> Am 27.04.2015 um 02:45 schrieb Emeric Vigier:
>> If you had some files added to the targetfs (fs-overlay, new packages,
>> ...) and you no longer need them, buildroot does not offer a simple way
>> to remove these items from the output/target directory. The rule added
>> by this commit allows you to clean the targetfs. Issuing 'make'
>> afterward will generate a new and clean targetfs.
>>
>> A section in the documentation is also added. It describes few examples
>> when developers could need it. 'make help' is also updated accordingly.
>> And full-rebuild section of the documentation is updated with content
>> and links.
>>
>
> Hi Emeric,
>
> this is very helpful, in fact i have a similar patch running for quite
> some time where I remove target/ and images/ and the corresponding
> stamps. There are some problems though and I want to share my findings
> with you.
> To begin with i was not 100% sure if the recreated target is the same as
> after a clean build. So I wrote a small check script which compares the
> original with the re-installed target trees. Here's the comparison i do:
>
>    rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude
> 'tmp/ldconfig/aux-cache' output/target/ target.orig/
>
> As you see it already has some files excluded that are always recreated
> differently.
> In addition I need to delete .stamp_host_installed from host-gcc-final*
> to force reinstall of libstdc++ into target (using external linaro
> toolchain).

In fact, the target-clean rule deletes output/staging, but that's just a 
symlink, thus the content is not erased.  My goal was to recreate the 
targetfs, not the toolchain's sysroot. But that's true that I force the 
re-installation of packages containing INSTALL_STAGING directives.

The manual says that if you change something in the toolchain, you have 
to do a full rebuild. I don't change this rule of thumb. So I don't 
believe I need to delete .stamp_host_installed here. But let me test 
with a Linaro toolchain and libstdc++.

>
> Another problem that showed up was that some of the package install
> steps dont seem separated very well. E.g. qt5 examples copies everything
> from a certain staging-dir/* to target/..

OMG, that's nasty, isn't it? Why so? Why doesn't qt copies from 
output/build to output/target?

> A later qt5 module also creates files in that staging-dir, so next round
> there's more files in target.

OMG, isn't that nastier? Isn't it an oppportunity to patch qt, rather 
than changing my current patch?

>
> I realize this is due to my way of not deleteing the staging dir any
> longer - I used to in the beginning. If I recall correctly this is
> because I noticed some packages copy files into staging/ during compile
> and these files are then missing after a reinstall. I'm not entirely
> sure though.
>
> So my question is, in your approach, are you certain the re-installed
> staging/ is the same as the original for all packages? Maybe you can run
> some comparison like my rsync line for staging as well.

That's worth a try. I'd also be interested by some test results in your 
environment if you find the time.

>
> regards,
> Andreas
>

thanks for sharing this,
Émeric Vigier July 14, 2015, 9:56 p.m. UTC | #5
On 15-04-27 04:28 AM, Andreas Naumann wrote:
>
>
> Am 27.04.2015 um 02:45 schrieb Emeric Vigier:
>> If you had some files added to the targetfs (fs-overlay, new packages,
>> ...) and you no longer need them, buildroot does not offer a simple way
>> to remove these items from the output/target directory. The rule added
>> by this commit allows you to clean the targetfs. Issuing 'make'
>> afterward will generate a new and clean targetfs.
>>
>> A section in the documentation is also added. It describes few examples
>> when developers could need it. 'make help' is also updated accordingly.
>> And full-rebuild section of the documentation is updated with content
>> and links.
>>
>
> Hi Emeric,
>
> this is very helpful, in fact i have a similar patch running for quite
> some time where I remove target/ and images/ and the corresponding
> stamps. There are some problems though and I want to share my findings
> with you.
> To begin with i was not 100% sure if the recreated target is the same as
> after a clean build. So I wrote a small check script which compares the
> original with the re-installed target trees. Here's the comparison i do:
>
>    rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude
> 'tmp/ldconfig/aux-cache' output/target/ target.orig/

Hi Andreas,

Sorry for the delay (BOFH excuse #273: The cord jumped over and hit the 
power switch). I finally have some time to work on this.

I ran your rsync command on a beaglebone_defconfig and ended up with 
some differences indeed:

$ rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude 
'tmp/ldconfig/aux-cache' output/target/ output/target.orig/
sending incremental file list
deleting lib/libgcc_s.so.1
deleting lib/libgcc_s.so
deleting lib/libatomic.so.1.1.0
deleting lib/libatomic.so.1
deleting lib/libatomic.so

sent 12,704 bytes  received 165 bytes  8,579.33 bytes/sec
total size is 1,671,066  speedup is 129.85 (DRY RUN)

> As you see it already has some files excluded that are always recreated
> differently.
> In addition I need to delete .stamp_host_installed from host-gcc-final*
> to force reinstall of libstdc++ into target (using external linaro
> toolchain).

removing $(BUILD_DIR)/host-gcc-final-*/.stamp_host_installed in the 
'target-clean' recipe fixed that issue. But is this solution generic enough?

> Another problem that showed up was that some of the package install
> steps dont seem separated very well. E.g. qt5 examples copies everything
> from a certain staging-dir/* to target/..
> A later qt5 module also creates files in that staging-dir, so next round
> there's more files in target.
>
> I realize this is due to my way of not deleteing the staging dir any
> longer - I used to in the beginning. If I recall correctly this is
> because I noticed some packages copy files into staging/ during compile
> and these files are then missing after a reinstall. I'm not entirely
> sure though.

I enabled qt4 and compare the targetfs after a target-clean, no differences:

$ rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude 
'tmp/ldconfig/aux-cache' output/target/ output/target.orig.qt4/
sending incremental file list

sent 15,095 bytes  received 62 bytes  30,314.00 bytes/sec
total size is 16,028,992  speedup is 1,057.53 (DRY RUN)

With what QT configs did you meet problems specifically?

> So my question is, in your approach, are you certain the re-installed
> staging/ is the same as the original for all packages? Maybe you can run
> some comparison like my rsync line for staging as well.

Yes, I have to check that too.

>
>
> regards,
> Andreas

thanks,
--
Emeric
Émeric Vigier July 16, 2015, 3:15 p.m. UTC | #6
>> Another problem that showed up was that some of the package install
>> steps dont seem separated very well. E.g. qt5 examples copies everything
>> from a certain staging-dir/* to target/..
>> A later qt5 module also creates files in that staging-dir, so next round
>> there's more files in target.
>>
>> I realize this is due to my way of not deleteing the staging dir any
>> longer - I used to in the beginning. If I recall correctly this is
>> because I noticed some packages copy files into staging/ during compile
>> and these files are then missing after a reinstall. I'm not entirely
>> sure though.
>
> I enabled qt4 and compare the targetfs after a target-clean, no
> differences:
>
> $ rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude
> 'tmp/ldconfig/aux-cache' output/target/ output/target.orig.qt4/
> sending incremental file list
>
> sent 15,095 bytes  received 62 bytes  30,314.00 bytes/sec
> total size is 16,028,992  speedup is 1,057.53 (DRY RUN)
>
> With what QT configs did you meet problems specifically?

Qt4 showed no difference in the targetfs.

I disabled Qt4 and enabled Qt5 with several modules and saw no 
differences in targetfs either. Here is my Qt5 config:

   http://pastie.org/10296840

I had to switch from a buildroot toolchain to a Linaro-gcc-4.9 toolchain 
to build Qt5. I haven't enabled Qt5-webkit because I fell into this 
GCC-4.9 bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61207.

>> So my question is, in your approach, are you certain the re-installed
>> staging/ is the same as the original for all packages? Maybe you can run
>> some comparison like my rsync line for staging as well.

I only delete staging symlink, not the sysroot content. This patch does 
not aim at fixing the black magic that some packages may be doing 
between the staging dir and the target dir, just recreating the targetfs.

So the only improvement I have in mind for this patch is this:

         rm -rf $(TARGET_DIR) $(STAGING_DIR) $(BUILD_DIR)/.root \
-         $(BUILD_DIR)/*/.stamp_target_installed 
$(BUILD_DIR)/*/.stamp_staging_installed
+         $(BUILD_DIR)/*/.stamp_target_installed 
$(BUILD_DIR)/*/.stamp_staging_installed \
+         $(BUILD_DIR)/host-gcc-final-*/.stamp_host_installed

Do you have other things in mind?

>> regards,
>> Andreas
>
> thanks,
> --
> Emeric

Emeric
Andreas Naumann July 23, 2015, 8:51 p.m. UTC | #7
Hi Emeric,

nice that you pick this up again. comments below...

Am 16.07.2015 um 17:15 schrieb Emeric Vigier:
>>> Another problem that showed up was that some of the package install
>>> steps dont seem separated very well. E.g. qt5 examples copies everything
>>> from a certain staging-dir/* to target/..
>>> A later qt5 module also creates files in that staging-dir, so next round
>>> there's more files in target.
>>>
>>> I realize this is due to my way of not deleteing the staging dir any
>>> longer - I used to in the beginning. If I recall correctly this is
>>> because I noticed some packages copy files into staging/ during compile
>>> and these files are then missing after a reinstall. I'm not entirely
>>> sure though.
>>
>> I enabled qt4 and compare the targetfs after a target-clean, no
>> differences:
>>
>> $ rsync -rvncl --delete --exclude '*.pyc' --exclude '*.pyo' --exclude
>> 'tmp/ldconfig/aux-cache' output/target/ output/target.orig.qt4/
>> sending incremental file list
>>
>> sent 15,095 bytes  received 62 bytes  30,314.00 bytes/sec
>> total size is 16,028,992  speedup is 1,057.53 (DRY RUN)
>>
>> With what QT configs did you meet problems specifically?
>
> Qt4 showed no difference in the targetfs.
>
> I disabled Qt4 and enabled Qt5 with several modules and saw no
> differences in targetfs either. Here is my Qt5 config:
>
>    http://pastie.org/10296840
>
> I had to switch from a buildroot toolchain to a Linaro-gcc-4.9 toolchain
> to build Qt5. I haven't enabled Qt5-webkit because I fell into this
> GCC-4.9 bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61207.

When compiling qt5-webkit I've probably hit the same bug as you, so my 
reaction was to switch from linaro gcc 4.9 to buildroots internal 
toolchain 4.8 (a few month ago).  That way webkit compiled.

The "reinstall" problems then started when selecting 
qt5-webkit-examples. I've also had problems with qt4, but I dont recall 
in which exact configuration.

>
>>> So my question is, in your approach, are you certain the re-installed
>>> staging/ is the same as the original for all packages? Maybe you can run
>>> some comparison like my rsync line for staging as well.
>
> I only delete staging symlink, not the sysroot content. This patch does

Ok, so to me it seems there's little difference to my not touching 
staging at all. What's your intention of deleting the symlink only?

> not aim at fixing the black magic that some packages may be doing
> between the staging dir and the target dir, just recreating the targetfs.

> So the only improvement I have in mind for this patch is this:
>
>          rm -rf $(TARGET_DIR) $(STAGING_DIR) $(BUILD_DIR)/.root \
> -         $(BUILD_DIR)/*/.stamp_target_installed
> $(BUILD_DIR)/*/.stamp_staging_installed
> +         $(BUILD_DIR)/*/.stamp_target_installed
> $(BUILD_DIR)/*/.stamp_staging_installed \
> +         $(BUILD_DIR)/host-gcc-final-*/.stamp_host_installed
>
> Do you have other things in mind?

I dont know how hard it is to compile an allyesdefconfig, but that, in 
combination with the rsync check, would be a nice testcase to prove 
correctness.
However, I'm on vacation for another week, so right now cant really work 
on this.


cheers,
Andreas


>
>>> regards,
>>> Andreas
>>
>> thanks,
>> --
>> Emeric
>
> Emeric
>
Arnout Vandecappelle Oct. 4, 2015, 4:56 p.m. UTC | #8
On 27-04-15 01:45, Emeric Vigier wrote:
> If you had some files added to the targetfs (fs-overlay, new packages,
> ...) and you no longer need them, buildroot does not offer a simple way
> to remove these items from the output/target directory. The rule added
> by this commit allows you to clean the targetfs. Issuing 'make'
> afterward will generate a new and clean targetfs.
> 
> A section in the documentation is also added. It describes few examples
> when developers could need it. 'make help' is also updated accordingly.
> And full-rebuild section of the documentation is updated with content
> and links.
> 
> Change-Id: I42b640e845bb4195fb7b160281b16ee40883f01f
> Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>

 Hi Emeric,

 Since there were some comments on this patch and there also seem to be cases
where it doesn't really work well, I've marked it as Changes Requested in our
patch tracking system. So unless you resubmit a new version that fixes the
comments, we will forget about your contribution.

 Regards,
 Arnout
diff mbox

Patch

diff --git a/Makefile b/Makefile
index 3983fce..b9db264 100644
--- a/Makefile
+++ b/Makefile
@@ -666,6 +666,18 @@  graph-depends: graph-depends-requirements
 	|tee $(GRAPHS_DIR)/$(@).dot \
 	|dot $(BR2_GRAPH_DOT_OPTS) -T$(BR_GRAPH_OUT) -o $(GRAPHS_DIR)/$(@).$(BR_GRAPH_OUT)
 
+target-clean:
+	@echo "----------------------------------------------------------------"
+	@echo "WARNING! target-clean does not fix package dependencies for you."
+	@echo "Think twice about what you are attempting! For instance, if you "
+	@echo "remove openssl needed by git, and just run make target-clean "
+	@echo "without rebuilding git, your rootfs will embed a broken git. It "
+	@echo "will fail to execute because it is linked again +openssl+, and  "
+	@echo "this library is not present anymore on your target rootfs."
+	@echo "----------------------------------------------------------------"
+	rm -rf $(TARGET_DIR) $(STAGING_DIR) $(BUILD_DIR)/.root \
+		$(BUILD_DIR)/*/.stamp_target_installed $(BUILD_DIR)/*/.stamp_staging_installed
+
 else # ifeq ($(BR2_HAVE_DOT_CONFIG),y)
 
 all: menuconfig
@@ -821,6 +833,7 @@  help:
 	@echo 'Cleaning:'
 	@echo '  clean                  - delete all files created by build'
 	@echo '  distclean              - delete all non-source files (including .config)'
+	@echo '  target-clean           - delete targetfs and staging directories'
 	@echo
 	@echo 'Build:'
 	@echo '  all                    - make world'
diff --git a/docs/manual/advanced.txt b/docs/manual/advanced.txt
index b7bfc49..1cf0427 100644
--- a/docs/manual/advanced.txt
+++ b/docs/manual/advanced.txt
@@ -14,3 +14,5 @@  include::download-location.txt[]
 include::package-make-target.txt[]
 
 include::using-buildroot-development.txt[]
+
+include::clean-target-filesystem.txt[]
diff --git a/docs/manual/clean-target-filesystem.txt b/docs/manual/clean-target-filesystem.txt
new file mode 100644
index 0000000..3e8181e
--- /dev/null
+++ b/docs/manual/clean-target-filesystem.txt
@@ -0,0 +1,39 @@ 
+// -*- mode:doc; -*-
+// vim: set syntax=asciidoc:
+
+[[clean-target-filesystem]]
+==== Clean target filesystem
+
+There are various cases where you would like to clean the target
+filesystem. Especially once you understood that buildroot does not
+have rules to uninstall files. Let's take some examples:
+
+1. You enabled +PACKAGE_OPENSSH+ to have a SSH server running on your
+   board. But you figure out that +sshd+ does not run well on your
+   target's architecture. Thus you decide to disable +PACKAGE_OPENSSH+
+   and enable +PACKAGE_DROPBEAR+ instead. You run +make+: +dropbear+
+   gets built and installed, fine. But +openssh+ files are still present
+   in +output/target+!
+
+2. You enabled +PACKAGE_NTPD+ and set the local timezone to
+   +America/Montreal+ with +BR2_TARGET_LOCALTIME+ config. Then you find
+   out that +Montreal+ local has been replaced by +Toronto+ (French
+   looks like a rogue language). You enter +make menuconfig+, make the
+   change, save, and run +make+ again. Problem:
+   +output/target/etc/timezone+ still has +America/Montreal+ content!
+
+Solution to this is either to identify which package to reconfigure, or
+remove files manually, or destroy the target filesystem and recreate it.
+This latter option is convenient: you don't have to care about which
+packages to rebuild, and it is quite fast. Here is how to recreate your
+target filesystem, and get rid of filesystem _stains_:
+
+------------------
+make target-clean
+make
+------------------
+
++target-clean+ removes +output/target+. That tells buildroot to recreate
+the target skeleton, and install each package again. This is a
+convenient way to rebuild your target filesystem cleanly without
+rebuilding everything.
diff --git a/docs/manual/rebuilding-packages.txt b/docs/manual/rebuilding-packages.txt
index 6faa67a..82385ae 100644
--- a/docs/manual/rebuilding-packages.txt
+++ b/docs/manual/rebuilding-packages.txt
@@ -39,17 +39,22 @@  can help you understand how to work with Buildroot:
    you would like to have SSL support in +ctorrent+, so you enable the
    +openssl+ package in Buildroot configuration and restart the
    build. Buildroot will detect that +openssl+ should be built and
-   will be build it, but it will not detect that +ctorrent+ should be
-   rebuilt to benefit from +openssl+ to add OpenSSL support. You will
-   either have to do a full rebuild, or rebuild +ctorrent+ itself.
+   will build it, but it will not detect that +ctorrent+ should be
+   rebuilt to benefit from +openssl+ support. You will either have to
+   do a full rebuild, or rebuild +ctorrent+ itself.
 
  * When a package is removed from the configuration, Buildroot does
    not do anything special. It does not remove the files installed by
    this package from the target root filesystem or from the toolchain
-   _sysroot_. A full rebuild is needed to get rid of this
-   package. However, generally you don't necessarily need this package
-   to be removed right now: you can wait for the next lunch break to
-   restart the build from scratch.
+   _sysroot_. To make sure that the target filesystem and _sysroot_
+   reflects your changes, you can use +make target-clean+ as described
+   in xref:clean-target-filesystem[]. Warning! +target-clean+
+   does not fix package dependencies for you. You still have to think
+   twice about what you are attempting. For instance, if you remove
+   +openssl+ needed by +git+, and just +target-clean+ without
+   rebuilding +git+, your rootfs will embed a broken +git+. It will
+   fail to work because it is linked again +openssl+, but this library
+   is not present anymore on your target rootfs.
 
  * When the sub-options of a package are changed, the package is not
    automatically rebuilt. After making such changes, rebuilding only
@@ -59,11 +64,11 @@  can help you understand how to work with Buildroot:
    not track when a package should be rebuilt: once a package has been
    built, it is never rebuilt unless explicitly told to do so.
 
- * When a change to the root filesystem skeleton is made, a full
-   rebuild is needed. However, when changes to the root filesystem
-   overlay, a post-build script or a post-image script are made,
-   there is no need for a full rebuild: a simple +make+ invocation
-   will take the changes into account.
+ * When a change to the root filesystem skeleton is made, clean the
+   target filesystem (xref:clean-target-filesystem[]). However, when
+   changes to the root filesystem overlay, a post-build script or a
+   post-image script are made, this is not needed: a simple +make+
+   invocation will take the changes into account.
 
 Generally speaking, when you're facing a build error and you're unsure
 of the potential consequences of the configuration changes you've