11

Using cmake 2.8

I would like to maintain the directory hierarchy while copying the header files from the source to the destination directory. For example, the header file that needs to be copied are abc/1.h, def/2.h and they should also be copied in the same order in the destination directly ( set via CMAKE_INSTALL_PREFIX )

This is what I have tried, but it just copies the header files and not the header files inclusive parent directory name

set(HEADERS "abc/1.h;def/2.h")
install(FILES ${HEADERS} DESTINATION include)

The final output should be dest_directory/abc/1.h and dest_directory/def/2.h.

infoclogged
  • 3,641
  • 5
  • 32
  • 53

3 Answers3

24

If you have many files in the directory for install, you may consider to install the directory with install(DIRECTORY) command flow. You may select which files in the directory should be installed with PATTERN or REGEX options:

install(DIRECTORY "${CMAKE_SOURCE_DIR}/" # source directory
        DESTINATION "include" # target directory
        FILES_MATCHING # install only matched files
        PATTERN "*.h" # select header files
)

See CMake documentation for more information about the install(DIRECTORY). Also, it describes meaning '/' at the end of source directory.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • found an exact duplicate here - https://stackoverflow.com/questions/20796048/regex-in-cmake-install-command – infoclogged Jan 11 '18 at 23:48
  • @infoclogged: On Stack Overflow *answers* cannot be duplicate, only *questions*. Referenced answer explains similar things like my one, but do that from a different point of view, as the questions are different. – Tsyvarev Jan 12 '18 at 07:29
  • I was actually referring to the question, but after your post, I realised its different. Thank you for the hint :) – infoclogged Jan 12 '18 at 09:39
  • 1
    I would recommend using CMAKE_CURRENT_SOURCE_DIR if you have a multi-level hierarchy directory. – pratikpc Feb 26 '22 at 08:21
3

In the spirit of the question, we wanted to install all the headers in a HEADER variable, which would not necessarily include all headers in a given directory (for e.g., there might be platform dependent headers).

We adressed this problem with the following macro, which actually installs all the files given to FILES while creating the parent directories, if any:

macro(install_with_directory)
    set(optionsArgs "")
    set(oneValueArgs "DESTINATION")
    set(multiValueArgs "FILES")
    cmake_parse_arguments(CAS "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

    foreach(FILE ${CAS_FILES})
        get_filename_component(DIR ${FILE} DIRECTORY)
        INSTALL(FILES ${FILE} DESTINATION ${CAS_DESTINATION}/${DIR})
    endforeach()
endmacro(install_with_directory)
Ad N
  • 7,930
  • 6
  • 36
  • 80
  • That's a great option ! An example of how using the macro : ```install_with_directory( DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${CMAKE_PROJECT_NAME}/ FILES ${HEADERS})``` with HEADERS a list of headers files with their directories. – Kafka Sep 16 '20 at 08:49
1

Just found the answer myself after trying a couple of times. It needs to be done in multiple steps.

install(FILES "abc/1.h" DESTINATION "include/abc")
install(FILES "def/2.h" DESTINATION "include/def")

In complicated situations, a REGEX can be used. Please see Regex in CMake install command

infoclogged
  • 3,641
  • 5
  • 32
  • 53