cmake-basis/BASIS

Installing externally supplied headers in nonstandard directories via basis

ahundt opened this issue · 8 comments

moved from #339

It seems a problem has come up again with my software installation, some header files are missing from the install and their location is also not on the include path:
ahundt/grl#128

It is due to my script that unzips and builds a user supplied zip file with source provided by another company (I can't change the contents):
https://github.com/ahundt/grl/blob/master/config/FRI_Client_SDK_Cpp.cmake

I need to install the unzipped headers into an appropriate location so users can include it in their own code.

I think I need to add an $<INSTALL_INTERFACE:include/mylib> parameter to the target_include_directories() call, but I think I'll also need an installation call for the individual headers.

I can write custom cmake code that does this, but some of the basis automation may be lost for those files. Do you have recommendations on what I can do?

If I should just write custom install code for this component that's okay, was just hoping to clarify if I might be able to use an appropriate basis function to make sure install/uninstall other basis features still work smoothly with minimal custom steps.

To clarify, I can change the contents of the cmake script that unzips builds and installs the code. I cannot change the zip itself.

I guess what it comes down to is how the BASIS functions are supposed to work, which ones you use, and what you expect of them otherwise...

basis_add_library: only handles source files that you provide as arguments. For these files of the library target it will add installation rules, but not for any other file that is included by these source files.

basis_install_directory: installs an entire subtree (I believe it's recursive), for each file within the directory, I think a corresponding removal command should be added to the uninstall script. See <Project>Uninstall.cmake file in <prefix>/lib/cmake/<project>/ of the installation.

basis_include_directories: works just as CMake's include_directories, hence, has nothing to do with installation.

target_include_directories: not a BASIS command, but also does not automatically add any installation rules.

I not quite sure what you would expect from BASIS to do in this case? Can you provide a minimalistic example of functionality you think should be there?

Otherwise, it looks to me as if you need to add manual installation steps (e.g., using basis_install_directory or basis_install) plus target_include_directories to have CMake add the respective paths to the include path of the exported targets.

Maybe you could extract this external zip in a modules subdirectory and then copy a BasisProject.cmake and possibly CMakeLists.txt file into this subdirectory, where the BasisProject.cmake file sets INCLUDE_DIR, CODE_DIR, and the like according to the external projects structure using basis_project ?

I.e., kind of patch the unzipped subproject to turn it into a BASIS module (subproject) which your top-level project (or other modules) then depend on. You'd add a CMakeLists.txt for the build of the libraries of this external module to the extracted files with the respective basis_add_library commands between basis_project_begin() and basis_project_end() (see impl of basis_project_impl for reference).

Interesting idea, is the top level Settings.cmake run early enough that if I generated a new modules repository in that way it would be picked up? Or should it be checked somewhere else?

probably not if it has to be between or before the basis_project_begin() call.

I'll try something out in a bit! Thanks for your suggestions. :-)

I think this should be part of a pre-configuration step. It seems to be part of a source code download rather than build configuration.

Respectively, you can perform the download and patching before basis_project_begin in your top-levels CMakeLists.txt. Still, that's more like Hunter works and I'm not a big fan of download during the CMake project build configuration stage...