How to run script in install phase from install directory

Dear CMake Gurus,

This is a little convoluted and long, but I’m hoping it’s possible in CMake…with as little change to source code as possible!

To wit, I work on a earth science model and one of the goals with our recent conversion to CMake is to make things “user portable” for the users. What I mean is that userA can build/install the model, and then userB can go to userA’s installation and run an experiment with that install.

Most of this is working, but I’m getting stuck on a new wrinkle. I was mainly focusing on running the model, etc. but there are postprocessing steps I often miss. What we did in old GNU Make days is during a model run when it’s time to make plots, the user ran a script in our (simplified for here) src/plots/ directory, src/plots/configure which set up a bunch of symlinks in the source tree so the plotting package was happy. Of course, this meant only the user that built the experiment could run this because of directory permissions. But, with some ugly GNU Make, I was able to figure out how to run that script at make install time so the symlinks got created.

Now, in CMake land, we have a rule that after installation, no script can ever refer back to the source directory. So, users now during postprocessing run install/plots/configure instead (we didn’t install it to install/bin as we wanted to keep all the plotting/postprocessing separate for various reasons). And like before, if userA built the model and userA runs install/plots/configure all is well as userA has permission to write to install/plots. But userB has an issue doing so.

So, what I’d like to do is:

  1. Install/copy configure to install/plots
  2. After copying, run install/plots/configure to set up the symlinks in install/plots

The first step we are doing with the usual:

install (
   PROGRAMS configure
   DESTINATION plots
   )

as it’s just “copy this to there”.

It’s that second step I’m having trouble with. The script has to be run from the install/plots directory because that’s where the symlinks need to be. Making it even more difficult is that an environment variable needs to be set (essentially to the full path of install) because configure is a shell script.

I’ve tried various things (making a custom target, ugly add_custom_command()), but I seem to be failing at this…

Thanks,
Matt

Have a look at install(SCRIPT | CODE …).

And to have a CMake script knowing various information about your directories, you can use configure_file().

@marc.chevrier Ah. I see. Well, my first attempt was that install(SCRIPT | CODE) is expecting CMake code, and I did install(SCRIPT configure) and not happy. So as a test I tried this. First, I created a file bobo.csh:

$ cat bobo.csh
#!/bin/csh -f

setenv GEOSUTIL @CMAKE_INSTALL_PREFIX@
echo "GEOSUTIL: ${GEOSUTIL}" > yaya

and then added to my CMakeLists.txt:

configure_file(bobo.csh bobo.csh @ONLY)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bobo.csh DESTINATION plots)
install(CODE "execute_process(COMMAND bobo.csh WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/plots)")

However, as far as I can see it wasn’t executed. I then did:

install(CODE "execute_process(COMMAND ${CMAKE_INSTALL_PREFIX}/plots/bobo.csh WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/plots)")

and that seemed to work! Huzzah. It’s a bit ugly though (so, on a par with my usual CMake code :smile:) . Is there a reason the original execute_process() didn’t work? Some CMake-ness I’m missing?

Your original code didn’t specify a path to bobo.csh in the install(CODE ...) command. The current directory is not on the PATH by default on Unix systems, so the script would not have been found. Since you set the WORKING_DIRECTORY, you could have specified the command as ./bobo.csh instead and it would have worked.

Ah. Duh. Sometimes I’m just dumb. I guess in my head I was thinking WORKING_DIRECTORY would be added to PATH as well. But, I guess there’s nothing wrong with specificity.