Discussion:
[CMake] CPack RPM: file XXX conflicts with file from package filesystem-yyy...
Mario Emmenlauer
2018-11-22 14:48:58 UTC
Permalink
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

I can see that the conflicting directories are removed from
CPACK_RPM_INSTALL_FILES. But that does not satisfy rpm :-(

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)

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? 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.

Any help would be greatly appreciated!

All the best,

Mario Emmenlauer
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Eric Noulard
2018-11-22 17:20:45 UTC
Permalink
Post by Mario Emmenlauer
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
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


I can see that the conflicting directories are removed from
Post by Mario Emmenlauer
CPACK_RPM_INSTALL_FILES. But that does not satisfy rpm :-(
Could someone shed some light? I believe that the problem may be
my install command: I call install only once for the full tree
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?
Post by Mario Emmenlauer
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.
Post by Mario Emmenlauer
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"

one more question, could you tell us which version of CPack/CMake you are
using?
--
Eric
Mario Emmenlauer
2018-11-23 10:10:19 UTC
Permalink
Post by Mario Emmenlauer
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
  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
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
Post by Mario Emmenlauer
I can see that the conflicting directories are removed from
CPACK_RPM_INSTALL_FILES. But that does not satisfy rpm :-(
Could someone shed some light? I believe that the problem may be
my install command: I call install only once for the full tree
  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?
Post by Mario Emmenlauer
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?
Post by Mario Emmenlauer
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.
- In the temporary copy, I can override RPATH on binaries and libraries
without changing them in their actual install location.
- 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).
Post by Mario Emmenlauer
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.

All the best,

Mario Emmenlauer
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmak
Eric Noulard
2018-11-23 10:36:29 UTC
Permalink
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
file / from install of <mypackage> conflicts with file from
package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
file /opt from install of <mypackage> conflicts with file from
package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
file /usr/bin from install of <mypackage> conflicts with file from
package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
file /usr/share from install of <mypackage> conflicts with file
from package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
file /usr from install of <mypackage> conflicts with file from
package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
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
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.
Post by Mario Emmenlauer
Could someone shed some light? I believe that the problem may be
Post by Mario Emmenlauer
my install command: I call install only once for the full tree
install(DIRECTORY "${INSTALL_TMP_ROOT}/" DESTINATION "/"
USE_SOURCE_PERMISSIONS)
Post by Mario Emmenlauer
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

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.
Post by Mario Emmenlauer
I have a wild guess that this install somehow includes the
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
RPM requires that any new (non shared) directory should be specified in
the spec file,
Post by Mario Emmenlauer
so CPackRPM tries to "discover that" automatically and make the package
relocatable.
Post by Mario Emmenlauer
Installing a whole directory to an absolute DESTINATION (even "/" in you
case) is probably
Post by Mario Emmenlauer
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.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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"
- 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.
Post by Mario Emmenlauer
- 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
Post by Mario Emmenlauer
- 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).
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
Mario Emmenlauer
2018-11-23 14:37:19 UTC
Permalink
Dear Eric,

thanks a lot for this help! I think I have the pointers to move forward!
Post by Mario Emmenlauer
     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
       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
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
       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
Post by Mario Emmenlauer
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"
 - 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
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.o
Mario Emmenlauer
2018-11-27 13:56:48 UTC
Permalink
Dear Eric,

just to let you know, your suggestion of using a post-install-script
for all system-wide links and files was indeed the solution to a working
RPM package. Now my files are completely encapsulated in /opt/PKGNAME/
and install works fine.

Cheers and Thanks,

Mario
Post by Mario Emmenlauer
Dear Eric,
thanks a lot for this help! I think I have the pointers to move forward!
Post by Mario Emmenlauer
     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
       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
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
       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
Post by Mario Emmenlauer
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"
 - 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
Viele Gruesse,

Mario Emmenlauer


--
BioDataAnalysis GmbH, Mario Emmenlauer Tel. Buero: +49-89-74677203
Balanstr. 43 mailto: memmenlauer * biodataanalysis.de
D-81669 München http://www.biodataanalysis.de/
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org
Eric Noulard
2018-11-27 14:05:08 UTC
Permalink
Post by Mario Emmenlauer
Dear Eric,
just to let you know, your suggestion of using a post-install-script
for all system-wide links and files was indeed the solution to a working
RPM package. Now my files are completely encapsulated in /opt/PKGNAME/
and install works fine.
Thank you very much for the *positive* feedback, we don't always get those
:-)

This is nice to me and probably useful to others knowing it finally works.

Cheers,
Eric

