Generate and install a file

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Generate and install a file

Norton Allen

I have spent a few hours trying to solve what seems like a simple problem.

I need to generate a file with some dependencies and install it.

If I want cmake to figure out how to compile and link it, I can

add_executable(mytarget mytarget.c)
install(TARGETS mytarget DESTINATION bin)

I also know that if I get cmake to configure a file, I can install it:

configure_file (
  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
  ${CMAKE_CURRENT_BINARY_DIR}/config.h )
intall(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
  DESTINATION include )

But what if I have a tool of my own that will generate the file? I know I can:

add_custom_command(
  OUTPUT mygeneratedfile
  COMMAND mytool -o mygeneratedfile
  DEPENDS mysourcefile
)

and this works well *provided* that mygeneratedfile is in turn a source file for another derivation, but I cannot follow that with:

install(FILES mygeneratedfile DESTINATION bin)

because mygeneratedfile is not a 'target', and I can't make it into a target with add_custom_target() because that's talking about something else entirely (commands that will be run unconditionally, not based on dependencies)

Am I missing something?

In my specific case, mytool actually creates an executable via it's own build system, but it could also be creating a script of some kind that needs to be installed. Of course in that case, I could possibly trick CMake by generating mygeneratedfile.in and using configure_file() with no substitutions (pretty dubious), but I can't do that with a binary file. Is this not possible?



--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

CMake mailing list
On Thu, 2019-03-28 at 14:58 -0400, Norton Allen wrote:

because mygeneratedfile is not a 'target', and I can't make it into a target with add_custom_target() because that's talking about something else entirely (commands that will be run unconditionally, not based on dependencies)


What exactly do you mean by "based on dependencies"? Do you mean that this file has dependencies on something else, or that something else has dependencies on it?

Kyle

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

Norton Allen
On 3/28/2019 3:11 PM, Kyle Edwards wrote:
On Thu, 2019-03-28 at 14:58 -0400, Norton Allen wrote:

because mygeneratedfile is not a 'target', and I can't make it into a target with add_custom_target() because that's talking about something else entirely (commands that will be run unconditionally, not based on dependencies)


What exactly do you mean by "based on dependencies"? Do you mean that this file has dependencies on something else, or that something else has dependencies on it?

I mean this file depends on some source files--if the source files change, I want to rerun the generation step.



--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

CMake mailing list
On Thu, 2019-03-28 at 15:26 -0400, Norton Allen wrote:
On 3/28/2019 3:11 PM, Kyle Edwards wrote:
On Thu, 2019-03-28 at 14:58 -0400, Norton Allen wrote:

because mygeneratedfile is not a 'target', and I can't make it into a target with add_custom_target() because that's talking about something else entirely (commands that will be run unconditionally, not based on dependencies)


What exactly do you mean by "based on dependencies"? Do you mean that this file has dependencies on something else, or that something else has dependencies on it?

I mean this file depends on some source files--if the source files change, I want to rerun the generation step.


Using the DEPENDS argument of add_custom_command() will do this. However, add_custom_command() on its own isn't enough to ensure that the file is generated before installation. You need to pair add_custom_command() with add_custom_target(). Example:

add_custom_command(
  OUTPUT mygeneratedfile
  COMMAND mytool -o mygeneratedfile
  DEPENDS mysourcefile
)
add_custom_target(mygeneratedtarget
  DEPENDS mygeneratedfile
)

This is different from:

add_custom_target(mygeneratedtarget
  COMMAND mytool -o mygeneratedfile
  BYPRODUCTS mygeneratedfile
  DEPENDS mysourcefile
)

because it will only run mytool when it needs to (when mysourcefile has changed).

Kyle

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

Norton Allen
On 3/28/2019 3:33 PM, Kyle Edwards wrote:
Using the DEPENDS argument of add_custom_command() will do this. However, add_custom_command() on its own isn't enough to ensure that the file is generated before installation. You need to pair add_custom_command() with add_custom_target(). Example:

