Help getting CMake to install a library created by custom command

I have an odd situation that I’m struggling with the CMake for. I work on a big Fortran source code that now has a need to build a shared object library and include file where they are created by Python and not by Fortran. We have a “main” library (made by Fortran) here which works just fine, called libFVdycoreCubed_GridComp.a (or .so, I suppose, but static for now). It’s this “extra” library that’s getting me.

Now, I can build the library at the moment with some horribly ugly CMake that creates an INTERFACE library (not sure if that’s what I should do?) and all seems to build. The library is made, all the executables that need it are satisifed, etc.

Now, at the end of my install step, I see the library in the build directory (aka CMAKE_CURRENT_BINARY_DIR for this file):

$ ls -l src/Components/@GEOSgcm_GridComp/GEOSagcm_GridComp/GEOSsuperdyn_GridComp/@FVdycoreCubed_GridComp/
total 610
drwxr-xr-x  4 mathomp4 g0620   512 Jan 24 13:53 @fvdycore/
drwxr-xr-x 10 mathomp4 g0620  8192 Jan 24 13:53 CMakeFiles/
-rw-r--r--  1 mathomp4 g0620   581 Jan 24 12:26 CTestTestfile.cmake
-rw-r--r--  1 mathomp4 g0620 70632 Jan 24 13:53 Makefile
-rw-r--r--  1 mathomp4 g0620 13425 Jan 24 13:53 cmake_install.cmake
-rw-r--r--  1 mathomp4 g0620 72548 Jan 24 13:54 fv_dynamics_interface_py.c
-rw-r--r--  1 mathomp4 g0620  2236 Jan 24 13:53 fv_dynamics_interface_py.h
-rw-r--r--  1 mathomp4 g0620 60104 Jan 24 13:54 fv_dynamics_interface_py.o
-rwxr-xr-x  1 mathomp4 g0620 54096 Jan 24 13:54 libfv_dynamics_interface_py.so*
drwxr-xr-x  3 mathomp4 g0620   512 Jan 24 13:53 scripts/

But I have one last thing I can’t figure out. I want/need this libfv_dynamics_interface_py.so file to end up in install/lib and I can’t seem to get it there. For example, I’ve tried:

install(TARGETS fv_dynamics_interface_py
  EXPORT ${PROJECT_NAME}-targets
  LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
  )

but I’m guessing install doesn’t really see it as an “actual” library. Okay, I also tried adding an explicit:

install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/libfv_dynamics_interface_py.so
  DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)

But, nope, not there at make install.

Maybe this is all due to the fact I sort of “hijacked” the add_library(INTERFACE) to try and get this to work?

I’m sure I’m missing something obvious…but it’s evading me!

Okay. I have…something. I tried adding a add_custom_command(POST_BUILD) on my library, but I got a "POST_BUILD not allowed on INTERFACE library" error. But, my library depended on a custom_target that made the library and:

set(FVDYN_INTERFACE_LIBRARY
  ${CMAKE_CURRENT_BINARY_DIR}/libfv_dynamics_interface_py.so
  )

set(FVDYN_INTERFACE_HEADER_FILE
  ${CMAKE_CURRENT_BINARY_DIR}/fv_dynamics_interface_py.h
  )

set(FVDYN_INTERFACE_SRCS
  ${CMAKE_CURRENT_SOURCE_DIR}/fv_dynamics_interface.py
  )

add_custom_command(
  OUTPUT ${FVDYN_INTERFACE_LIBRARY}
  COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 1 ${Python_EXECUTABLE} ${FVDYN_INTERFACE_SRCS}
  BYPRODUCTS ${FVDYN_INTERFACE_HEADER_FILE}
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  DEPENDS ${FVDYN_INTERFACE_SRCS}
  COMMENT "Building library with Python"
  VERBATIM
  )

add_custom_target(fv_dynamics_interface_py_h DEPENDS ${FVDYN_INTERFACE_LIBRARY})
add_custom_command(TARGET fv_dynamics_interface_py_h
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy "${FVDYN_INTERFACE_LIBRARY}" ${CMAKE_INSTALL_PREFIX}/lib)

I’m pasting this because maybe an expert will see something bad. For the INTERFACE bits:

add_library(fv_dynamics_interface_py INTERFACE)
target_include_directories(fv_dynamics_interface_py INTERFACE
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # stubs
  # modules and copied *.h, *.inc
  $<BUILD_INTERFACE:${esma_include}/${this}>
  $<INSTALL_INTERFACE:include/${this}>
  )
target_link_libraries(fv_dynamics_interface_py INTERFACE ${FVDYN_INTERFACE_LIBRARY})
add_dependencies(fv_dynamics_interface_py fv_dynamics_interface_py_h)

install(TARGETS fv_dynamics_interface_py
  EXPORT ${PROJECT_NAME}-targets
  LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
  )

This is sort of a “borrow from a lot of bits of our code base” hodge-podge of CMake. I’m currently at “Get working” not “make correct” :slight_smile: