get_filename_component can be used to remove/extract the longest extension.
EXT = File name longest extension (.b.c from d/a.b.c)
NAME_WE = File name without directory or longest extension
I have a file with a dot in its name, so I need the shortest extension:
set(MYFILE "a.b.c.d")
get_filename_component(MYFILE_WITHOUT_EXT ${MYFILE} NAME_WE)
message(STATUS "${MYFILE_WITHOUT_EXT}")
reports
-- a
but I want
-- a.b.c
What is the preferred way to find the file name without the shortest extension?
I would do:
string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${MYFILE})
The regular expression matches a dot (\\.
, see next paragraph), followed by any number of characters that is not a dot [^.]*
until the end of the string ($
), and then replaces it with an empty string ""
.
The metacharacter dot (normally in a regular expression it means "match any character") needs to be escaped with a \
to be interpreted as a literal dot. However, in CMake string literals (like C string literals), \
is a special character and need to be escaped as well (see also here). Therefore you obtain the weird sequence \\.
.
Note that (almost all) metacharacters do not need to be escaped within a Character Class: therefore we have [^.]
and not [^\\.]
.
Finally, note that this expression is safe also if there's no dot in the filename analyzed (the output corresponds to the input string in that case).
Link to string command documentation.
As of CMake 3.14 it is possible to do this with get_filename_component
directly.
NAME_WLE
: File name without directory or last extension
set(INPUT_FILE a.b.c.d)
get_filename_component(OUTPUT_FILE_WE ${INPUT_FILE} NAME_WE)
get_filename_component(OUTPUT_FILE_WLE ${INPUT_FILE} NAME_WLE)
OUTPUT_FILE_WE
would be set to a
, and OUTPUT_FILE_WLE
would be set to a.b.c
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With