Cheers and Thanks,
Post by Mario Emmenlauer
Mario
Post by Mario Emmenlauer
Dear Eric,
thanks a lot for this help! I think I have the pointers to move forward!
Post by Mario Emmenlauer
Le jeu. 22 nov. 2018 à 16:16, Mario Emmenlauer <
I'm trying to build an RPM with CPack, and everything seems
to work,
Post by Mario Emmenlauer
Post by Mario Emmenlauer
but the resulting package can not be installed. I get
Transaction check
Post by Mario Emmenlauer
Post by Mario Emmenlauer
file / from install of <mypackage> conflicts with file from
package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
Post by Mario Emmenlauer
file /opt from install of <mypackage> conflicts with file
from package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
Post by Mario Emmenlauer
file /usr/bin from install of <mypackage> conflicts with
file from package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
Post by Mario Emmenlauer
file /usr/share from install of <mypackage> conflicts with
file from package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
Post by Mario Emmenlauer
file /usr from install of <mypackage> conflicts with file
from package filesystem-3.2-25.el7.x86_64
Post by Mario Emmenlauer
Post by Mario Emmenlauer
I've read in the CPackRPM source code about how to add
excludes and
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
https://cmake.org/cmake/help/v3.13/cpack_gen/rpm.html#variable:CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
Post by Mario Emmenlauer
my install command: I call install only once for the full tree
install(DIRECTORY "${INSTALL_TMP_ROOT}/" DESTINATION "/"
USE_SOURCE_PERMISSIONS)
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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?
Post by Mario Emmenlauer
Post by Mario Emmenlauer
I'm not sure if I can use a relative path. I want to build a system
package
Post by Mario Emmenlauer
Post by Mario Emmenlauer
that installs to /opt/<package>/ with symlinks in /usr/bin/ and
desktop
Post by Mario Emmenlauer
Post by Mario Emmenlauer
files in /usr/share/applications/. Since files go into different
paths below
Post by Mario Emmenlauer
Post by Mario Emmenlauer
system root (/opt, /usr, maybe /var) I assume I need to install
into root?
Post by Mario Emmenlauer
Post by Mario Emmenlauer
Maybe I misunderstand?
Not really. Usually you install in relative bin/ share/ man/ whatever
other subdir you need.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
Then you define CPACK_PACKAGING_INSTALL_PREFIX (see
https://cmake.org/cmake/help/v3.13/variable/CPACK_PACKAGING_INSTALL_PREFIX.html
)
Post by Mario Emmenlauer
Post by Mario Emmenlauer
to set up your "main" install prefix for your package. Every CPack
generator has a default **packaging install prefix** (not to be confused
with
Post by Mario Emmenlauer
Post by Mario Emmenlauer
CMAKE_INSTALL_PREFIX).
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
Post by Mario Emmenlauer
Post by Mario Emmenlauer
the script itself may call standard symlink creation like
https://linux.die.net/man/8/update-alternatives
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
Sometimes you *really* need absolute prefix like when you install in
/etc/init...
Post by Mario Emmenlauer
Post by Mario Emmenlauer
then for those (generally system) specific file you install them with
absolute destination.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
Post by Mario Emmenlauer
on the individual files?
CPack RPM tries its best to avoid shipping directories he does
not need to ship, but
Post by Mario Emmenlauer
Post by Mario Emmenlauer
RPM requires that any new (non shared) directory should be
specified in the spec file,
Post by Mario Emmenlauer
Post by Mario Emmenlauer
so CPackRPM tries to "discover that" automatically and make the
package relocatable.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
Installing a whole directory to an absolute DESTINATION (even "/"
in you case) is probably
Post by Mario Emmenlauer
Post by Mario Emmenlauer
giving tough time to CPackRPM.
There is something I don't understand: I can see that CPackRPM
removes
Post by Mario Emmenlauer
Post by Mario Emmenlauer
several things from CPACK_RPM_INSTALL_FILES, but later rpm complains
about several of the removed items nonetheless. For example
/usr/bin.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
Does that mean the filtering failed, or does the filter work but
(somehow)
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
I would prefer not to call install on the
individual files because that overrides file permissions for
every
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
- Its easier for me to grasp. I.e. I can nicely inspect the
package and
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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
https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
Post by Mario Emmenlauer
Post by Mario Emmenlauer
- I prefer file(COPY) over install(FILES) because the former can
set
Post by Mario Emmenlauer
Post by Mario Emmenlauer
permissions with complex patterns. I appreciate that file(COPY)
allows
Post by Mario Emmenlauer
Post by Mario Emmenlauer
me to set executable permissions on *.so and binaries with a
single
Post by Mario Emmenlauer
Post by Mario Emmenlauer
invocation (in a loop over many directories).
if you install(TARGET ..) any binaries or .so would have the
appropriate permissions precisely because cmake
Post by Mario Emmenlauer
Post by Mario Emmenlauer
knows what they are and does not consider them as "file" which is the
case for install(FILES).
Post by Mario Emmenlauer
Post by Mario Emmenlauer
one more question, could you tell us which version of CPack/CMake
you are using?
Post by Mario Emmenlauer
Post by Mario Emmenlauer
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.
Post by Mario Emmenlauer
Post by Mario Emmenlauer
install(DIRECTORY ...) is a kind of trap-them-all for things that are
not installed otherwise, this is usually used for things like
Post by Mario Emmenlauer
Post by Mario Emmenlauer
generated documentation and not for "normally built artefact" like
executable, libraries etc...
Post by Mario Emmenlauer
Post by Mario Emmenlauer
--
Eric
Viele Gruesse,
Mario Emmenlauer
--
BioDataAnalysis GmbH, Mario Emmenlauer Tel. Buero: +49-89-74677203
Balanstr. 43 mailto: memmenlauer * biodataanalysis.de
D-81669 MÃŒnchen http://www.biodataanalysis.de/
--
Eric
Loading...