Notes |
|
(0025765)
|
Eric NOULARD
|
2011-03-13 16:24
|
|
I did try a blind fix with this commit:
Merge topic 'CPackRPM-TestWithMoreTraces' into next
a201028 CPack try to please SUSE 64 bits and install lib in lib64 and not lib. |
|
|
(0025766)
|
Eric NOULARD
|
2011-03-13 18:17
|
|
Looks like the lib vs lib64 thing is written in:
www.x86-64.org/documentation/abi.pdf
p123:
A.1 Execution of 32-bit Programs
The AMD64 processors are able to execute 64-bit AMD64 and also 32-bit ia32
programs. Libraries conforming to the Intel386 ABI will live in the normal places
like /lib, /usr/lib and /usr/bin. Libraries following the AMD64, will
use lib64 subdirectories for the libraries, e.g /lib64 and /usr/lib64. Pro-
grams conforming to Intel386 ABI and to the AMD64 ABI will share directories
like /usr/bin. In particular, there will be no /bin64 directory.
And it looks like Debian did not follow the rule:
http://gcc.gnu.org/ml/gcc-help/2010-11/msg00359.html [^] |
|
|
(0025767)
|
Eric NOULARD
|
2011-03-13 18:19
|
|
Copy/Paste message from ML, as a reminder.
On my Debian 64 bits box I have:
$ ls -ld /usr/lib*
drwxr-xr-x 311 root root 151552 12 mars 23:30 /usr/lib
drwxr-xr-x 33 root root 45056 29 janv. 10:18 /usr/lib32
lrwxrwxrwx 1 root root 3 31 déc. 2008 /usr/lib64 -> lib
drwxr-xr-x 3 root root 4096 1 janv. 2009 /usr/libexec
As you can see /usr/lib is the 'native' lib dir, with lib64 being a
link to this.
Then lib32 is the 32bits 'non-native' one.
This layout seems reasonable, I'll check on Fedora 64 or other RPM based
distros during this week.
Now I may teach CPackRPM to detect if it is running on Fedora or SUSE
or Mandriva etc..
and do some nasty things like renaming lib destination into lib64
if we are packaging a 64 bit package but I currently find it weird.
The rpm installer (the rpm command) or packager (rpmbuild) perfectly knows
that we are building a natively 64 bits RPM package it's even written in the RPM
using "Architecture" field so if he wants to enforce to put 64 bits
libs into lib64
he may do it by itself and not asking the packager to do it.
Currently I would say that rpm build policy on SUSE 64 bits
is the culprit not CPackRPM (which is simply calling RPM build).
However, I'll investage further because up to now I did never face
such 32/64 bits issue
even if I use natively 64 bits linux systems since at least 5 years...
Slackware seems to be using lib${LIBDIRSUFFIX}
http://www.mail-archive.com/slackbuilds-users@slackbuilds.org/msg01569.html [^]
Others (like at least Fedora, RedHat, Mandriva)
seems to be using builtin RPM "%_libdir" macros.
The thing is currently with cpack the user chose the library/runtime
destination
so if he chose 'lib' shall we go with "lib64" should be safe but
if the installation prefix is not '/usr' but '/opt/' or '/anywhere/you/want'
shall we do the lib-->lib64 automatic renaming.
Any insight or reference about this 32/64 bits lib mixup is welcomed. |
|
|
(0025768)
|
Rolf Eike Beer
|
2011-03-14 03:42
|
|
Gentoo also has a link lib -> lib64, at least on my AMD64-nomultilib installations.
Ideally this would not be part of the CPack stuff, but only used by it so things like that would just do the right thing:
INCLUDE(NativeLibraryDir)
ADD_LIBRARY(foo SHARED foo.c)
INSTALL(TARGETS foo DESTINATION ${NATIVE_LIBRARY_DIR}) |
|
|
(0025771)
|
Eric NOULARD
|
2011-03-14 07:49
|
|
I've done some verification all the following 64 bits distribution
- OpenSUSE Linux 11.4
- Fedora Core 14
- Mandriva 2010.2
do have separate:
/usr/lib --> for 32 bits libs
/usr/lib64 --> for 64 bits libs
this is the same for
/lib and /lib64
/usr/local/lib and /usr/local/lib64
so since other distro (at least debian based and gentoo) do have
a link lib-->lib64, it should be safe to always install lib
in lib64 if the package is a 64 bits package. |
|
|
(0025772)
|
Marcel Loose
|
2011-03-14 08:18
|
|
There is this IMHO weird ambiguity in CMake between find_library() that uses lib64 to search for libraries (if FIND_LIBRARY_USE_LIB64_PATHS is TRUE), and install() that only installs in lib64 if you explicitly specify 'lib64' as DESTINATION. I don't know if this is somehow related to the CPackRPM issue, though. |
|
|
(0025773)
|
Eric NOULARD
|
2011-03-14 08:59
|
|
Hi Marcel,
Where is the "FIND_LIBRARY_USE_LIB64_PATHS" variable documented?
Is it defined by CMake or should the user define it?
I think , I'll soon recast this bug into something
wider than the CPackRPM concerns.
In fact if the majority of 64bits linux distros
and x86-64 ABI document advocate the use of 'lib64'
for 64bits libs and 'lib' for 32bits ones then
CMake should provided a way to **automatically** install
libraries in lib for 32bits and lib64 for 64bits.
I imagine (at least) 2 differents solutions:
A) This could be a new
CMAKE_LIBDIR_NAME var which could be set by CMake
and then used in install command (as suggested by Eike).
B) Or alternatively CMAKE_LIBDIR_SUFFIX
which would be added to the
LIBRARY DESTINATION
and
ARCHIVE DESTINATION
this could be used by find_library too.
Now B) can be set by CMake or set/overriden by the user.
CMake may at least do it by itself
if CMAKE_SYSTEM_NAME == Linux and CMAKE_SIZEOF_VOID_P == 8.
When CMAKE_LIBDIR_SUFFIX is set (by CMake or by the User)
[and we are not cross-compiling]
the install generator could be made smart enough to
replace "lib[/whatever]" relative path by
"lib${CMAKE_LIBDIR_SUFFIX}[/whatever]"
What do you think? |
|
|
(0025775)
|
Marcel Loose
|
2011-03-14 10:57
|
|
"FIND_LIBRARY_USE_LIB64_PATHS is a global scope property. It is defined by CMake, but the user may override it (if she so desires).
I think I favor option B). It feels a bit cleaner and matches with the use of CMAKE_*_LIBRARY_SUFFIX.
It does need some tweaking of the C++ implementation as well, because the current cmFindLibraryCommand.* and cmFindPackageCommand.* already do some name juggling of lib<->lib64 depending on whether FIND_LIBRARY_USE_LIB64_PATHS is set or not. |
|
|
(0025776)
|
Eric NOULARD
|
2011-03-14 16:15
|
|
What should we use for CMAKE_LIBDIR_SUFFIX
should we use a property or a variable? |
|
|
(0025778)
|
Rolf Eike Beer
|
2011-03-15 02:12
|
|
I think a variable would be best, otherwise you always need to query the property before doing INSTALL(TARGET foo DESTINATION ...).
And for the cross compiling case we need that to be set to lib32 on those platforms where it is needed (like your Debian).
The other version would be that the value of that property would override every target destination given as "lib" when CMAKE_LIBRARY_PATH_LIB_OVERRIDE set to true (or whatever) but I think that is not very intuitive. |
|
|
(0025779)
|
Marcel Loose
|
2011-03-15 04:12
|
|
IMO a global property would be more logical, because there's already a FIND_LIBRARY_USE_LIB64_PATH property. A new property INSTALL_LIBRARY_USE_LIB64_PATH could be defined for this. You normally don't want to override this setting, so it could be defined by of CMake's initialization modules. Or maybe it should be a shorter, more general property name, like CMAKE_USE_LIB64_PATH. |
|
|
(0025780)
|
Eric NOULARD
|
2011-03-15 05:25
|
|
I think that the property idea is meant to be "automatic".
If CMake (or the user) does:
set_property(GLOBAL PROPERTY CMAKE_LIBDIR_SUFFIX "64")
then CMake will append this suffix for any ARCHIVE or LIBRARY
destination found in
install(TARGETS myExe mySharedLib myStaticLib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
which would transparently (for the user) became
install(TARGETS myExe mySharedLib myStaticLib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib64
ARCHIVE DESTINATION lib64/static)
now since this should only be done on linux x86_64
for a limited set of directories:
(.*)/lib[/(.*)]* -> (.*)/lib64[/(.*)]*
so we could even do:
set_property(GLOBAL PROPERTY
CMAKE_LIBRARY_DESTINATION_REPLACE "(.*)/lib[/(.*)]*;(.*)/lib64[/(.*)]*")
set_property(GLOBAL PROPERTY
CMAKE_ARCHIVE_DESTINATION_REPLACE "(.*)/lib[/(.*)]*;(.*)/lib64[/(.*)]*")
but may be
set_property(GLOBAL PROPERTY CMAKE_USE_LIB64_PATH TRUE)
could be simpler and more appropriate.
The suffix idea is more versatile but I don't really know if it is
not just simply overkilling the need.
I think we want to do this somehow "globally" because I cannot
(but I may be wrong) imagine someone wanting to do that for one lib
and not for the other.
Opinion? |
|
|
(0025781)
|
Marcel Loose
|
2011-03-15 06:02
|
|
Yes, I think too that this should be a global property. My idea is also that the lib vs. lib64 handling is done transparently to the user, just like Eric wrote. I think having a user-definable suffix is overkill; personally I don't see any use for it.
Most of this behind-the-scenes stuff should be implemented in the C++ part, I guess. |
|
|
(0025785)
|
Rolf Eike Beer
|
2011-03-15 10:57
|
|
That still leaves the question: how would that work when building 32 bit libraries on 64 bit Debian then? As /lib/ should be replaced by /lib32/ then to be consistent. |
|
|
(0025786)
|
Eric NOULARD
|
2011-03-15 11:13
|
|
Building 32bits on a native 64bits is somehow cross-compiling.
I'll think about it.
How do you to build 32bits on debian (or other) 64bits distro?
Do you manually add "-m32" ? |
|
|
(0025789)
|
Eric NOULARD
|
2011-03-15 14:28
|
|
|
|
(0025829)
|
Eric NOULARD
|
2011-03-19 10:40
|
|
I've just merged a fix on next.
Merge topic 'linux-lib64-handling' into next
d515479 fix 0011964 withe the use of a new CMAKE_USE_LIB64_PATH property
I did use a new global property:
CMAKE_USE_LIB64_PATH.
When this property is true then the path found in
DESTINATION ARCHIVE
or
DESTINATION LIB
are mangled by replacing occurrence of 'lib' by 'lib64'.
It is done in 3 differents contexts:
lib
<whatever>/lib
lib/<whatever>
so that 'librarian' won't be renamed to 'lib64brarian'.
The property is automatically set by CMake:
- FALSE is the default value on UnixPaths.cmake
- TRUE in Linux.cmake if we are on a x86_64 system
but not on Debian based systems
The property may be overriden by the user in its CMakeLists.txt. |
|
|
(0025830)
|
Eric NOULARD
|
2011-03-19 10:41
|
|
I think the issue is resolved even if we will have
to handle the "32 bits" on "64bits" debian system case.
I think this is a kind of cross-compilation case which needs
to be discussed separately. |
|
|
(0025831)
|
Eric NOULARD
|
2011-03-19 10:42
|
|
|
|
(0025865)
|
Brad King
|
2011-03-22 15:29
|
|
Reopening due to SimpleInstall test trouble. |
|
|
(0025866)
|
Brad King
|
2011-03-22 15:33
|
|
|
|
(0025867)
|
Brad King
|
2011-03-22 15:51
|
|
Since I reverted the original commits you'll have to rebase and rewrite them to publish them again. We'll review and discuss this feature here. Please push future versions to the stage but do not merge them to next until we're done.
The corresponding property for find_library is called "FIND_LIBRARY_USE_LIB64_PATHS". This one affects the install() commands so it should be called "INSTALL_USE_LIB64_PATHS".
Further comments may follow. |
|
|
(0025869)
|
Brad King
|
2011-03-22 16:02
|
|
I see no reason to do this only for ARCHIVE and LIBRARY destinations. A RUNTIME file may be installed in lib/myproj if it is a private helper executable. Do it for all destination types.
In DoMangleLibDestination consider using cmSystemTools::SplitPath, then transform each component as lib->lib64 trivially, and then use JoinPath to recombine the destination. |
|
|
(0025870)
|
Brad King
|
2011-03-22 16:12
|
|
Unlike the find_library command whose result can easily be overridden by a cache entry, this feature introduces a major change in behavior for existing code on existing platforms. Other than an obscure test failure and a semi-standard design document is there any reason to enable this by default? Ideally all applications should allow their destinations to be configured. This magic lib->lib64 transformation is nice to help the switch all destinations at once. However, it will also lead to surprising behavior like:
$ cat CMakeLists.txt
install(... DESTINATION lib)
...
$ make install
Installing .../lib64/...
$ wtf?
|
|
|
(0025878)
|
Marcel Loose
|
2011-03-23 04:41
|
|
And another note of caution. If you're "cross-compiling" a 32-bit application on a 64-bit RedHat-like system, you DON'T want the libraries to be installed in lib64, but in lib. Ditto for Debian-like systems; there you want the libraries to be installed in lib32. |
|
|
(0025881)
|
Eric NOULARD
|
2011-03-23 09:12
|
|
Hi Brad and Marcel,
Thank you Brad for re-opening this.
I should have re-opened it but I wasn't able to access the tracker at that time.
I was clearly too confident for this patch.
I won't push it to next until we are OK.
Concerning the "magic" aspect, you may be right
I'm beginning to think that this may not be
a good goal to achieve "total" transparency.
May be we could just:
1) Guess for any system the "preferred" LIBDIR and
set a new variable
CMAKE_SYSTEM_PREFERRED_LIBDIR_NAME
that would evaluate to lib, lib32 or lib64 or whatever.
2) Let the user use this variable in its INSTALL rules or not.
3) Make some enhancement in concerned CPack generators
(mainly CPackRPM and CPackDeb) in order to spit out a warning
(or an error) when 'lib' is used where Linux system standard
expects lib64, lib32, libWhatever...
As you mentioned the black magic of the behind the scene rename
may simply be too cryptic.
Concerning the 32bits compile on 64bits systems I continue to think
that this is a kind of cross-compiling. If it's not and we expect
to be able to build both 32 and 64 bits executables/lib in the same
tree we could define a
CMAKE_SYSTEM_PREFERRED_LIBDIR32_NAME as well. |
|
|
(0025883)
|
Marcel Loose
|
2011-03-23 09:52
|
|
Hi Eric,
I would prefer a property like INSTALL_LIBRARY_USE_LIB64_PATH, to be more in line with FIND_LIBRARY_USE_LIB64_PATH.
I don't mind a bit of under-the-hood smartness. As a user, I would expect find_library() and install() to behave similarly when it comes to handling library paths. At the moment, that is not the case.
So, if we decide to add a property like INSTALL_LIBRARY_USE_LIB64_PATH, then it could be initialized to the same value as INSTALL_LIBRARY_USE_LIB64_PATH. The install() command should always honor the value of INSTALL_LIBRARY_USE_LIB64_PATH. Advantage of this automatic library path handling is that the user doesn't have to remember to set this variable when on RedHat-like systems (something he might very well forget).
W.r.t. compiling 32-bit code on a 64-bit system: you may be right that this should be considered cross-compilation. My guess is that find_library() will also fail in these cases, unless you explicitly tell CMake that you're doing cross-compilation (though Brad may prove me wrong). |
|
|
(0025884)
|
Eric NOULARD
|
2011-03-23 10:51
|
|
Hi Marcel,
I'm basically OK with the fact that INSTALL_LIBRARY_USE_LIB64_PATH
and FIND_LIBRARY_USE_LIB64_PATH should be set to coherent values
and/or be tight together in some way (e.g.setting one this to TRUE
implies the other is true too), or simply use FIND_LIBRARY_USE_LIB64
as an indication for INSTALL to behave likewise.
Now the main difference between find_library and install is,
as stated by Brad, is that find library gives you a result you
may perfectly override. If install is doing nasty renaming behind
you back you may be bitten by unexpected effect.
Have look at what is done by Tests/SimpleInstall and Tests/SimpleInstallS2
and you'll soon discover that there is a wealth of way to break
and automated lib->lib64 renaming.
For example I'm not a MacOS user but this var CMAKE_INSTALL_NAME_DIR
may give us some trouble,
I know the lib64 thing shouldn't be activated on MacOS, but I'm not
sure to have examined all possible VAR-configured or PROPERTY-tunable
lib-related features offered by CMake.
As Brad said if the user expect to find the lib in
${CMAKE_INSTALL_PREFIX}/MyTest/lib
then he may do something like (taken from SimpleInstall test)
# Make sure the test executable can run from the install tree.
SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES
INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
and it will fail because the lib has been installed in
${CMAKE_INSTALL_PREFIX}/MyTest/lib64.
Now we should automatically track:
- DESTINATION (ARCHIVE, LIBRARY and RUNTIME) for lib in INSTALL commands
- INSTALL_RPATH target properties
- CMAKE_INSTALL_RPATH variable value
- ... what else
have a look at http://www.vtk.org/Wiki/CMake_RPATH_handling [^]
and tell me there is no other possible interaction.
Basically the "automatic" behavior will certainly be ok for
mainstream non-exotic installation & packaging and will
fail with subtle black magic interaction in other cases.
I'm not sure I want to:
1) take time to seek every possible interaction
2) maintain that in the long term
The main reason is that in a may-be-not-to-far-away future,
the situation may even be more complicated:
https://wiki.ubuntu.com/MultiarchSpec [^]
So in the end offering the average user to
**explicitely** use sensible default value computed by CMake
for libdir in it install rule seem enough.
Afterwards if people want to use fancy non-standard
library install location, they could do it as well.
I don't want them to begin to file bug-report because
the automated CMake behavior broke their scheme.
What do you think? |
|
|
(0025888)
|
Brad King
|
2011-03-23 14:27
|
|
Re 0011964:0025884: Great summary, Eric. I agree that the easiest solution is simply to provide a "preferred" library directory name computed based on the target platform of the build. Project code can then use this as the default wherever it might otherwise have used "lib". It is then up to the project to use it consistently.
This actually overlaps with issue 0003976 whose contributed patch I've been meaning to tweak and accept (0003976:0025620). |
|
|
(0025890)
|
Brad King
|
2011-03-23 14:48
|
|
|
|
(0025894)
|
Marcel Loose
|
2011-03-24 06:26
|
|
That looks good. If indeed these variables will be set to sensible defaults, also and especially for the lib/lib64 issue, then AFAIC this issue is solved. It might be that I'm overlooking things, since I've never really delved into the intricacies of building packages with CPack, like Eric did, and I've never developed for Mac OS with its multi-arch binaries. |
|
|
(0025909)
|
Eric NOULARD
|
2011-03-25 17:22
|
|
Hi All,
Thank you Brad.
I did have a look at 0003976.
It looks reasonable to put the lib64 default into this module.
Since the module may be loaded even if C is not enabled [yet]
I shall add the same logic I added in Linux.cmake in the immature patch
in order to check whether if we are on a Linux non-debian 64 bit host.
Then
set(CMAKE_INSTALL_LIBDIR "lib64" etc...
I'll try that by the end of the week-end or next week. |
|
|
(0025910)
|
Brad King
|
2011-03-25 17:31
|
|
Eric, I think it is reasonable to demand that languages be enabled before including this file if authors want this behavior. You could simply check to make sure at least one language is available and CMAKE_SIZEOF_VOID_P has been set and warn if not. |
|
|
(0025912)
|
Eric NOULARD
|
2011-03-26 10:05
|
|
Hi Brad,
I've pushed this second try to stage/linux-lib64-handling-v2:
To git@cmake.org:stage/cmake.git
* [new branch] HEAD -> linux-lib64-handling-v2
Would you like to test it on your side before I merge to next?
This time it should be harmless unless it is used.
I did use it in Tests/CPackComponentForAll however I do not
have any non-debian linux 64 bits hosts at hand to testdrive it.
I may have one on monday at work but I'm not sure I'll have time
to do it. |
|
|
(0025921)
|
Brad King
|
2011-03-28 09:07
|
|
Thanks for working on this, Eric. Good start. I have a couple comments on the current patch (410f4c7f).
(1) The message(WARNING) should be message(AUTHOR_WARNING) because it is the project author that made a mistake.
(2) Please write a more descriptive commit message. Someone reading that in 2 years will have no idea what "second try" means. Describe the change and its motivation as if you were writing high-level instructions for someone else to write the patch.
(3) In order to base work on a topic that is in next but not master, do one of these:
git checkout -b linux-lib64-handling stage/gnu-install-dirs-issue-3976
or if you also need to base it on something in master that was merged since the topic started:
git branch gnu-install-dirs-issue-3976 stage/gnu-install-dirs-issue-3976
git checkout -b linux-lib64-handling origin/master
git merge gnu-install-dirs-issue-3976
git branch -d gnu-install-dirs-issue-3976
The commit message created by this type of merge should not mention the 'stage' at all. |
|
|
(0025946)
|
Eric NOULARD
|
2011-03-28 15:22
|
|
Hi Brad,
The new 'linux-lib64-handling' branch should follow your advices,
I have just pushed it:
To git@cmake.org:stage/cmake.git
* [new branch] HEAD -> linux-lib64-handling
I may merge it to next if you are OK (or you may do it yourself).
Be warned I cannot test this on my computer so it may be worth
a try on non-debian 64bits host before merging. |
|
|
(0025947)
|
Eric NOULARD
|
2011-03-28 15:26
|
|
By the way I removed the buggy branch from stage. |
|
|
(0025949)
|
Eric NOULARD
|
2011-03-29 05:48
|
|
I just tested the new linux-lib64-handling
on a 64bits OpenSUSE 11.4 box
and it works as expected.
Moreover all the CMake tests passed
(including previously failing SimpleInstall*)
which is logical because the current patch does not
change the behavior unless one uses GNUInstallDirs.cmake :-] |
|
|
(0025988)
|
Brad King
|
2011-03-31 13:36
|
|
Re 0011964:0025949:
This is good, except for one bug. You can't use the FORCE option to override the default because that will run every time. We still need to honor any user-set value in the cache. The typical way to choose a default dynamically for a CACHE entry is this:
set(_LIBDIR_DEFAULT "lib")
if(...)
set(_LIBDIR_DEFAULT "lib64")
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})") |
|
|
(0025989)
|
Brad King
|
2011-03-31 13:40
|
|
FYI, today we merged the GNUInstallDirs module topic to master. I rebased the linux-lib64-handling topic on the new master and pushed it back to the stage to simplify the history shape. Please fetch that topic and rewrite it to address 0011964:0025988. |
|
|
(0025990)
|
Eric NOULARD
|
2011-03-31 14:21
|
|
Ok,
Sorry for CACHE FORCE misuse, I'm not using CACHE entry so much.
Should be ok now:
To git@cmake.org:stage/cmake.git
ce7e686..268502a linux-lib64-handling -> linux-lib64-handling |
|
|
(0025991)
|
Eric NOULARD
|
2011-03-31 14:23
|
|
By the way,
I did not merge it to next in order to let you have a last look :-) |
|
|
(0025992)
|
Brad King
|
2011-03-31 14:49
|
|
|