I want to install all files under a folder called scfg which contains .cfg, .xml files, and folders to another location which contains scfg. The code below installs correctly.
file(GLOB config_files "scfg/*.cfg")
install(FILES ${config_files} DESTINATION scfg)
file(GLOB xml_files "scfg/*.xml")
install(FILES ${xml_files} DESTINATION scfg)
But it is possible that there will be more files with types other than .cfg and .xml in the future. To prevent changing this file frequently, I am looking for a more generic solution, such as installing all file types other than folders. I have heard about the EXCLUDE keyword. But I don't know what PATTERN I should use for folders.
It should exclude subdirectories explicitly and then all other files will be installed correctly as usual.
install(DIRECTORY scfg/ DESTINATION scfg
PATTERN "scfg/config/" EXCLUDE
PATTERN "scfg/xml/" EXCLUDE
)
Related
assuming i have the next structure in my project:
src_dir\a
src_dir\b\b2
src_dir\c\c2\c3
and in each folders i have few types of files (.txt, .lib, .dll....)
i want to install only the dll files in directory X, so i tried:
install(
DIRECTORY src_dir
DESTINATION X/
COMPONENT DLLS
FILES_MATCHING PATTERN "*.dll"
)
it does work fine but it give me the full structure of my original structure (and i only want the dll files in X directory). the output it:
X/a/a.dll
X/b/b2/b.dll
X/c/c2/c3/c.dll
and i want it to be like that a.dll, b.dll and c.dll will be in X (without any sub-folders).
is there a way to do it without giving the full paths to every dll file i have in my project?
Thanks :)
You should be able to get the behaviour you want by listing each directory, not necessarily each DLL. If you include a trailing forward slash at the end of the DIRECTORY, it will omit the directory name when copying to the destination. I'd expect something like the following to achieve what you want:
install(
DIRECTORY src_dir/a/
DESTINATION X
COMPONENT DLLS
FILES_MATCHING PATTERN "*.dll"
)
install(
DIRECTORY src_dir/b/b2/
DESTINATION X
COMPONENT DLLS
FILES_MATCHING PATTERN "*.dll"
)
install(
DIRECTORY src_dir/c/c2/c3/
DESTINATION X
COMPONENT DLLS
FILES_MATCHING PATTERN "*.dll"
)
I'm trying to create an installation package with CMake and CPack. Everything works fine, but I would like to reduce the amount of code drastically by copying my resources folder entirely with one call instead of one for every subfolder.
So far, I do component wise installation the following way:
set(RESOURCES_CALIBRATION_DIR resources/calibration)
file(GLOB RESOURCES_CALIBRATION "${CMAKE_SOURCE_DIR}/${RESOURCES_CALIBRATION_DIR}/*")
install(FILES ${RESOURCES_CALIBRATION} DESTINATION ${RESOURCES_CALIBRATION_DIR} COMPONENT ResourcesCalibration)
set(RESOURCES_CURSORS_DIR resources/cursors)
file(GLOB RESOURCES_CURSORS "${CMAKE_SOURCE_DIR}/${RESOURCES_CURSORS_DIR}/*")
install(FILES ${RESOURCES_CURSORS} DESTINATION ${RESOURCES_CURSORS_DIR} COMPONENT ResourcesCursors)
...
... (repeat for every folder of my resources folder)
set(CPACK_COMPONENTS_ALL applications ResourcesCalibration ResourcesCursors ...)
set(CPACK_COMPONENT_RESOURCESCALIBRATION_GROUP "resources")
set(CPACK_COMPONENT_RESOURCESCURSORS_GROUP "resources")
...
...
Is there a clean way to copy / install the entire resources folder including all subfolders?
Command flow install(DIRECTORY) exists specifically for installing directory with its subdirectories and files.
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources/
DESTINATION resources
COMPONENT ResourcesCursors)
or even
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources
DESTINATION .
COMPONENT ResourcesCursors)
will copy resource directory in the source tree to the installation directory. See documentation on install for more info.
I have a folder full of source files (*.h, *.cpp), that I want to include in a new project. However, the folder also contains two files (main.cpp, CMakeLists.txt) that I don't want to include in the new project (for obvious reasons).
I know that the commands:
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
add all the source files in the project directory to the project. Also I could say:
aux_source_directory(/path/to/folder/ SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
to include all source files in a folder. But how can I exclude some specific files (in this example, /path/to/folder/main.cpp and /path/to/folder/CMakeLists.txt)?
But how can I exclude some specific files
Try this (according to Documentation):
list (REMOVE_ITEM SRC_LIST /path/to/folder/main.cpp /path/to/folder/CMakeLists.txt)
This question looks like related.
I have a CMakeLists.txt file for a library. It's pretty basic:
set(LIB_FILES source/first.cpp)
add_library(first ${LIB_FILES})
I put the files in a list because I will eventually be adding more source files to the library. The problem is that all of the files will be in the source directory. And I don't want to constantly have to repeat that.
I also don't want to use the GLOB pattern matching solution, because I want to have to edit the CMakeLists.txt file when I add a new file. That way, my build will re-build the build solution, and new files will correctly appear (as I understand it. I'm still new with CMake).
I tried adding a CMakeLists.txt file into the source directory itself, just to build the LIB_FILES list. That didn't work out very well. Variables in CMake are file scoped. And even when I broke scoping (with PARENT_SCOPE), I still had to prefix each file with the directory. So that gained nothing.
I don't want to put the actual library definition in the source directory, as that will generate all the build files in the source directory. And I don't want that. Also, I will need to include headers that aren't in or under the source directory.
My directory structure looks like this:
libroot (where the project build files should go)
\-source (where the source code is)
\-include (where the headers that the user of the library includes go)
So how do I tell CMake that all of the source files come from the source directory, so that I don't have to constantly spell it out?
You could move the add_library call to your source/CMakeLists.txt also:
set(LIB_FILES first.cpp)
add_library(first ${LIB_FILES})
Then just use add_subdirectory in your top-level CMakeLists.txt:
add_subdirectory(source)
you could use a simple macro for that
macro(AddSrc dst_var basepath_var)
foreach(file ${ARGN})
list(APPEND ${dst_var} ${basepath_var}/${file})
endforeach()
endmacro()
set(MY_SRCFILES "")
AddSrc(MY_SRCFILES path/to/source
foo.cpp
bar.cpp
whatever.cpp
)
I've created a list of files using:
file(GLOB_RECURSE DEPLOY_FILES "${PROJECT_SOURCE_DIR}/install/*")
I want to install all of these files in /usr/myproject/, but I want to maintain the file tree on the installed folder:
install/junk
install/other/junk2
install/other/junk3
If I use:
install(FILES ${DEPLOY_FILES} DESTINATION "usr/myproject")
All the files end up in /usr/myproject as:
/usr/myproject/junk
/usr/myproject/junk2
/usr/myproject/junk3
How can I make the install command keep track of relative paths?
I've worked around the issue by doing it manually in a for loop:
set(BASE "${PROJECT_SOURCE_DIR}/install")
foreach(ITEM ${DEPLOY_FILES})
get_filename_component(ITEM_PATH ${ITEM} PATH)
string(REPLACE ${BASE} "" ITEM_PATH ${ITEM_PATH})
install(FILES ${ITEM} DESTINATION "usr/myproject${ITEM_PATH}")
endforeach()
...but this is annoying to do. Surely there's an easier way?
(I can't see anything in the install documentation though...)
The simplest way to install everything from a given directory is:
install(DIRECTORY mydir/ DESTINATION dir/newname)
Trailing '/' is significant.
Without it mydir would be installed to newname/mydir.
From the CMake documentation:
The last component of each directory name is appended to the destination
directory but a trailing slash may be used to avoid this because it
leaves the last component empty.
I am assuming you have a list of files, let's say INCLUDE_FILES. Possibly a selection of files spread over a number of subdirectories, e.g. header files from across the source tree, as opposed to everything in a single subdir like in the other answers.
You can loop over the file list and use get_filename_component() to extract the directory part, then use that in a subsequent install() to set the DESTINATION subdirectory:
foreach ( file ${INCLUDE_FILES} )
get_filename_component( dir ${file} DIRECTORY )
install( FILES ${file} DESTINATION include/${dir} )
endforeach()
Done. ;-)
Edit: If all the files you want to install that way match a particular file pattern -- e.g. "all header files" -- then brno's answer has the edge over this one.
Use:
INSTALL( DIRECTORY <directory> DESTINATION usr/myproject )
(See here for details: http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:install)
INSTALL( DIRECTORY ... ) preserves the directory structure. But, if you use install as <directory>, you would end up with usr/myproject/install/.... which is not what you want.
There are two ways to do this:
Use INSTALL( FILES .... DESTINATION usr/myproject) to install the files that lie directly in install/, then use INSTALL( DIRECTORY .... DESTINATION usr/myproject) and manually list the directories to install.
Use your globbing command in your original post, and then determine which entries are files, which are directories, move the directory entries to a separate list, feed the lists to INSTALL( FILES ...) and INSTALL( DIRECTORY ...), respectively.
file(GLOB DEPLOY_FILES_AND_DIRS "${PROJECT_SOURCE_DIR}/install/*")
foreach(ITEM ${DEPLOY_FILES_AND_DIRS})
IF( IS_DIRECTORY "${ITEM}" )
LIST( APPEND DIRS_TO_DEPLOY "${ITEM}" )
ELSE()
LIST( APPEND FILES_TO_DEPLOY "${ITEM}" )
ENDIF()
endforeach()
INSTALL( FILES ${FILES_TO_DEPLOY} DESTINATION usr/myproject )
INSTALL( DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION usr/myproject )
Note: Depending on the type of files you install, other INSTALL( ...) commands might be more appropriate (for example, INSTALL( TARGETS .... ) to install your libraries/executables.
Since globbing is not recommended, and running loops in CMakeLists.txt files is clunky, a pattern matching option of DIRECTORY did the trick for me.
install(DIRECTORY src/ DESTINATION include FILES_MATCHING PATTERN "*.h")
This took the entire folder structure inside src/ and reproduced it within <INSTALL_DIR>/include, header files only.