After Reading a *.lst file(multiple lines with different filenames along with its path),How to find specific filename with its path in CMAKE? - cmake

Lets Consider a lst file "txt_filelist.lst" which has different text files mentioned with different path's, Now After reading the "txt_filelist.lst" file how to identify a specific text file along with its path in CMAKE?
txt_filelist.lst File:
`variants\EXX\application\a2l\srcxx_xx_xx\xx_xx_xx.txt`
`variants\EXX\application\a2l\srcxx_xx_xx\xx_xx_xx.txt`
`variants\EXX\application\a2l\srcxx_xx_xx\xx_xx_xx.txt`
`variants\EXX\application\a2l\srcxx_xx_xx\xx_xx_xx.txt`
After reading the lst file txt_filelist.lst How can I first identify the srcxx_xx_xx.txt in the lst and then secondly How can I fetch its entire path as variants\EXX\application\a2l\srcxx_xx_xx\xx_xx_xx.txt in CMAKE?
Thanks in Advance..!!!

You can use file(STRINGS) to read the lines of the file to a list variable. get_filename_component can be used to separate file names according to your needs. Using file(TO_NATIVE_PATH) may be necessary, if you use get_filename_component in a way that yields a path containing separators, but most tools should be able to work with forward slashes, even on Windows:
file(STRINGS txt_filelist.lst FILE_LINES LENGTH_MINIMUM 1)
message("=========================")
foreach(LINE IN LISTS FILE_LINES)
get_filename_component(FILE_NAME "${LINE}" NAME)
get_filename_component(FILE_DIR "${LINE}" DIRECTORY)
file(TO_NATIVE_PATH "${LINE}" FILE_PATH_NATIVE)
message(
"------------------------
LINE = '${LINE}'
FILE_NAME = '${FILE_NAME}'
FILE_DIR = '${FILE_DIR}'
FILE_PATH_NATIVE = '${FILE_PATH_NATIVE}'
"
)
endforeach()
message("=========================")
Note: The LENGTH_MINIMUM 1 option is there to ignore empty lines. This may not be necessary depending on the input you get.

Related

A variable is holding multiple file paths in a single line, How to make the first file path in first line & second path in next line using CMAKE?

A CMake variable ${data} is holding multiple paths in a single line as shown below
C:/Users/s.xxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/xxxC:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/xxyyC:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/yyC:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/yyzzC:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/zzz
How to bring like shown below using Cmake
C:/Users/s.xxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/xxx
C:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/xxyy
C:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/yy
C:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/yyzz
C:/Users/s.xxxxx/Documents/CMake/25_10/xxxxx/xxxxx/variants/xxxxx/application/source/common/zzz
I tried to write the variable ${data} to a file test1.txt and tried as below
file(READ ${test1} testread)
string(REGEX REPLACE "C:/" "\ C:/" ${new_line_test} ${testread})
file(WRITE ${Fin_test} ${new_line_test})
Here it is hard coded specific to C:/, what if the project will run in D:/ or in Linux?
How to make it a generic conversion using CMake?

cmake - preset settings for entries from ini file

