In my git repo, I am copying some files to the target.
install(DIRECTORY data/ DESTINATION usr/bin)
However, I want to preserve the file timestamps (last_updated). There is an option to set a timestamp, but I can't find one to preserve it. Any suggestions on how to preserve a file's timestamp?
Related
I have a custom makefile used for versioning.
It basically sets the version according to some predefined rules and fetching info from git repo
I want to intergrate it with the esp32 cmake project.
Till now i managed to run the makefile from the cmakelist.txt file using
add_custom_target(versioning ALL
COMMAND ${CMAKE_COMMAND} -P "sometext.cmake"
)
and in the sometext.cmake i am calling the makefile which sets a FirmwareVersion variable.
I use this variable in the root cmakelist.txt to set the project(${FirmwareVersion})
But i want the project name to be changed every time firmwareVersion is changed.
But project command is only if there is some changes in cmakelist.txt
Any help to accomplish it is highly apreciated.
Thanks
The project() command also has VERSION named keyword. That is what you actually want. You can store the actual version in some extra CMake file (like version.cmake)
set(VERSION_FROM_GIT "1.2.3+9a6b075")
and use like
include("${CMAKE_CURRENT_SOURCE_DIR}/version.cmake")
project(MyProject VERSION ${VERSION_FROM_GIT} ...)
...
It's up to you how you going to update this file... There are plenty of ways to do that.
You can tell cmake to do a reconfiguration if a file changes. Since the .git directory contains a HEAD file either denoting the commit hash of the detached head or a reference to the file containing the commit hash, you could these files as configuration dependencies.
# assume the .git directory is in the same directory as this CMakeLists.txt
set(GIT_HEAD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/.git/HEAD")
# add dependency to the head itself
set_property(DIRECTORY . APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${GIT_HEAD_FILE}")
file(READ "${GIT_HEAD_FILE}" GIT_HEAD_CONTENT)
if (GIT_HEAD_CONTENT MATCHES "ref: +([^ ]+)")
# add file referenced in HEAD for non detached head state
set_property(DIRECTORY . APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.git/${CMAKE_MATCH_1}")
endif()
... your logic depending on the git version goes here ...
This gets a bit more complicated if you intend on using your repository as submodule of another repo, since the .git directory is not necessarily located in the submodule.
Let's say I have the directory X which includes many files and I want to install it to some destination:
INSTALL(DIRECTORY x
Destination ${DEST}
)
When I run this command, the folder structure would look like this:
${DEST}/x/a
${DEST}/x/b
${DEST}/x/c
...
How can I make CMake to "Unpack" the directory structure and my output like this?
${DEST}/a
${DEST}/b
${DEST}/c
...
When you append a / to your directory x the contents of the directory is copied to the DESTINATION, i.e.
install(DIRECTORY x/
DESTINATION ${DEST}
)
The DESTINATION keyword has to be given upper case.
See CMake's install documentation for further details.
I'm using CMake for a project, and generating some configuration .h files with a configure_file() command. This works well enough, but - if I make clean, the generated file is not deleted - nor is it overwritten when I invoke cmake again with different parameters (or ccmake and so on).
Why is this the case, and how can I force re-generation of configure_file output files - when necessary / always?
It seems this may happen if the files are generated under the source folder rather than under the build folder. I think CMake treated the (generated) files it found as source files - or at least, not build files (see #Tsyvarev's comment), so they must not be deleted/altered.
I'm trying to move a file to a specific location, and I did it like this:
file(INSTALL file.txt DESTINATION ../install_dir)
This worked fine. This moved file.txt to the specified destination.
However then I tried like this:
install(FILES ./file.txt DESTINATION ./install_dir)
Using install(FILES) doesn't copy files like I expect. The file is not installed at that location when I run the CMake configure command.
Can someone please explain the difference to me? Why is it that file(INSTALL) works when running the configure command, but install(FILES) doesn't?
The two commands do different things. install(FILES fil DESTINATION dest) instructs CMake to generate a build rule so that file fil is copied into dest when running the install step (make install or equivalent).
file(INSTALL ...) is evaluated immediately at configure time, while CMake is parsing the CMakeLists.txt file. Note that this signature is primarily intended for CMake's internal implementation of the above mentioned installation step: it prints install-themed status messages etc. If you just want to copy a file at configure time, you might want to prefer file(COPY) or file(COPY_IF_DIFFERENT).
How do I define a rule in CMake that will recursively copy a complete directory structure to a target directory, as well as remove the copied directory when running make clean afterwards?
Use
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/target_dir
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/dir ${CMAKE_BINARY_DIR}/target_dir)
add_custom_target(copy_dir_target ALL
DEPENDS ${CMAKE_BINARY_DIR}/target_dir)
CMake should automatically add any files/dirs which are produced with OUTPUT of add_custom_command().
If that wouldn't work you can try to gather files you wish to copy with file(GLOB ...), then add_custom_command() which copies only single file with foreach(FILE ${FILES}), and finally wrap everthing into the single add_custom_command() call. This way every file will be cleaned, except of target dir itself.
Finally, you can play with setting ADDITIONAL_MAKE_CLEAN_FILES property on source dir, but be sure to copy files into respective binary dir.