Feature request - make uninstall

Was the possibility of creating a make uninstall script to complement cmake’s make install which would delete all the files listed in install_manifest.txt ever considered? If so, is there any inherent reason why the idea was discarded?

One of the problems could be the removal of files that were installed independently of ROOT. I wonder if there is a way to check if a file was already present and prevent ROOT from writing that file(and thereby prevent it being recorded in the install_manifest.txt)…

Motivation - Existing installations of ROOT seem to conflict with newer builds of ROOT.
I faced an issue recently which was solved by removing the installed ROOT files manually - Build failure with cxx14 and root7 enabled
Also, I faced an issue where I installed a build with pyroot_experimental enabled. Then I installed a build with pyroot_experimental disabled. I sourced the thisroot.sh in my /usr/local/ (where ROOT is installed by default for a system wide installation) and pyroot_experimental features were enabled. (Ofcourse this issue could be worked around with sourcing the thisroot.sh in my build directory)

I support this feature. From what I understand cmake does not allow natively to do “make uninstall” but for this sure, such feature would be really useful. I think you should open a JIRA ticket to track this feature request.

Related pull request - https://github.com/root-project/root/pull/3405

2 Likes

As discussed in the pull request, I think that adding make uninstall is not a good idea. If you install a custom ROOT compiled by hand, just install into a custom directory like /opt/root-6.16 or similar, which you can just remove later to uninstall. With make uninstall it’s too easy to break things by changing configuration between calls to make install / make uninstall which will leave you with a half-uninstalled ROOT, or worse, with important files removed from the system that were installed by other means. It’s already possible to “uninstall” with xargs rm < install_manifest.txt from the build directory in any case if you really need it. The issue you described, however, is due to sourcing more than one thisroot.sh in the same shell, which will mess up the environment. Just start with a fresh shell and source only one thisroot.sh file, or put $ROOTSYS/bin in $PATH and $ROOTSYS/lib in $PYTHONPATH only, without sourcing thisroot.sh.

@Wile_E_Coyote I think that what you say in your linked post is no longer true. It’s perfectly possible now to use, for example, Fedora, and use ROOT that you get with yum install root. It’s usually the latest version or close to latest, and incompatibilities are not such a big issue anymore. You may only need to install a separate version of ROOT 5 if your own scripts do not work with ROOT 6, but that’s only 1 custom version of ROOT 5.34. Also, in Gentoo Linux I made it possible to install ROOT 6.12, 6.14, 6.16, and master, all along side each other and “system-provided”. For example, you can try it out by running (not sourcing) /cvmfs/sft.cern.ch/lcg/contrib/gentoo/linux/x86_64/startprefix from any Linux distribution and then run root-6.12, root-6.16, etc, as they will be in $PATH already.

If we installed ROOT in /opt/root, there is indeed no interest to use “make install”. The advantage of “make uninstall” is clear when we did not specify any install prefix and then ROOT has been installed in /usr/local.
If it breaks something on Mac OS, maybe some “workaround” exists (I do not know this OS) but on Linux, I am not aware of such issues.
If we compiled ROOT and installed it in /usr/local, what is the solution to properly uninstall it in order to avoid version mix?

Sourcing more than one thisroot.sh in the same shell, MUST NOT mess up the environment. This script IS EXPECTED to clean any environment variables which reference the “previous” version and then add appropriate entries for the “new” version.

1 Like

If you installed more than one compiled ROOT into /usr/local they will have partially overwritten each other’s files. There’s not much that can be done in that case to restore a consistent installation. You can, however, use xargs rm < install_manifest.txt, as suggested in CMake’s own FAQ, which is equivalent to the make uninstall target that the pull request creates, but requires no changes to ROOT.

I believe that is indeed what happens (@amadio correct me if I’m wrong) . I never had problems sourcing more than one thisroot.sh in the same shell.

Building ROOT with an active thisroot.sh, however, can be tricky.

In my “old post”, I explicitly warn against it.

This was one of my main motivations for proposing the make uninstall feature, so that the user is able to set up a clean system before building ROOT again.

The ultimate solution is to install all needed versions of ROOT, but each version in a different “version specific” ROOTSYS subdirectory.

See also:

That’s just not possible if you install ROOT into /usr/local or another path that is there by default. For example, you cannot tell the loader to stop looking for libraries into directories that are listed in /etc/ld.so.conf, regardless of what LD_LIBRARY_PATH is set to. Same for CMAKE_PREFIX_PATH default paths. In any case, the script also does not account for the fact that @libdir@ may not be $ROOTSYS/lib, but $ROOTSYS/lib64 when removing paths, which will leave the old directory in place, etc (although this is indeed a problem with the script itself). In my opinion the scripts thisroot.* should not be installed with ROOT at all, as they are only a workaround to let people use ROOT from the build directory, which I think is a very bad idea. If you install ROOT with make install, thisroot.* should not be used. I never use these scripts myself and never had the sort of problems described above with mixed up environments.

Absolutely, but what if the user already has a system wide installation of ROOT?
(Ofcourse as @amadio pointed out, xargs rm < install_manifest.txt does the same thing as make uninstall)

Is it not explicitly mentioned in the very first and the very last sentences of my “old post” (and also in some sentences inside which explicitly say “purge”)?

My apologies, I misread.