[CMake] INSTALL when source file is already at DESTINATION?

Gregory Peele ARA/CFD gpeele at ara.com
Thu Dec 16 11:02:30 EST 2010


> -----Original Message-----
> From: Eric Noulard [mailto:eric.noulard at gmail.com]
> Sent: Thursday, December 16, 2010 2:48 AM
> To: Gregory Peele ARA/CFD
> Cc: cmake at cmake.org
> Subject: Re: [CMake] INSTALL when source file is already at
> DESTINATION?
> 
> 2010/12/16 Gregory Peele ARA/CFD <gpeele at ara.com>:
> > Hi all,
> >
> > What is the expected behavior is for INSTALL (TARGETS) when the
> source file
> > for a particular destination is already at the relevant DESTINATION?
> For
> > example, this could happen with a  Unix Makefile generator for
> "LIBRARY
> > DESTINATION lib" when CMAKE_INSTALL_PREFIX/lib and
> > CMAKE_LIBRARY_OUTPUT_DIRECTORY are the same path - the latter having
> been
> > set differently than the default of course.
> >
> > In practice it seems like this case works fine for all types of
> targets in
> > Windows/MSVC generators, and fails only for shared objects in
> Linux/Unix
> > Makefiles.  It might even only fail for shared objects with SOVERSION
> > symlinks but I haven't confirmed that yet.    The actual shared
> library is
> > being deleted at some point after build (leaving a dangling symlink)
> and
> > then the INSTALL step fails because its source file is missing.
> 
> Would you have an example with file names?
> For example I have some shared lib with so version and I get (in the
> build dir)*
> 
> (1) libCERTId.so -> libCERTId.so.3
> (2) libCERTId.so.3 -> libCERTId.so.3.4.1cvs
> (3) libCERTId.so.3.4.1cvs
> 
> then I get the same set of files and symlinks in the (separate) install
> tree.
> Do you mean that in your case the plain file (3) is deleted ?
> 
> > Not a big deal for me since this only comes up in very controlled
> > circumstances in my project that are handled by macros - I skip the
> TARGETS
> > install step when this will happen.   I'm just curious if this
> failure is
> > expected or could be considered a minor bug.
> 
> My point of view would be that this is a user mistake and the best
> CMake can do
> would be  to warn about the collision and simply avoid "install onto
> myself" case.
> 
> --
> Erk
> Membre de l'April - « promouvoir et défendre le logiciel libre » -
> http://www.april.org

Here's a more specific example with CMake code.

SET (CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}")
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# similar for RUNTIME and ARCHIVE but not relevant
ADD_LIBRARY (RUGUD_Core_DataClient SHARED DataClient.cpp DataClient.h)
SET_TARGET_PROPERTIES (RUGUD_Core_DataClient PROPERTIES SOVERSION 2.0.0 DEFINE_SYMBOL RUGUD_CORE_DATACLIENT_BUILD_DLL)
INSTALL (TARGETS RUGUD_CORE_DataClient RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

After build, the contents of ${CMAKE_BINARY_DIR}/lib will be:

RUGUD_Core_DataClient.so -> RUGUD_Core_DataClient.so.2.0.0
RUGUD_Core_DataClient.so.2.0.0

When INSTALL is run, RUGUD_Core_DataClient.so.2.0.0 is deleted, then the INSTALL command fails trying to copy it onto itself because it is missing, with RUGUD_Core_DataClient.so now being a dangling symlink.  I'm not sure if there was ever an intermediate RUGUD_Core_DataClient.so.2 symlink (probably should be) but if there was it is also deleted by the INSTALL step.

The use case this comes up in was for the MSVC developers to be able to have a "developer" build mode where binaries are built into the correct relative location rather than being staged there by the INSTALL step.  This allowed them to quickly make changes, recompile just the affected DLL targets, and immediately see the results when launching our applications from the IDE debugger.  Our baseline is rather... large, and our INSTALL step has a lot of data files to process (3D models, textures, height maps, etc.) so even just re-linking 140+ unaffected targets and a no-op INSTALL can take 45+ seconds on Windows.  Maybe not a huge amount of time but it definitely frustrated the MSVC developers who are accustomed to their pre-CMake work flow.

For normal product builds we do it the "right" way where the OUTPUT paths are left default and INSTALL is used to stage everything to the right spot, so I think there is no harm in skipping the INSTALL(TARGETS) step for this specific "developer" build mode.

Thanks,
Gregory Peele, Jr.



More information about the CMake mailing list