I am trying to convert our installation process to use cmake instead of our old custom build that we have today. In the project we do have a few perl files that sometimes change that we want to include in the built product. In these perl files we want to set the shebang (#!/path/to/perl) during installation, so it can run on the system where cmake is run.
Usually I would use configure_file(), but due to the nature of configure_file() any @Unidentified-sequence@
will default to an empty string, when using configure_file() with any other option than COPYONLY (https://gitlab.kitware.com/cmake/cmake/-/issues/22740). This becomes inconvenient for perl scripts, as @ is used to define an array.
The workaround I have today is to read the file into cmake and use string replace,
file(READ "${srcDir}/${file}" FILE_CONTENTS)
#I have full control over the files. Thus adding a custom variable, such as @PERLPATH@, instead of a REGEX, is possible
string(REGEX REPLACE "#!/[/A-Za-z_0-9.-]+/perl" "#!${PERL_PATH}" FILE_CONTENTS "${FILE_CONTENTS}")
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${destDir}/${file}" CONTENT "${FILE_CONTENTS}")
This works, but any changes to the perl files requires cmake -B /path/to/build -S /path/to/source
to be rerun. Also, it will rerun this for any file and not only the changed files.
I would like it to automatically update the files when doing cmake --build
. Further, I would also prefer to have a check whether the files are changed or not and only update them then (which requires old change data to be saved and thus cannot be done during configure, cmake -B /path/to/build -S /path/to/source
).
I would appreciate if someone had a standardized solution to this, but as I understand it, this use case is not exactly supported in CMake. Thus I would consider it good enough with a workaround. Getting the change date is easy enough with stat -c %y
.
Is there any way to force cmake to run some particular cmake code snippet during cmake --build
, lets say the above example?