[CMake] How not to copy a link

David Cole david.cole at kitware.com
Wed Jan 11 10:52:23 EST 2012


On Wed, Jan 11, 2012 at 10:10 AM, Michael Hertling <mhertling at online.de> wrote:
> On 01/07/2012 03:52 PM, David Cole wrote:
>> On Sat, Jan 7, 2012 at 9:47 AM, David Cole <david.cole at kitware.com> wrote:
>>> On Fri, Jan 6, 2012 at 10:54 PM, Michael Hertling <mhertling at online.de> wrote:
>>>> On 01/06/2012 07:51 PM, Kevin Burge wrote:
>>>>> Thanks David.  These are external libraries built outside of CMake,
>>>>> without CMake, not imported via any of the import capabilities of cmake,
>>>>> and that need to be installed alongside my CMake built files.  I think
>>>>> I'm just going to do the install with the rename.  Requires me to be
>>>>> more explicit, but, it's not like it changes all that frequently.
>>>>
>>>> Isn't it sufficient to copy such SONAME symlinks as they are, along with
>>>> the actual library files, of course? Having a symlink from the SONAME to
>>>> the library file is a basic mean of the ABI management on platforms with
>>>> advanced - ;-) - support of shared libraries. Besides, these symlinks
>>>> are automatically created by ldconfig when the latter processes the
>>>> directory.
>>>>
>>>> Anyway, w.r.t. your initial question, I'd usually suggest to use the
>>>> GET_FILENAME_COMPONENT(... REALPATH) command on the symlink prior
>>>> to the INSTALL() command, but it seems to not work as expected:
>>>>
>>>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>>>> PROJECT(P NONE)
>>>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>>>> EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E
>>>>    touch xyz.dat.0)
>>>> EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E
>>>>    create_symlink xyz.dat.0 xyz.dat)
>>>> GET_FILENAME_COMPONENT(XYZ xyz.dat REALPATH)
>>>> MESSAGE("XYZ: ${XYZ}")
>>>>
>>>> Due to the documentation of GET_FILENAME_COMPONENT(... REALPATH),
>>>>
>>>> "... the full path with *all* symlinks resolved (REALPATH)."
>>>>
>>>> I'd expect to see
>>>>
>>>> XYZ: .../xyz.dat.0
>>>>
>>>> instead of
>>>>
>>>> XYZ: .../xyz.dat
>>>>
>>>> Do I misunderstand GET_FILENAME_COMPONENT() in respect thereof?
>>>>
>>>> Regards,
>>>>
>>>> Michael
>>>>
>>>>> On 01/06/12 12:45, David Cole wrote:
>>>>>> Have you considered setting the VERSION and SOVERSION target
>>>>>> properties on your libraries instead of doing the symlinks yourself?
>>>>>> CMake will build and install the symlinks automatically for you on
>>>>>> platforms where they are supported if you set these target properties.
>>>>>>
>>>>>> http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:SOVERSION
>>>>>> http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:VERSION
>>>>>>
>>>>>> (Or was that just an example, and you need to do this with other
>>>>>> symlink files that are not simply the version symlinks for a
>>>>>> library...?)
>>>>>>
>>>>>>
>>>>>> HTH,
>>>>>> David
>>>> --
>>>>
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.cmake.org/mailman/listinfo/cmake
>>>
>>> It works if you use:
>>>
>>>  GET_FILENAME_COMPONENT(XYZ ${CMAKE_CURRENT_BINARY_DIR}/xyz.dat REALPATH)
>>>
>>> I'm not 100% sure if the behavior is expected to be defined for
>>> non-full paths. Hopefully Brad sees this and chimes in. If not, I'll
>>> try to remember to ask him about it on Monday.
>>>
>>>
>>> HTH,
>>> David
>>
>>
>> It appears to be resolved w.r.t. the current *source* directory when
>> you do not give the full path, and since "xyz.dat" does not actually
>> exist in the source dir, there's no way we can know that it is
>> supposed to be a symlink.
>>
>> But get_filename_component has to work with non-existing files since
>> some people need that simply to compute where files should go, or what
>> other file's base names should be based on CMake variables alone...
>>
>> Hope that explains it better.
>
> Yes, it does; thanks for straightening this out. Actually, it's rather
> obvious that the ABSOLUTE/REALPATH clauses of GET_FILENAME_COMPONENT()
> do need a reference point, but perhaps, one should document explicitly
> that it's CMAKE_CURRENT_SOURCE_DIR, whereas CMAKE_CURRENT_BINARY_DIR
> won't be taken into account. Elsewhere, CMake behaves differently.
>

Is it CMAKE_CURRENT_SOURCE_DIR? Or is it the current working directory
of the cmake process, which happens to be CMAKE_CURRENT_SOURCE_DIR
when you make the call ...?

>> I know it's *possible* to use non-full paths in many contexts within
>> CMake and still get the results you expect, but because of little
>> nuggets like this, ...
>>
>> ... I always, always, always use full paths anyway, unconditionally. [...]
>
> With ADD_EXECUTABLE() and ADD_LIBRARY(), too? ;-) But seriously...

Yes, even with them. Exception: when I'm editing a CMakeLists file
that pre-dates my involvement, and I'm just making an edit to blend in
with what's there and working already...

And especially with add_custom_command, add_custom_target,
execute_process calls. And file DEPENDS clauses for anything.


>
>> [...] I
>> always recommend to everyone that they also adopt this CMake best
>> practice of referring to files by their full path names whenever
>> possible. It eliminates confusion, ambiguity and unintended mistaken
>> results -- and is 100% absolutely worth the effort.
>
> Definitely agreed, but there're some commands which are typically used
> with relative paths, although it's not explicitly documented how they
> behave in this respect. Notable examples are the already mentioned
> ADD_EXECUTABLE/LIBRARY() or SET_SOURCE_FILES_PROPERTIES() - IMO, the
> latter should behave in the same manner as the formers, so one can use
> the same source file specifications. Perhaps, one could add a few lines
> to the documentation in order to clarify for which commands/properties/
> etc. a relative path does behave well, e.g. like for ADD_SUBDIRECTORY().
>

Better documentation is always a good thing. I will not argue against
improving the documentation.

However:

Using full paths always so that you don't have to remember how
relative paths are treated differently in different contexts is an
even better thing.

The simple fact is: if you always use full paths, you never have to
think about relative paths, and your CMake code will be better.
Because this practice will eliminate a whole slew of possible thinking
and documentation lookup mistakes that you can make along the way.


> Regards,
>
> Michael
> --
>
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake


Sincerely,
David


More information about the CMake mailing list