Re: [CMake] copy_if_different on build

2013-04-24 Thread Matthew Woehlke

On 2013-04-23 16:00, Skippy VonDrake wrote:

Hmm... that is odd. I think there may be something else going on in your
project that is not obvious from the above information. I wrote a quick
example along the lines of what you show, and it worked fine for me. Actual
CMakeLists.txt I used is attached. (The foo.c can contain any compiling
code, and foo.cfg.in can contain anything or even be empty.)

(Apparently a disadvantage of just using add_custom_target is that it always
runs, regardless of the DEPENDS. Not that this should be a huge problem,
though.)

Have you tried naming the input/output like
${CMAKE_CURRENT_SOURCE_DIR}/name.in and
${CMAKE_CURRENT_BINARY_DIR}/name? (I didn't do that in the attached
example because I was lazy (and the example may only work for in-source
builds as a result), but that is how I would recommend naming the files in a
real project.)


The source of my problem was 'naming'. I did use the CMake 'SOURCE_DIR'
variable but my file extensions were wrong and my path was off by one level!
Everything works fine now.


Ah, good to hear :-). Thanks for letting us know.


I did notice an effect I didn't expect - when
'make clean' is run the 'output' is deleted. Hadn't thought about that...


Well, yes, with the custom commend the output file is effectively a 
build artifact, so of course it is deleted by clean :-).


--
Matthew

--

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


Re: [CMake] copy_if_different on build

2013-04-23 Thread Matthew Woehlke

Please keep this on list so that others may contribute/benefit. Thanks.

On 2013-04-23 10:43, Skippy VonDrake wrote:

Hmm... yes, I'm not sure if add_dependencies can be used to add a file
dependency to a target (the documentation only talks about adding other
targets as dependencies).

Usually things like configured files are used as source files, i.e. as
inputs to add_executable, etc.

If for some reason that doesn't work, I believe you can make your executable


Since this config file is not needed for the code to compile, I want to keep it
separated from the sources list. CMake should be able to accomplish this
task without adding the file to the sources.


dependent on a custom target, which in turn depends on the output file from
your custom command. IOW:

add_custom_command(OUTPUT out DEPENDS in COMMAND stuff)
add_executable(exe sources)
add_custom_target(exe_config DEPENDS out)
add_dependencies(exe exe_config)


So with the example code above this would translate to?:
   add_executable (${TARGETNAME}main.cpp)
   add_custom_command(OUTPUT ${output} DEPENDS
${input} COMMAND ${CMAKE_COMMAND} -E
copy_if_different ${input} ${output})
   add_custom_target(exe_config DEPENDS ${output})
   add_dependencies(${TARGETNAME} exe_config)

Which results in make error:
   make[2]: *** No rule to make target `../src/bin/config.cfg', needed
by `src/CMakeFiles/exe_config'.  Stop.


If you only have one custom command, you can probably use add_custom_target
to run the command instead, i.e.:

add_custom_target(exe_config DEPENDS in COMMAND stuff)
add_executable(exe sources)
add_dependencies(exe exe_config)


With example code this would be?:
   add_executable (${TARGETNAME}main.cpp)
   add_custom_target(exe_config DEPENDS
   ${input} COMMAND ${CMAKE_COMMAND} -E
copy_if_different ${input} ${output})
   add_dependencies(${TARGETNAME} exe_config)

This created the same make error above. Am I translating your suggestions into
the example code erroneously, Matthew?


Hmm... that is odd. I think there may be something else going on in your 
project that is not obvious from the above information. I wrote a quick 
example along the lines of what you show, and it worked fine for me. 
Actual CMakeLists.txt I used is attached. (The foo.c can contain any 
compiling code, and foo.cfg.in can contain anything or even be empty.)


(Apparently a disadvantage of just using add_custom_target is that it 
always runs, regardless of the DEPENDS. Not that this should be a huge 
problem, though.)


Have you tried naming the input/output like 
${CMAKE_CURRENT_SOURCE_DIR}/name.in and 
${CMAKE_CURRENT_BINARY_DIR}/name? (I didn't do that in the attached 
example because I was lazy (and the example may only work for in-source 
builds as a result), but that is how I would recommend naming the files 
in a real project.)


(Incidentally, this tickles a ninja generator bug in CMake  2.8.11.)

--
Matthew

project(foo)
cmake_minimum_required(VERSION 2.8)

add_executable(foo foo.c)
if(1) # Just to show doing it both ways
  add_custom_command(
OUTPUT foo.cfg
DEPENDS foo.cfg.in
COMMAND ${CMAKE_COMMAND} -E copy foo.cfg.in foo.cfg
  )
  add_custom_target(foo_config DEPENDS foo.cfg)
else()
  add_custom_target(foo_config
DEPENDS foo.cfg.in
COMMAND ${CMAKE_COMMAND} -E copy_if_different foo.cfg.in foo.cfg
  )
endif()
add_dependencies(foo foo_config)
--

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

