why Cmake's " file(REMOVE_RECURSE [file1 ...]) "does not remove file having *.xxx.yy extension file? - cmake

I want to remove all the files from my binary directory which has ".asm.js" extension
below is my source code
file (REMOVE
${CMAKE_BINARY_DIR}/dist/*.asm.js
)
Unfortunately, It's not able to delete the file which has .asm.js extension.
is there anyone who can help me with this
Thanks in advance

As CMake docs says :
Remove the given files. The REMOVE_RECURSE mode will remove the given
files and directories, also non-empty directories. No error is emitted
if a given file does not exist.
So you need to do a list of files to send it to file(REMOVE)
To do it you can use :
file(GLOB MY_FILES ${CMAKE_BINARY_DIR}/dist/*.asm.js)
Or if you want to match them in subdirectories :
file(GLOB_RECURSE MY_FILES ${CMAKE_BINARY_DIR}/dist/*.asm.js)
Then you can use your command :
file (REMOVE
${MY_FILES}
)

if you want to delete all the "asm.js" type of files in the subdirectory as well then you can use the below command
file(GLOB_RECURSE MY_FILES ${CMAKE_BINARY_DIR}/dist/**/*.asm.js)

Related

CMakeLists - how to recursively delete directories

How can I have cmake recursively delete directories, equivalent to rm -rf?
I have tried using file(REMOVE_RECURSE which sounds like the right thing but I found that file(REMOVE_RECURSE test/) will delete a directory called test if test is empty or contains files or empty directories. However, if test contains another directory which contains a file, nothing is deleted - it is silently ignored.
cmake version 3.18.4
I found the same with cmake 3.17.5.
My fix was to specify the full path, as in:
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/test/)

How to find the path to a file recursively using CMake?

I have placed some header files in a subdirectory next to CMakeLists.txt called "dependencies". I want to search this directory recursively to find a header file. I'm trying the below command, but it's not working:
find_path(ALLEGRO_INCLUDE_DIR NAMES "allegro*.h" PATHS ${CMAKE_CURRENT_SOURCE_DIR})
You can use the following command instead:
file(GLOB_RECURSE ALLEGRO_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/allegro*.h")

CMake: install(FILES ...) for a file containing a list of files

Consider I have a simple text file containing a list of (absolute) file paths.
Is there any easy way to make CMake install those files (as if install(FILES ...) was used)?
Directory structure (minus some constant leading path components) should be maintained.
Right now the only option I could come up with was to use
install(CODE "execute_process(COMMAND my_script.sh)")
and do it using normal shell commands, but that seems to defeat the purpose of using a build system in the first place...
I believe this would do the trick:
# 'filename' is the file that contains a list ';' separated paths relative to that input file
function(install_my_files filename)
file(READ ${filename} relative_paths)
get_filename_component(parent_directory ${filename} DIRECTORY) # parent directory of input file
foreach(relative_path ${relative_paths})
get_filename_component(relative_directory ${relative_path} DIRECTORY)
install(FILES "${parent_directory}/${relative_path}" DESTINATION ${relative_directory})
endforeach()
endfunction()

Where is CMake's `FILE (GLOB` relative to?

If I do FILE (GLOB "*.cpp") where does it look? What is the working directory of the search? Is it the current source directory? This doesn't seem to be documented anywhere (although it is for FILE (COPY).
The FILE(GLOB globbing expression) accepts paths in the globbing expression to. Thus you can include any path into the expression. The following example finds all files with extension dat in subfolder testdata:
file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/testdata/*.dat")
Note: The usage of predefined path variables like CMAKE_CURRENT_SOURCE_DIR avoids any thinking about relative paths and made CMakeLists.txt more reusable and platform independent.
Bad:
file(GLOB generatedSources "../build-arm/autocode/*.c")
Good:
file(GLOB generatedSources "${PROJECT_BINARY_DIR}/autocode/*.c")
You can also specify a RELATIVE path. I'm not sure when the RELATIVE option was added, but it appears to be available from at least v3.0.2.
The search occurs in the current source directory, i.e. the directory of your CMakeLists.txt.
As a side remark regarding what you want to achieve with this, I would emphasize the following:
Note: We do not recommend using GLOB to collect a list of source files
from your source tree. If no CMakeLists.txt file changes when a source
is added or removed then the generated build system cannot know when
to ask CMake to regenerate.

How to use file glob in a different directory in CMake

file(GLOB ...) and file(GLOB_RECURSE ...) only seems to work on the current source directory. Is there any way to glob a different directory?
file(GLOB) can be a little confusing at first, i had a similar issue a few months ago.
You have to specify your path directly in the <globbing-expressions> :
file(GLOB <variable>
[LIST_DIRECTORIES true|false] [RELATIVE <path>]
[<globbing-expressions>...])
For example :
file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/directory/*.cpp")
foreach(file_path ${my_cpp_list})
message(${file_path})
endforeach()
Will print the path of all .cpp files in ${CMAKE_CURRENT_SOURCE_DIR}/directory.
I had the same issue where no matter what path I specified, I would get a glob from CMAKE_CURRENT_SOURCE_DIR. The issue was that the path I was providing to GLOB wasn't valid, and it was reverting (gracefully, but annoyingly) to CMAKE_CURRENT_SOURCE_DIR. For example, either of the following will create the symptom you see:
file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/directory *.cpp")
I forgot the "/" after "directory". This was why I never got valid results, even with valid directory names.
file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/directoryy/*.cpp")
There is no sub-folder named "directoryy"