[CMake] call already made makefile

David Cole david.cole at kitware.com
Fri Nov 5 06:38:02 EDT 2010


On Fri, Nov 5, 2010 at 5:17 AM, Michael Hertling <mhertling at online.de>wrote:

> On 11/05/2010 05:23 AM, SK wrote:
> > On Thu, Nov 4, 2010 at 6:09 PM, Alan W. Irwin <irwin at beluga.phys.uvic.ca>
> wrote:
> >> then the custom make command
> >> should always be run (since it has no DEPENDS option),
> >
> > Alan, you are absolutely right!!  I missed this since the external
> > makefile I need actually does have a dependency to create the makefile
> > itself.  So, the custom command only ran when the single explicit
> > dependency was out of date.  I can solve that some other way and I
> > appreciate all your effort to straighten this out.  I wish the
> > document would have explicitly stated that the command always runs
> > without a dependency, though that is the intuitive course of action.
>
> AFAIK, a custom command without dependencies doesn't run if its OUTPUT
> exists; see the following CMakeLists.txt and the generated Makefiles:
>
> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
> PROJECT(INDEPENDCUSTOMCOMMAND C)
> ADD_CUSTOM_COMMAND(
>    OUTPUT ${CMAKE_BINARY_DIR}/main.h
>    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/main.h)
> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "
> #include \"main.h\"
> int main(void){return 0;}
> ")
> ADD_EXECUTABLE(main main.c main.h)
>
> The sole possibility to (re)run the custom command is to delete main.h;
> if main.h exists the command never runs. You might even have a foreign
> main.h: Try "cmake <path/to/source>" followed by "touch main.h" from
> within an empty build directory, and you won't see the custom command
> run. In ${CMAKE_BINARY_DIR}/CMakeFiles/main.dir/build.make, the related
> lines are:
>
> main.h:
>        ...
>        .../cmake -E touch .../main.h
>
> So, the commands associated with make's "main.h" target aren't executed
> if make detects that main.h is already present. Thus, a dependency-less
> custom command doesn't run each time; rather, it runs only if its output
> doesn't exist.
>
> Regards,
>
> Michael
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
>


In addition to all that has been discussed in this thread already, consider
using CMake's ExternalProject module to drive the external make.

It should be as simple as something like (or at least very similar to):
include(ExternalProject)
ExternalProject_Add(extern_lib
  SOURCE_DIR "${dir_of_Makefile}"
  BUILD_IN_SOURCE 1
  BUILD_COMMAND $(MAKE)
)

You may also need:
  DOWNLOAD_COMMAND ""
  UPDATE_COMMAND ""
  CONFIGURE_COMMAND ""
  INSTALL_COMMAND ""
(to avoid built-in defaults for those build steps...)

In the ExternalProject module, we use a technique to run a custom command
always:
- Name an output for the custom command that never exists on disk, mark that
source file with the "SYMBOLIC" property, and then make sure that the custom
command never actually produces the named output file...

It's documented like this in the add_custom_command docs:
"If the output of the custom command is not actually created as a file on
disk it should be marked as SYMBOLIC with SET_SOURCE_FILES_PROPERTIES."

See also:
http://cmake.org/cmake/help/cmake-2-8-docs.html#command:add_custom_command
http://cmake.org/cmake/help/cmake-2-8-docs.html#prop_sf:SYMBOLIC


HTH,
David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20101105/28292527/attachment.htm>


More information about the CMake mailing list