Re: [CMake] copy_if_different on build

2013-04-23 Thread Skippy VonDrake
 Hmm... that is odd. I think there may be something else going on in your
 project that is not obvious from the above information. I wrote a quick
 example along the lines of what you show, and it worked fine for me. Actual
 CMakeLists.txt I used is attached. (The foo.c can contain any compiling
 code, and foo.cfg.in can contain anything or even be empty.)

 (Apparently a disadvantage of just using add_custom_target is that it always
 runs, regardless of the DEPENDS. Not that this should be a huge problem,
 though.)

 Have you tried naming the input/output like
 ${CMAKE_CURRENT_SOURCE_DIR}/name.in and
 ${CMAKE_CURRENT_BINARY_DIR}/name? (I didn't do that in the attached
 example because I was lazy (and the example may only work for in-source
 builds as a result), but that is how I would recommend naming the files in a
 real project.)

The source of my problem was 'naming'. I did use the CMake 'SOURCE_DIR'
variable but my file extensions were wrong and my path was off by one level!
Everything works fine now.

 (Incidentally, this tickles a ninja generator bug in CMake  2.8.11.)

Don't know about that bug. I did notice an effect I didn't expect - when
'make clean' is run the 'output' is deleted. Hadn't thought about that...

Thanks for your help and patience!

-Skippy
--

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


Re: [CMake] copy_if_different on build

2013-04-19 Thread Matthew Woehlke

On 2013-04-17 12:41, Skippy VonDrake wrote:

Thought I understood this - but alas my implementation is wrong.

Here's my test case with a top-level cmake file and 3 subdirectories:
'src', 'bin' and 'outdir'.

Top level CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (copyFile)
set (TARGETNAME fooCopy)
set (TARGETDEST ${PROJECT_SOURCE_DIR}/bin)
add_subdirectory (src)

src/CMakeLists.txt
add_executable (${TARGETNAME}   main.cpp)
set (input  ${CMAKE_CURRENT_SOURCE_DIR}/bin/config.cfg)
set (output ${CMAKE_CURRENT_SOURCE_DIR}/outdir/config.cfg)

add_dependencies(${TARGETNAME}  ${output})

add_custom_command(
OUTPUT ${output}
DEPENDS ${input}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${input} ${output}
)

install (TARGETS ${TARGETNAME} DESTINATION ${TARGETDEST})

The config file (config.cfg) is just some text and cpp file is just a
hello world
example.

Since the config file is not source included as a dependency in the
add_executable command, I assume my problem is making the target
properly depend on it? Specifically ${TARGETNAME} should depend
on ${output}?


Hmm... yes, I'm not sure if add_dependencies can be used to add a file 
dependency to a target (the documentation only talks about adding other 
targets as dependencies).


Usually things like configured files are used as source files, i.e. as 
inputs to add_executable, etc.


If for some reason that doesn't work, I believe you can make your 
executable dependent on a custom target, which in turn depends on the 
output file from your custom command. IOW:


add_custom_command(OUTPUT out DEPENDS in COMMAND stuff)
add_executable(exe sources)
add_custom_target(exe_config DEPENDS out)
add_dependencies(exe exe_config)


If you only have one custom command, you can probably use 
add_custom_target to run the command instead, i.e.:


add_custom_target(exe_config DEPENDS in COMMAND stuff)
add_executable(exe sources)
add_dependencies(exe exe_config)


Hope that helps,

--
Matthew

--

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


Re: [CMake] copy_if_different on build

2013-04-17 Thread Skippy VonDrake
 believe what you want is:

  add_custom_command(
 OUTPUT ${output}
 DEPENDS ${input}
 COMMAND ${CMAKE_COMMAND} -E copy
 ${input} ${output}

 ...which is roughly equivalent to a Makefile rule like:

 output: input
   cp input output

 IOW, the file ${output} depends on the file ${input} (so the target will
 only run when ${input} is newer than ${output}), and will be created by
 copying ${input} to ${output} (using 'cmake -E' for portability).

 Don't forget to have an actual target depend on ${output} :-). (Probably
 you are using it as a source file for a library or executable, so there is
 no problem.)

 You may also want to use 'copy_if_different' instead of just 'copy', which
 won't change the time stamp of ${output} if the contents are the same as
 ${input}. On the plus side, this means that large targets depending on
 ${output} won't be needlessly rebuilt/relinked. On the down side, the
 copy_if_different will remain out of date, and as a result still think it
 needs to run after a successful build.

Thought I understood this - but alas my implementation is wrong.

Here's my test case with a top-level cmake file and 3 subdirectories:
'src', 'bin' and 'outdir'.

Top level CMakeLists.txt
   cmake_minimum_required (VERSION 2.8)
   project (copyFile)
   set (TARGETNAME fooCopy)
   set (TARGETDEST ${PROJECT_SOURCE_DIR}/bin)
   add_subdirectory (src)

