[CMake] How to create "staging" rules

Paul Smith paul at mad-scientist.net
Wed Jun 19 13:29:45 EDT 2013


Well, no love for this question but I figured it out myself:

  macro(stageobj target dir)
      get_property(targetpath TARGET ${target} PROPERTY LOCATION)
      get_filename_component(targetname ${targetpath} NAME)
      add_custom_command(OUTPUT "${CMAKE_INSTALL_PREFIX}/${dir}/${targetname}"
          COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_INSTALL_PREFIX}/${dir}"
          COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:${target}>" "${CMAKE_INSTALL_PREFIX}/${dir}"
          DEPENDS ${targetname}
          COMMENT "Staging ${target} to ${CMAKE_INSTALL_PREFIX}/${dir}"
          VERBATIM)
      add_custom_target("stage_${target}" ALL
          DEPENDS "${CMAKE_INSTALL_PREFIX}/${dir}/${targetname}")
  endmacro()

It's invoked like: "stageobj(myProgram bin)".  Note I believe this only
works with derived objects; I have a different macro I use for source
files that need to be staged (header files etc.)

Hope this is of interest to someone else!


On Mon, 2013-06-17 at 15:46 -0400, I wrote:
> I need my build to "stage" the final results (which consist of a few
> binaries, shared libraries, static libraries, and header files plus some
> scripts etc.) to a location in my workspace where they can be found for
> testing and packaging.  #1 requirement: this staging MUST happen as part
> of the default target.  It cannot require running a special target
> (like, oh, say... install :-)).
> 
> I am currently using the "install" facility of CMake to do it using a
> hack like this http://marc.info/?l=cmake&m=130365717914933&w=2 to invoke
> the install as a side-effect of the default target.  This hack has some
> annoying issues so I'm looking for a better way.
> 
> What I wanted to try to do instead was create a "stage" target using
> add_custom_command() / add_custom_target() that would have an output
> file of the staged file and depend on the built target, and where the
> rule body would do the copy, something like this:
> 
>   macro(stagebin target)
>       add_custom_command(OUTPUT "${STAGEDIR}/bin/${target}"
>           COMMAND "${CMAKE_COMMAND}" -E make_directory "${STAGEDIR}/bin"
>           COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:${target}>" "${STAGEDIR}/bin"
>           MAIN_DEPENDENCY ${target}
>           COMMENT "Staging ${target} to ${STAGEDIR}/bin"
>           VERBATIM)
>       add_custom_target("stage_${target}" ALL
>           DEPENDS "${STAGEDIR}/bin/${target}")
>   endmacro()
> 
> This actually seems to work very well for binaries, and I have a version
> of this macro for generic files that takes a list of files and works for
> header files.
> 
> The problem is libraries.  The above works due to a trick, that the
> target name is identical to the output file name, but for libraries the
> target name is something like "mylibrary" but the output file name is
> "libmylibrary.a" or "libmylibrary.so" (or "libmylibrary.dylib" or
> "libmylibrary.dll" or whatever).
> 
> So I cannot use ${target} in the OUTPUT string; it doesn't work.
> Unfortunately I also cannot use a generator expression like
> $<TARGET_FILE:${target}> here.  So, I'm kind of stuck.
> 
> Any pointers on how to create a "staging" rule like this for libraries?




More information about the CMake mailing list