[CMake] CPack RPM: file XXX conflicts with file from package filesystem-yyy...
Mario Emmenlauer
mario at emmenlauer.de
Fri Nov 23 09:37:19 EST 2018
Dear Eric,
thanks a lot for this help! I think I have the pointers to move forward!
One more detail below:
On 23.11.18 11:36, Eric Noulard wrote:
> Le ven. 23 nov. 2018 à 11:10, Mario Emmenlauer <mario at emmenlauer.de <mailto:mario at emmenlauer.de>> a écrit :
> Dear Eric, thanks for the help! Below more:
>
> On 22.11.18 18:20, Eric Noulard wrote:
> > Le jeu. 22 nov. 2018 à 16:16, Mario Emmenlauer <mario at emmenlauer.de <mailto:mario at emmenlauer.de> <mailto:mario at emmenlauer.de
> <mailto:mario at emmenlauer.de>>> a écri
> > I'm trying to build an RPM with CPack, and everything seems to work,
> > but the resulting package can not be installed. I get Transaction check
> > error:
> > file / from install of <mypackage> conflicts with file from package filesystem-3.2-25.el7.x86_64
> > file /opt from install of <mypackage> conflicts with file from package filesystem-3.2-25.el7.x86_64
> > file /usr/bin from install of <mypackage> conflicts with file from package filesystem-3.2-25.el7.x86_64
> > file /usr/share from install of <mypackage> conflicts with file from package filesystem-3.2-25.el7.x86_64
> > file /usr from install of <mypackage> conflicts with file from package filesystem-3.2-25.el7.x86_64
> >
> > I've read in the CPackRPM source code about how to add excludes and
> > CPackRPM says that my "Final list of path to OMIT in RPM" would be
> > /etc;/etc/init.d;/usr;/usr/bin;/usr/include;/usr/lib;/usr/libx32;/usr/lib64;/usr/share;/usr/share/aclocal;/usr/share/doc;/opt;/usr/share/applications
> >
> >
> > You can read the doc too:
> > https://cmake.org/cmake/help/v3.13/cpack_gen/rpm.html#variable:CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST
>
> Haha, done that! I've read everything I could find, including the
> docs and the excellent but hard-to-find community wiki at
> https://gitlab.kitware.com/cmake/community/wikis/home
>
>
> OK then you are up-to-doc then.
>
> > Could someone shed some light? I believe that the problem may be
> > my install command: I call install only once for the full tree
> > of files that I'd like to package:
> > install(DIRECTORY "${INSTALL_TMP_ROOT}/" DESTINATION "/" USE_SOURCE_PERMISSIONS)
> >
> > Yep this is looking for trouble.
> > How did you build the "${INSTALL_TMP_ROOT}" in the first place?
> >
> > Can't you use relative path install DESTINATION ? For all files/target you build?
>
> I'm not sure if I can use a relative path. I want to build a system package
> that installs to /opt/<package>/ with symlinks in /usr/bin/ and desktop
> files in /usr/share/applications/. Since files go into different paths below
> system root (/opt, /usr, maybe /var) I assume I need to install into root?
> Maybe I misunderstand?
>
>
> Not really. Usually you install in relative bin/ share/ man/ whatever other subdir you need.
> Then you define CPACK_PACKAGING_INSTALL_PREFIX (see https://cmake.org/cmake/help/v3.13/variable/CPACK_PACKAGING_INSTALL_PREFIX.html)
> to set up your "main" install prefix for your package. Every CPack generator has a default **packaging install prefix** (not to be confused with
> CMAKE_INSTALL_PREFIX).
> In your case:
> set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
> which should even be (AFAIR) the default value for RPM and DEB.
>
> Concerning the symlink in /usr/bin (or other places /usr/share etc...) this usually done using post-install script
> https://cmake.org/cmake/help/v3.13/cpack_gen/rpm.html#variable:CPACK_RPM_SPEC_MORE_DEFINE
>
> the script itself may call standard symlink creation like https://linux.die.net/man/8/update-alternatives
Aha, now I see the recommended approach! Makes perfect sense! So I will
continue to bundle up everything, but try to avoid files outside my
man package directory (for me /opt/${PROJECT_NAME}). Then I will make
the system integration (to /usr/bin, /usr/share, etc) via symlinks
and update-alternatives in post-install scripts. This makes perfect
sense, I'm sorry I did not think of it myself!
All the best,
Mario
> Sometimes you *really* need absolute prefix like when you install in /etc/init...
> then for those (generally system) specific file you install them with absolute destination.
> CPackRPM is able to handle those as "config" file automatically.
>
> > I have a wild guess that this install somehow includes the
> > directories, and probably it would be better to just call install
> > on the individual files?
> >
> > CPack RPM tries its best to avoid shipping directories he does not need to ship, but
> > RPM requires that any new (non shared) directory should be specified in the spec file,
> > so CPackRPM tries to "discover that" automatically and make the package relocatable.
> >
> > Installing a whole directory to an absolute DESTINATION (even "/" in you case) is probably
> > giving tough time to CPackRPM.
>
> There is something I don't understand: I can see that CPackRPM removes
> several things from CPACK_RPM_INSTALL_FILES, but later rpm complains
> about several of the removed items nonetheless. For example /usr/bin.
> Does that mean the filtering failed, or does the filter work but (somehow)
> the directory still ends up being packaged?
>
>
> Evil usually hides in details.
>
> Difficult to say without having the actual code and package to look into it.
> Is your project public? If so could you provide us with the source?
>
> If not tries to setup a stripped down public project that exhibit the same issue.
>
>
> > I would prefer not to call install on the
> > individual files because that overrides file permissions for every
> > file, and I carefully prepared my package upfront to have the
> > exact permissions for installation.
> >
> >
> > How did you "carefully prepared my package upfront" ?
> > And what do you mean by
> > "because that overrides file permissions for every file"
>
> Currently I bundle my package in a temporary directory for three reasons:
> - Its easier for me to grasp. I.e. I can nicely inspect the package and
> see what will be bundled before the fact.
>
>
> make/ninja DESTDIR=/tmp/testinstall all
>
> may be used equally for that.
>
>
> - In the temporary copy, I can override RPATH on binaries and libraries
> without changing them in their actual install location.
>
>
> If you have a "clean" prefix and relative install path for all binaries then you can safely use $ORIGIN
> see: https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
>
>
>
> - I prefer file(COPY) over install(FILES) because the former can set
> permissions with complex patterns. I appreciate that file(COPY) allows
> me to set executable permissions on *.so and binaries with a single
> invocation (in a loop over many directories).
>
>
> if you install(TARGET ..) any binaries or .so would have the appropriate permissions precisely because cmake
> knows what they are and does not consider them as "file" which is the case for install(FILES).
>
>
> > one more question, could you tell us which version of CPack/CMake you are using?
>
> I'm on the latest cmake 3.13 as of now, but I tested 3.12.4 as well.
>
>
> Then you have all bleeding edge feature with you.
>
> I'm not trying to tell you what to do with your install, I'm just trying what CPack expects.
>
> install(DIRECTORY ...) is a kind of trap-them-all for things that are not installed otherwise, this is usually used for things like
> generated documentation and not for "normally built artefact" like executable, libraries etc...
>
>
> --
> Eric
More information about the CMake
mailing list