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

Sebastien BARRE sebastien . barre at kitware . com
Fri, 09 Nov 2001 16:09:12 -0500


--=====================_196331680==_.ALT
Content-Type: text/plain; charset="us-ascii"; format=flowed

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 
--=====================_196331680==_.ALT
Content-Type: text/html; charset="us-ascii"

<html>
Hi CMake users,<br><br>
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.<br><br>
I've reimplemented this command code and thus slightly changed the
command usage to:<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;ADD_CUSTOM_COMMAND(SOURCE source
COMMAND command TARGET target &quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;[ARGS [args...]] [DEPENDS
[depends...]] [OUTPUTS [outputs...]])\n&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;Add a custom
command.&quot;;<br><br>
I've successfully used it to automatically propagate a DLL to several
directories everytime it is rebuilt.<br><br>
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). <br><br>
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
(<a href="http://wildsau . idv . uni-linz . ac . at/mfx/upx . html" eudora="autourl">http://wildsau . idv . uni-linz . ac . at/mfx/upx . html</a>).
It can be used to self-pack DLL too.<br><br>
Add these lines to the end of
CMake\Source\MFCDialog\CMakeLists.txt<br><br>
<tt>OPTION(SELF_PACK_EXECUTABLES &quot;Self-pack executables.&quot;
OFF)<br><br>
IF (SELF_PACK_EXECUTABLES)<br>
&nbsp; INCLUDE(${CMAKE_ROOT}/Modules/FindSelfPackers.cmake)<br>
&nbsp; IF (SELF_PACKER_FOR_EXECUTABLE)<br>
&nbsp;&nbsp;&nbsp; IF (WIN32)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADD_CUSTOM_COMMAND(<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE
CMakeSetup<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COMMAND
${SELF_PACKER_FOR_EXECUTABLE} <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARGS
${SELF_PACKER_FOR_EXECUTABLE_FLAGS} <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
${EXECUTABLE_OUTPUT_PATH}/$(INTDIR)/CMakeSetup.exe<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TARGET
CMakeSetup)<br>
&nbsp;&nbsp;&nbsp; ENDIF (WIN32)<br>
&nbsp; ENDIF (SELF_PACKER_FOR_EXECUTABLE)<br>
ENDIF (SELF_PACK_EXECUTABLES)<br><br>
</tt>- 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).<br><br>
- 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).<br><br>
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 :)<br><br>
<tt>OPTION(SELF_PACK_EXECUTABLES &quot;Self-pack executables.&quot;
OFF)<br><br>
IF (SELF_PACK_EXECUTABLES)<br>
&nbsp; INCLUDE(${CMAKE_ROOT}/Modules/FindSelfPackers.cmake)<br>
&nbsp; IF (SELF_PACKER_FOR_EXECUTABLE)<br>
&nbsp;&nbsp;&nbsp; IF (WIN32)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
INCLUDE(${CMAKE_ROOT}/Modules/FindUnixCommands.cmake)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF (BASH)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADD_CUSTOM_COMMAND(<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SOURCE
CMakeSetup<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COMMAND
${BASH}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARGS
&quot;-c&quot; &quot;if test 'x$(INTDIR)' == 'x.\\Release'; then
${SELF_PACKER_FOR_EXECUTABLE} ${SELF_PACKER_FOR_EXECUTABLE_FLAGS}
${EXECUTABLE_OUTPUT_PATH}/Release/CMakeSetup.exe; fi&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TARGET
CMakeSetup)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF (BASH)<br>
&nbsp;&nbsp;&nbsp; ENDIF (WIN32)<br>
&nbsp; ENDIF (SELF_PACKER_FOR_EXECUTABLE)<br>
ENDIF (SELF_PACK_EXECUTABLES)<br><br>
</tt>Just my 2 cents<br>
<br>
<div>--</div>
Sebastien Barre
</html>

--=====================_196331680==_.ALT--