[Cmake] Using ADD_CUSTOM_COMMAND: self-pack exes or dlls

Sebastien BARRE sebastien.barre at kitware.com
Fri Nov 9 16:09:12 EST 2001


Hi CMake users,

Ken has just modified the DSW writer so that it supports custom commands 
created using ADD_CUSTOM_COMMAND and attached to libs or exes through the 
SOURCE parameter. In that specific case the custom command is triggered as 
a post-build command by nmake.

I've reimplemented this command code and thus slightly changed the command 
usage to:

       "ADD_CUSTOM_COMMAND(SOURCE source COMMAND command TARGET target "
       "[ARGS [args...]] [DEPENDS [depends...]] [OUTPUTS [outputs...]])\n"
       "Add a custom command.";

I've successfully used it to automatically propagate a DLL to several 
directories everytime it is rebuilt.

Here is a another (typical) example demonstrating how to self-pack an 
executable everytime it is rebuilt (i.e. same exe but decompressed 
on-the-fly).

This example self-packs CMakeSetup.exe to 30% of its size with upx (548 Ko 
to 127 Ko for the 'Release' build). You need UPX, a 87 Ko free command-line 
self-packer (http://wildsau.idv.uni-linz.ac.at/mfx/upx.html). It can be 
used to self-pack DLL too.

Add these lines to the end of CMake\Source\MFCDialog\CMakeLists.txt

OPTION(SELF_PACK_EXECUTABLES "Self-pack executables." OFF)

IF (SELF_PACK_EXECUTABLES)
   INCLUDE(${CMAKE_ROOT}/Modules/FindSelfPackers.cmake)
   IF (SELF_PACKER_FOR_EXECUTABLE)
     IF (WIN32)
       ADD_CUSTOM_COMMAND(
           SOURCE CMakeSetup
           COMMAND ${SELF_PACKER_FOR_EXECUTABLE}
           ARGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS}
                ${EXECUTABLE_OUTPUT_PATH}/$(INTDIR)/CMakeSetup.exe
           TARGET CMakeSetup)
     ENDIF (WIN32)
   ENDIF (SELF_PACKER_FOR_EXECUTABLE)
ENDIF (SELF_PACK_EXECUTABLES)

- The FindSelfPackers.cmake (see CVS) module looks for a self-packer 
(SELF_PACKER_FOR_EXECUTABLE and SELF_PACKER_FOR_SHARED_LIB) and the 
according flags).

- The custom command is attached to the exe post-build steps by using the 
target name as the SOURCE parameter (of course, TARGET should also be set 
to this value).

Of course it does not make a lot of sense if you self-pack your Debug 
executables. You might focus on packing the release build (for quick 
distribution purposes for example). Here is a hack: instead of launching 
the packer it launches a shell that tests for the $(INTDIR) var. But you 
need a unix-like shell (cygwin bash) as I was not able to figure out if 
command.exe is able to interpret a string instead of executing a batch or 
entering in interactive mode. Hence, if you use bash you can not use 
$(INTDIR) to specify the path to the executable to compress (as it use a 
'/'). But since we know the INTDIR value (here, './Release') it's not that 
important. It's a hack anyway :)

OPTION(SELF_PACK_EXECUTABLES "Self-pack executables." OFF)

IF (SELF_PACK_EXECUTABLES)
   INCLUDE(${CMAKE_ROOT}/Modules/FindSelfPackers.cmake)
   IF (SELF_PACKER_FOR_EXECUTABLE)
     IF (WIN32)
       INCLUDE(${CMAKE_ROOT}/Modules/FindUnixCommands.cmake)
       IF (BASH)
         ADD_CUSTOM_COMMAND(
           SOURCE CMakeSetup
           COMMAND ${BASH}
           ARGS "-c" "if test 'x$(INTDIR)' == 'x.\\Release'; then 
${SELF_PACKER_FOR_EXECUTABLE} ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} 
${EXECUTABLE_OUTPUT_PATH}/Release/CMakeSetup.exe; fi"
           TARGET CMakeSetup)
       ENDIF (BASH)
     ENDIF (WIN32)
   ENDIF (SELF_PACKER_FOR_EXECUTABLE)
ENDIF (SELF_PACK_EXECUTABLES)

Just my 2 cents

--
Sebastien Barre 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20011109/4c272594/attachment.html>


More information about the CMake mailing list