I want to collect all the source or header files from a specified folder, also matching a curtain naming convention. I don't want to use GLOBbing, and also couldn't find any examples of an approach using only cmake.
One answer from this question suggests to use ls *.cpp into CMakeLists.txt. So I though of getting a list of sources via invoking a batch script in CMakeLists.
But something is wrong. Though it seems that the output is totally correct, CMake can not find those files. The path is (visually) correct: if I manually type it into add_executable, generating will succeed.
While I still want to know how to achieve the initial intent, I am extremely confused about the reason why totally identical strings compare to false:
CMake log:
-- Manually-typed: C:/Repos/cmake-scanner/src/main.cpp
-- Recieved-batch: C:/Repos/cmake-scanner/src/main.cpp
-- Path strings not identical
CollectSources.bat
@echo off
set arg1=%1
set arg2=%2
powershell -Command "$path = '%1'.Replace('\','/'); $headers = New-Object Collections.Generic.List[string]; ls -Name $path/*.%2 | foreach-object{ $headers.Add($path + '/' + $_)}; $headers"
CMakeLists.txt
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(Auto-scanner)
set(HEADERS)
set(SOURCES)
if(WIN32)
execute_process(
    COMMAND CMD /c ${CMAKE_CURRENT_SOURCE_DIR}/CollectSources.bat ${CMAKE_CURRENT_SOURCE_DIR}/include h
    OUTPUT_VARIABLE res
    )
message(STATUS "Found headers: ${res}")
execute_process(
    COMMAND CMD /c ${CMAKE_CURRENT_SOURCE_DIR}/CollectSources.bat ${CMAKE_CURRENT_SOURCE_DIR}/src cpp
    OUTPUT_VARIABLE res2
    )
message(STATUS "Found sources: ${res2}")
set(${HEADERS} ${res})
endif(WIN32)
message(STATUS "Collected headers: ${HEADERS}")
message(STATUS "Manually-typed: C:/Repos/cmake-scanner/src/main.cpp")
message(STATUS "Recieved-batch: ${res2}")
if(NOT "C:/Repos/cmake-scanner/src/main.cpp" STREQUAL "${res2}")
message(STATUS "Path strings not identical")
else()
message(STATUS "Path strings are identical")
endif()
add_executable(${PROJECT_NAME}
    ${res}
    ${res2}
    )
target_include_directories(${PROJECT_NAME}
    PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    )
and project tree:
cmake-scanner
|-include 
|  |-IPublicA.h
|  |-IPublicB.h
|  |-IPublicC.h
|  |-IPublicD.h
|-src
   |-main.cpp
https://github.com/ElDesalmado/cmake-scanner.git
UPDATE
Strings' comparison by length yields different results, so I thought maybe there are some trailing characters in the output of execute_process.
So I replaced all the newlines that actually might prevent cmake from finding source files.
string(REGEX REPLACE "\n$" "" ...)
So they compare equal, however still could not be located by cmake.
I had some luck with using OUTPUT_STRIP_TRAILING_WHITESPACE in execute_command and main.cpp has been finally located and project generated. But when there are 2 or more sources this doesn't help.
I m going to try outputting sources' names in a single line and see what would occur...
I have solved the issue.
Cmake accepts lists of sources that must be formatted in a way, that sources' paths are separated with a semicolon. So the solution was to modifiy batch script to output a string line of semicolon-separated file names. Later I will update the repo and provide the batch code.
