[CMake] Copying shared libraries in a post-build step

J Decker d3ck0r at gmail.com
Tue Dec 9 19:44:42 EST 2014


This is all handled by install.
Plugins get installed in their correct directory
resources; data files etc get installed in their correct directory...
each type of target is handled with INSTALL( TARGET ) but you get 3
destinations; RUNTIME (exe), LIBRARY(.dll,.so) and ARCHIVE (.lib,.a) ; they
claim that runtime is .dll on windows; but this is just not true; if
library is set, DLL goes to that path...
but otherwise...

Sounds really like you're working to build a package, which install is
intended to do.  With a few more cmake commands after building install
rules, can use package command and build an installable.... NSIS works good
for windows; I know there's MAC dmz(?) support also... but the first thing
you'd do is build a directory structure.

Again INSTALL doesn't have to be 'install' but can be 'write to this
relative directory, this directory structure'

Then you just have to right-click on the project, edit debugging
properties, and browse to the installed location.

CMAKE is really fast in visual studio if you have a large project of lots
of targets and only a few rebuild and copy.

The INSTALL output can be really noisy, but there's a new setting that can
be applied at the top of the root cmake script file...
set( CMAKE_INSTALL_MESSAGE "LAZY" )

that will cut down on the output and only show what was actually updated.




On Tue, Dec 9, 2014 at 4:34 PM, Eric Wing <ewmailing at gmail.com> wrote:

> On 12/9/14, Walter Gray <chrysalisx at gmail.com> wrote:
> > Hey all,
> > I'm working on a module that will allow me to automatically copy all the
> > required .dll files as defined by well-formed import library targets to
> > the appropriate location (same folder for windows, Frameworks folder for
> > OSX bundle, ect).  I've got the code that scans an executable's
> > INTERFACE_LINK_LIBRARIES property recursively to find all such shared
> > library, however I'm running into a small problem.  I really like using
> > file globbing in higher level source directories to add all appropriate
> > sub-directories, but this means that sometimes a dependency will not be
> > fully defined yet. This is normally fine since these things are usually
> > resolved at *generation* time, but since I'm doing a manual traversal of
> > the list of link libraries at config time that's not really acceptable.
> > I realize I could just not do the globbing and just make sure the
> > directories were setup in the correct order, but I really don't like
> > making the add_subdirectory calls order dependent.
> >
> > One solution I've come up with is to add the targets I want to do this
> > to to a global list, then iterate over that list as the last step in my
> > top-level cmake lists file, but that has the issue that I can no longer
> > use add_custom_command on those targets at that point.  I'm wondering 3
> > things:
> >
> > 1)What is the reasoning behind not allowing add_custom_command on
> > targets not defined in the current directory? Especially now that SOURCE
> > can be modified, the restriction seems very arbitrary.
> >
> > 2)How stupid would it be to reserve the command using something like
> > add_custom_command(TARGET ${target} POST_BUILD COMMAND
> > $<TARGET_PROPERTY:COPY_SHARED_LIBS_COMMAND>)
> >   then use set_property(TARGET ${target} APPEND PROPERTY
> > COPY_SHARED_LIBS_COMMAND to add more copy steps to the command?
> >
> > 3) Am I completely missing something and there's already a totally well
> > supported way of making sure that an executable's shared library
> > dependencies end up in the correct directory?  I couldn't find a really
> > satisfactory answer on stack overflow or the archives.
> >
> > Thanks!
> >
>
>
> I think this is a good idea if you can pull it off. I recently wrote a
> lot of excruciating CMake code to do this for me. (I also was dealing
> with resource and plugin code which shares similar issues.) This
> actually took me a very long time to implement and it would be better
> if CMake handled this automatically. Here is a list of ideas that I
> needed to deal with:
>
> - My motivation was to build a runnable product when you build. On
> Visual Studio, you can't run through the debugger because none of the
> .dlls are in place. Similarly on Mac, iOS, Android, and now WinRT,
> there is no separation/distinction between compiling the executable
> and packaging the contents. This is in my opinion of the most
> problematic design issues in CMake. I also strongly feel that having
> to run the install target is very wrong because it violates the normal
> workflow on all these platforms and you also end up developing/testing
> something different than what you ship to testers/users.
>
> - The fix_bundle_utils didn't work for me because it did stuff in the
> install stage (too late). Also, it didn't handle my usage of Mac
> @rpath (not sure if that was fixed since) so I gave up on it early.
>
>
> - I needed an explicit declaration mechanism to describe which
> libraries needed to be bundled (or which did not). Some are system
> libraries while others need to be redistributed with the app. And some
> might be static libraries which you don't copy. (A .lib/.dll on Visual
> Studio and a .framework on iOS is ambiguous to whether they are static
> or dynamic.)
>
>     - There was also both implicit knowledge about where they go for
> each platform (had to make decisions about Linux and RPATH_ORIGIN),
> and also made decisions when they were nested in subdirectories. (I
> preserve the layout.)
>
>     - For Visual Studio, that explicit mechanism had to be aware that
> you link with .libs, but copy the .dll.
>
>     - I didn't do an explicit scan of the libraries for dependencies
> for multiple reasons. One important reason to me though is I want the
> build to be as fast as possible (ideally on par with Xcode normally
> does which is apples-to-apples in this case).
>
>         - I don't think scanning INTERFACE_LINK_LIBRARIES is
> sufficient because it won't capture what libraries each of those might
> depend on. For example, I deal with a pre-build SDL_image library on
> Windows which depends on libtiff, libjpeg, libpng. libpng then in turn
> depends on zlib.
>
>             - The complexity of recursively walking the dependencies,
> and then also knowing which ones are system supplied libraries and
> which are not is really hard, which is another reason I went the
> explicit declaration route. (And shipping Linux binaries is a
> nightmare; you have to make hard decisions about what is a system
> library and what you need to need to ship yourself.)
>
> - Mac/iOS framework copies were a pain because they are bundles
> (directory structures) and also have symlinks, both of which CMake
> does not support well for copying. I ended up using rsync on those
> platforms.
>
> - rsync had a nice advantage of resyncing if the source
> framework/library changed and its a very efficient copy.
>
>     - But rsync got me into performance overhead when I introduced
> codesigning because codesigning always changes the library, causing
> the library to be resynced with the original and then needing to
> codesign again. (Codesigning is a slow operation.)
>
> - I also need an explicit mechanism that signed libraries/plugins.
> This signing MUST happen before Xcode tries to do the final
> codesigning for your application. (I don't know if POST_BUILD is too
> late or not.)
>
>     - I was thinking that it would be nice if there was a CMake way to
> declare which things need to be codesigned too. (Some kind of
> SET_PROPERTIES thing.)
>
> - In some cases, libraries get nested into subdirectories and this
> information needs to be preserved for packing. Traversing the file
> hierarchy relative to the bundles and preserving this information was
> really nasty. I needed data structures in CMake and ended up doing
> really nasty string tricks since everything is a string in CMake.
>
>
> - I needed to handle things like rpath (Linux, Mac).
>
>
> - Note, almost all this stuff I ended up re-applying for plugins and
> resources.
>
> - I ended up dealing with icons, launch screens, application
> manifests, sandboxing entitlements as completely separate entities.
>
>
> There's probably a lot more.
>
>
> Thanks,
> Eric
> --
> Beginning iPhone Games Development
> http://playcontrol.net/iphonegamebook/
> --
>
> 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:
> http://public.kitware.com/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20141209/8d26f30a/attachment.html>


More information about the CMake mailing list