Running cpack after install target and install cpack results?

All, this is one of those myriad of “CMake post install” issues. Essentially, I’m trying to figure out how I can run cpack after I run make install and then install the bits that cpack just made into the installation directory.

More verbosely, what I’d like is that every time users run make install for my code, I’d also like to make a tarball of the source code and then install that tarball into CMAKE_INSTALL_PREFIX. (Why? Well, I work on a climate model and users have expressed a want to make sure they have the source code for every experiment they make which might be a single source code change they build, install, and make an experiment for.)

I already have a nice CPack setup that can do that with the usual make package_source. But since install isn’t like a “real” CMake target, all the easy ways I can think of doing this are hard (i.e., have the package_source target depend on install or some such).

Do I perhaps need to make a shell script called via install(SCRIPT) that does what CPack would do for make package_source (aka tar czf ...) and then does a Linux cp into the CMAKE_INSTALL_PREFIX? Or is there some cool CMake I don’t know about that could help me do this more

Well, huh. I guess I figured something out but I guess because it works doesn’t mean I should depend on it.

I made a file PostInstall.cmake:

execute_process(
  COMMAND make package_source
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  COMMAND_ECHO STDOUT
  )
file(
  INSTALL ${CMAKE_PROJECT_NAME}.tar.gz
  DESTINATION ${CMAKE_INSTALL_PREFIX}/src
  )

and then added to my main CMakeLists.txt at the very end:

include(esma_cpack) # This is our cpack configuration
install(CODE "set(CMAKE_PROJECT_NAME \"${CMAKE_PROJECT_NAME}\")")
install(SCRIPT "${CMAKE_SOURCE_DIR}/PostInstall.cmake")

And this…seems to work? It works because our make package_source uses CMAKE_PROJECT_NAME to name the source tarball. I had to add that install(CODE) line because I guess install() is…weird. (StackOverflow told me too :slight_smile: )

Do the CMake gurus here see any issues with what I’m doing?

Well, i’d say your project is not completely broken yet :grinning_face_with_smiling_eyes:

Your project depends on the Makefile generator. Also, if you package your project it will essentially package twice. This works with simple archive packages but i don’t know what will happen with other package generator.

Have you considered to package your project? Note that a package depends on install, which depends on a build. This makes sure your project is reproducible. Installing it directly from source does not.

Usually you have to decide if you want to install from source or if you want to install from a package, but don’t make a mix of both.

1 Like

Oooooh. Nuts. You are right. I didn’t think about ninja! Okay…more to look at… :slight_smile:

@hex First, our code isn’t really packageable. I mean it’s 5 million lines of Fortran with library dependencies up the wazoo (ESMF, netCDF, HDF, gFTL, etc.). So, it’s source all the way unfortunately. (Well, I have made AWS images so…sort of like a package. A very bulky package :smiley: )

Now, I managed to make something that seems just as bad as before. First realize the only Generators I support are Make and Ninja. Maybe others work but…yeah, I haven’t tested. So, looking at that this seems to work:

execute_process(
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR} --target package_source
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  )
file(
  INSTALL ${CMAKE_PROJECT_NAME}.tar.gz
  DESTINATION ${CMAKE_INSTALL_PREFIX}/src
  )

Again, I ask the gurus, how bad is this? It works, but seems perverse that I run cmake to make it so I can do a ninja install call that then calls cmake!

my point is that you have it backwards. Packaging is not part of the installation process. I’m not familiar with Fortran so i cannot help with that. In general what you should do is package your project sources / binaries, then use your package manager to install it.

In case of CPack, if your project can be installed it can also be packaged. Otherwise i’m not sure what your installation does or the problems you are facing. How about something like make install && cpack in your IDE or terminal? I am only suggesting this because you said your project cannot be packaged.

Edit: to be clear - i am not telling you to run the packaging with CMake but outside of it.