src/CMakeLists.txt
   add_executable (${TARGETNAME}main.cpp)
   set (input  ${CMAKE_CURRENT_SOURCE_DIR}/bin/config.cfg)
   set (output ${CMAKE_CURRENT_SOURCE_DIR}/outdir/config.cfg)

   add_dependencies(${TARGETNAME}  ${output})

   add_custom_command(
   OUTPUT ${output}
   DEPENDS ${input}
   COMMAND ${CMAKE_COMMAND} -E copy_if_different
${input} ${output}
   )

   install (TARGETS ${TARGETNAME} DESTINATION ${TARGETDEST})

The config file (config.cfg) is just some text and cpp file is just a
hello world
example.

Since the config file is not source included as a dependency in the
add_executable command, I assume my problem is making the target
properly depend on it? Specifically ${TARGETNAME} should depend
on ${output}?

-Skippy
--

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


Re: [CMake] copy_if_different on build

2013-04-01 Thread Matthew Woehlke

On 2013-03-29 17:07, Skippy VonDrake wrote:

I'll look closer at add_custom_command. I want the file to copy over if
it has changed - at build time. Not cmake time. And not copy if it hasn't
changed. But that may not be doable.

Seems like every StackOverflow post I see has a different take on how
to do this simple process.


That's a little surprising... as you say, this shouldn't be complicated. 
I believe what you want is:


 add_custom_command(
OUTPUT ${output}
DEPENDS ${input}
COMMAND ${CMAKE_COMMAND} -E copy
${input} ${output}

...which is roughly equivalent to a Makefile rule like:

output: input
  cp input output

IOW, the file ${output} depends on the file ${input} (so the target 
will only run when ${input} is newer than ${output}), and will be 
created by copying ${input} to ${output} (using 'cmake -E' for 
portability).


Don't forget to have an actual target depend on ${output} :-). 
(Probably you are using it as a source file for a library or executable, 
so there is no problem.)


You may also want to use 'copy_if_different' instead of just 'copy', 
which won't change the time stamp of ${output} if the contents are the 
same as ${input}. On the plus side, this means that large targets 
depending on ${output} won't be needlessly rebuilt/relinked. On the 
down side, the copy_if_different will remain out of date, and as a 
result still think it needs to run after a successful build.


--
Matthew

--

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


[CMake] copy_if_different on build

2013-03-29 Thread Skippy VonDrake
I'm using:
  execute_process(COMMAND ${CMAKE_COMMAND}  -E  copy_if_different
some-file  some-dest-dir)

Should the file be copied when:
   the file has changed AND a build is executed?
   Or
   the file has changed AND CMakeLists.txt has changed AND a build is executed?

Only the 2nd method (when the CMakeLists.txt file is touched) results in the
changed file being copied.

I'd expect the 1st method to also cause a file copy.
If this assumption is wrong please tell me why.

-Skippy
--

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


Re: [CMake] copy_if_different on build

2013-03-29 Thread Matthew Woehlke

On 2013-03-29 15:15, Skippy VonDrake wrote:

I'm using:
   execute_process(COMMAND ${CMAKE_COMMAND}  -E  copy_if_different
some-file  some-dest-dir)

Should the file be copied when:
the file has changed AND a build is executed?
Or
the file has changed AND CMakeLists.txt has changed AND a build is executed?

Only the 2nd method (when the CMakeLists.txt file is touched) results in the
changed file being copied.

I'd expect the 1st method to also cause a file copy.
If this assumption is wrong please tell me why.


execute_process is a configure step. It does not create build rules and 
will ONLY execute when CMake is run.


If you want to create a build rule, use add_custom_command or 
add_custom_target instead.


Anyway, the above is silly; if you really only wanted the file copied at 
cmake time, you should instead use configure_file(... COPY_ONLY) :-) 
rather than unnecessarily invoking an extra process.


--
Matthew
--

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


Re: [CMake] copy_if_different on build

2013-03-29 Thread Skippy VonDrake
 I'm using:
execute_process(COMMAND ${CMAKE_COMMAND}  -E  copy_if_different
 some-file  some-dest-dir)

 Should the file be copied when:
 the file has changed AND a build is executed?
 Or
 the file has changed AND CMakeLists.txt has changed AND a build is
 executed?

 Only the 2nd method (when the CMakeLists.txt file is touched) results in
 the
 changed file being copied.

 I'd expect the 1st method to also cause a file copy.
 If this assumption is wrong please tell me why.


 execute_process is a configure step. It does not create build rules and will
 ONLY execute when CMake is run.

 If you want to create a build rule, use add_custom_command or
 add_custom_target instead.

 Anyway, the above is silly; if you really only wanted the file copied at
 cmake time, you should instead use configure_file(... COPY_ONLY) :-) rather
 than unnecessarily invoking an extra process.

I'll look closer at add_custom_command. I want the file to copy over if
it has changed - at build time. Not cmake time. And not copy if it hasn't
changed. But that may not be doable.

Seems like every StackOverflow post I see has a different take on how
to do this simple process.
--

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