I have a project that uses some third party libraries. So each time I setup this project with CMake, I have to set each entry (path of the third party library) on the GUI of CMake. I improve this by making CMake script guess the path by this script (learn this technique from OGRE):
# Guess the paths.
set( OGRE_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre" CACHE STRING "Path to OGRE source code (see http://www.ogre3d.org/tikiwiki/tiki-index.php?page=CMake+Quick+Start+Guide)" )
So each time I setup with CMake, it will automatic fill the entry OGRE_SOURCE. But that doesn't enough. If the Ogre source is not in the path
"${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre"
, then I have to open and edit the CMake script or I have to edit the entry on the GUI of CMake. I find that pretty inconvenient, especially when you link to a lot of third party libraries.
So I want to use another technique: preset settings for entries from file - CMake reads the presets from file PresetEntries.txt (that I make) and apply the these presets on the entries (It's a lot quicker to edit the path in text file than on the GUI of CMake).
Here my idea about this preset file: PresetEntries.txt
OGRE_SOURCE=E:/Source/ogre
I found that CMake can read a text file, but if I use this, I have to do string manipulations.
CMake has the file CMakeCache.txt to save the settings on the CMake GUI, but I want it to be simple: it should only has the preset settings that need to be pre-set.
So I wonder if CMake support this preset settings for entries from file.
Edit:
So I read this question and see that CMake can set config from file, but this require to fire cmake with the -C mysettings.cmake, but I wanna it to be automatically with CMake GUI - just edit the file and hit generate button in CMake GUI. So I wanna make this question more specific:
In my CMakeLists.txt should have script like this:
# Guess the paths.
#I wanna have this function from C++
#https://msdn.microsoft.com/en-us/library/windows/desktop/ms724353%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
GetPrivateProfileString("OGRE", #lpAppName
"OGRE_SOURCE", #lpKeyName
"${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre", #lpDefault
OGRE_SOURCE_VAR,#lpReturnedString
MAX_PATH, #nSize, may be can reduce this variable
"LibPath.ini") #lpFileName
set( OGRE_SOURCE "${OGRE_SOURCE_VAR}" CACHE STRING "Path to OGRE source code" )
In the file LibPath.ini
[OGRE]
OGRE_SOURCE = "E:/Source/ogre"
So the user can choose to either use the ini file or not.
I don't know if there any way I can use a function that similar to function GetPrivateProfileString (of C++) in CMake.
Thanks for reading
The external libraries should be included by one of the following commands
find_package(ttnlib REQUIRED HINTS /usr/local/lib/cmake)
include_directories(${ttnlib_INCLUDE_DIR})
set(EXTRA_LIBS ${EXTRA_LIBS} ${TTNLIB_LIBRARY})
or
find_library(MY_EXTERNAL_LIB name COOLSTUFF libCOOLSTUFF libCOOLSTUF.so hints /usr/local/lib)
The search for the external packages and libraries should only be necessary for the first run of cmake.
I can't find the function to read the ini file, so what I can do is create a simple function that read simple txt file for myself.
I declare the function in 1 file for other file use it
"\CMake\Dependencies\CommonFunc.cmake"
#------------Define function Read file------------
macro( readSettingFile KEY DEFAULT_RESULT STRING_RESULT_OUT)
unset(STRING_RESULT)
# Read the file
file( READ "${CMAKE_SOURCE_DIR}/LibPath.txt" LIB_PATH_STR )
# Set the variable "Esc" to the ASCII value 27 - basically something
# which is unlikely to conflict with anything in the file contents.
string(ASCII 27 Esc)
# Turn the contents into a list of strings, each ending with an Esc.
# This allows us to preserve blank lines in the file since CMake
# automatically prunes empty list items during a foreach loop.
string(REGEX REPLACE "\n" "${Esc};" LIB_PATH_LINES "${LIB_PATH_STR}")
foreach(LINE ${LIB_PATH_LINES})
if("${LINE}" MATCHES "${KEY}")
#remove the key, leave the content untouch
string(REPLACE "${KEY}" "" STRING_RESULT ${LINE})
# Swap the appended Esc character back out in favour of a line feed
string(REGEX REPLACE "${Esc}" "" STRING_RESULT ${STRING_RESULT})
endif()
endforeach()
if("${STRING_RESULT}" STREQUAL "")
set( STRING_RESULT ${DEFAULT_RESULT} )
endif()
#message( STATIC "---GTA Sa-----" "[${STRING_RESULT}]" )
endmacro()
(I need the help from this answer to write this function :p)
Here is how I use
For example: "\CMake\Dependencies\Ogre.cmake"
#include common functions
include( CMake/Dependencies/CommonFunc.cmake )
#---------------Guess the paths.----------------------
#----Set OGRE_SOURCE
readSettingFile( "OGRE_SOURCE="
"E:/Source/ogre"
STRING_RESULT
)
set( OGRE_SOURCE "${STRING_RESULT}" CACHE STRING "Path to OGRE Source" )
#----Set OGRE_BINARIES
readSettingFile( "OGRE_BINARIES="
"E:/Source/_build/ogre"
STRING_RESULT
)
set( OGRE_BINARIES "${STRING_RESULT}" CACHE STRING "Path to OGRE's build folder generated by CMake" )
Here is the setting file
"\LibPath.txt"
OGRE_SOURCE=E:/Source/ogre
OGRE_BINARIES=E:/Source/_build/ogre

Excluding directory somewhere in file structure from cmake sourcefile list

In any subdirectory of my project it shall be possible to create anywhere a directory called 'hide' and put some code files (.c, .cpp, .h, ...) inside. CMake shall ignore those files. How can I achieve this?
Any proposals for a simple approach? Searched the net but could not find a solution.
What I tried:
file & glob
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
file(GLOB_RECURSE REMOVE_SOURCES
"*/hide/*"
"${PROJECT_SOURCE_DIR}/CMakeFiles/*"
"*main.c")
file(GLOB_RECURSE REMOVE_SOURCES "*/hide/*")
list(REMOVE_ITEM SOURCE_FILES ${REMOVE_SOURCES})
The 2rd line works fine if the directory path is known (as for the 'CMakeFiles' directory) or if the file is known (as for the 'main.c' file). But it does not work if there are two '*' for a string. I can not find a simple solution for a directory which is located somewhere.
Regex
Then I tried with REGEX.
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
string(REGEX REPLACE ";.*/hide/.*;" ";" FOO ${SOURCE_FILES})
Because the source file list is separated by semicolon, the line above shall remove the string from one semicolon to the next in case it contained the string 'hide'.
The expression seems to have a problem with the semicolon. Having any semicolon makes the command to find nothing.
foreach loop
I tried with some foreach loops, but could not achieve to get a list of all my 'hide'-directories.
One of the ways, I suppose, would be just like this:
set (EXCLUDE_DIR "/hide/")
file (GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
foreach (TMP_PATH ${SOURCE_FILES})
string (FIND ${TMP_PATH} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
list (REMOVE_ITEM SOURCE_FILES ${TMP_PATH})
endif ()
endforeach(TMP_PATH)
Simply searching for /hide/ substring in strings from the list. If the substring found --- remove whole string from the list.
Beware, this might be only solution for Linux. And might not work on older versions of CMake (<2.8.5, according to this).
In mentioned case You can do something like:
# try to replace substring with empty string, compare to original:
string (REPLACE ${EXCLUDE_DIR} "" REPLACED_PATH ${TMP_PATH})
string (COMPARE EQUAL ${TMP_PATH} ${REPLACED_PATH} EXCLUDE_DIR_FOUND)
NOTE: GLOB_RECURSE is considered to be root of all evil.
NOTE2: another thing to be aware of - CMake bug in matching empty variable to string.
NOTE3: took into account gg99's comment
Found a solution that works for me. Added a function to make it easy to exclude another directory.
# Function: EXCLUDE_FILES_FROM_DIR_IN_LIST
# Description: Exclude all files from a list under a specific directory.
# Param _InFileList: Input and returned List
# Param _excludeDirName: Name of the directory, which shall be ignored.
# Param _verbose: Print the names of the files handled
FUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST _InFileList _excludeDirName _verbose)
foreach (ITR ${_InFileList})
if ("${_verbose}")
message(STATUS "ITR=${ITR}")
endif ("${_verbose}")
if ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)") # Check if the item matches the directory name in _excludeDirName
message(STATUS "Remove Item from List:${ITR}")
list (REMOVE_ITEM _InFileList ${ITR}) # Remove the item from the list
endif ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)")
endforeach(ITR)
set(SOURCE_FILES ${_InFileList} PARENT_SCOPE) # Return the SOURCE_FILES variable to the calling parent
ENDFUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST)
EXCLUDE_FILES_FROM_DIR_IN_LIST("${SOURCE_FILES}" "/hide/" FALSE)
Generalizing the function solution mentioned above you get something like:
# Remove strings matching given regular expression from a list.
# #param(in,out) aItems Reference of a list variable to filter.
# #param aRegEx Value of regular expression to match.
function (filter_items aItems aRegEx)
# For each item in our list
foreach (item ${${aItems}})
# Check if our items matches our regular expression
if ("${item}" MATCHES ${aRegEx})
# Remove current item from our list
list (REMOVE_ITEM ${aItems} ${item})
endif ("${item}" MATCHES ${aRegEx})
endforeach(item)
# Provide output parameter
set(${aItems} ${${aItems}} PARENT_SCOPE)
endfunction (filter_items)
You can then use it thus:
file(GLOB_RECURSE MyFunFiles "*.fun")
filter_items(MyFunFiles ".*NotCool.*")

Filter files from directory vb.net

Straight to the question...I have files such as word documents with extension(.doc) and its respective sample files starting with (.sample)
Now I would like to load only the word documents..
I found the way as shown below to load the files but this loads all the files
Can anyone say me how do I filter these files while loading them ?
This is what I'm trying to do:
Dim files = Array.FindAll(Directory.GetFiles(mydir), Function(x) (Not x.StartsWith(".sample")))
This is my directory consists of files as said above:
The way you use it, all the files are retrieved (paying the whole computational cost) and then they are filtered.
As stated in this article, you can use a search pattern directly in file retrieval from your file system.
I suppose you could do something like that:
Dim files = Directory.GetFiles(mydir,".doc*")
If you gave an example of filenames, perhaps I would give you the right filter to apply too.
Hope I helped!
The GetFiles method returns filenames with the path that you specified included.
So if your files are in a folder C:\working\, your mydir variable will contain "C:\working\" and all of the results of GetFiles will be something like
"C:\working\.sample_filename.doc"
"C:\working\123797.doc"
So your x.StartsWith is always going to return false, because x always starts with C:\
Try this:
Dim files = Array.FindAll(Directory.GetFiles(mydir), Function(x) (Not x.StartsWith(mydir & ".sample")))
Note this assumes that your mydir variable ends with a \ character. If not, add it in in the concatenation within the function.
Try this,
Dim files = Array.FindAll(Directory.GetFiles(mydir), Function(x) (Not Path.GetFileName(x).StartsWith(".sample")))

CMAKE aux_source_directory exclude pattern

I want to include all filed in source directory leaving one file.
Is there any way to using aux_source_directory or anything else I can include all files leaving that file ?
There are two possible solutions:
Use file (GLOB ... instead of aux_source_directory with a globbing expression that does not match that one file but includes all the others, e.g.:
file(GLOB _srcFiles "src/f[1-3].cpp")
This will match match files f1.cpp, f2.cpp, f3.cpp, but not f4.cpp.
Or use aux_source_directory and then remove the file to be excluded explicitly with a list(REMOVE_ITEM command, e.g.:
aux_source_directory(src _srcFiles)
list(REMOVE_ITEM _srcFiles "src/f4.cpp")