add_custom_command(
  OUTPUT mygeneratedfile
  COMMAND mytool -o mygeneratedfile
  DEPENDS mysourcefile
)
add_custom_target(mygeneratedtarget
  DEPENDS mygeneratedfile
)

This is different from:

add_custom_target(mygeneratedtarget
  COMMAND mytool -o mygeneratedfile
  BYPRODUCTS mygeneratedfile
  DEPENDS mysourcefile
)

because it will only run mytool when it needs to (when mysourcefile has changed).

Kyle,

What you say makes sense, and I can even understand why add_custom_target might do that, but I cannot get this to actually work. Here is a minimal CMakeLists.txt. mysourcefile is just and empty file.

I have these files in test/cmake, and I:

cd test
mkdir build-cmake
cd build-cmake
cmake ../cmake
make

and there is no sign of mygeneratedfile. I then try

make install

and I get:

$ make install
Install the project...
-- Install configuration: ""
CMake Error at cmake_install.cmake:31 (file):
  file INSTALL cannot find "/home/nort/test/build-cmake/mygeneratedfile".


make: *** [Makefile:84: install] Error 1

Where is my mistake?




--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

CMakeLists.txt (542 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

CMake mailing list
On Thu, 2019-03-28 at 16:07 -0400, Norton Allen wrote:

Kyle,

What you say makes sense, and I can even understand why add_custom_target might do that, but I cannot get this to actually work. Here is a minimal CMakeLists.txt. mysourcefile is just and empty file.

I have these files in test/cmake, and I:

cd test
mkdir build-cmake
cd build-cmake
cmake ../cmake
make

and there is no sign of mygeneratedfile. I then try

make install

and I get:

$ make install
Install the project...
-- Install configuration: ""
CMake Error at cmake_install.cmake:31 (file):
  file INSTALL cannot find "/home/nort/test/build-cmake/mygeneratedfile".


make: *** [Makefile:84: install] Error 1

Where is my mistake?

One more thing: if you want the custom target to be built by "make" or "make all", you have to give it the ALL argument:

add_custom_target(mygeneratedtarget ALL
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mygeneratedfile
)

Otherwise you can build the target with "make mygeneratedtarget".

Kyle

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

Norton Allen
On 3/28/2019 4:12 PM, Kyle Edwards wrote:
One more thing: if you want the custom target to be built by "make" or "make all", you have to give it the ALL argument:

add_custom_target(mygeneratedtarget ALL
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mygeneratedfile
)

Otherwise you can build the target with "make mygeneratedtarget".

OK! That does make a difference. I had focused on the add_custom_target documentation that indicated the rule was always considered out of date, and jumped to the conclusion that that meant it was always run.

Thank you for sorting that out!

What I find surprising is that 'make install' could not identify how to create mygeneratedfile. Is there some reason why 'mygeneratedfile' cannot be a target in its own right with needing to refer to this phony target to achieve the desired result?

Related to that, I noticed in another thread the mention of 'CMAKE_SKIP_INSTALL_ALL_DEPENDENCY'. If that were set in this case, how could I indicate that install depends on mygeneratedtarget? (Admittedly, I'm having a hard time coming up with a case where this would apply, but I'm having trouble with the tenuous connection between the instruction to install mygeneratedfile and the rule that actually generates it.)


--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Generate and install a file

CMake mailing list
On Thu, 2019-03-28 at 16:38 -0400, Norton Allen wrote:
> Related to that, I noticed in another thread the mention of
> 'CMAKE_SKIP_INSTALL_ALL_DEPENDENCY'. If that were set in this case,
> how could I indicate that install depends on mygeneratedtarget?

There is no way to do this. C/C++ targets (executables and libraries)
suffer from the same problem: if you set
CMAKE_SKIP_INSTALL_ALL_DEPENDENCY and then run "make install" without
running "make" first, the install rule will complain that it can't find
the files (such as libfoo.a.) If you set
CMAKE_SKIP_INSTALL_ALL_DEPENDENCY, you have to make sure the targets
you want to install are built before running "make install".

Kyle
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake