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"
Related
I'm trying to find a problem why cmake is not able to find a custom openssl version, therefore I debugged the original findOpenssl.cmake.
There they search for the ssl.h file. So, I created a small cmake file which tries to find out the issue:
project(CMAKETEST)
cmake_minimum_required(VERSION 3.16)
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl/ssl.h")
message(STATUS CUSTOMOPENSSLPATH: ${OPENSSL_CUSTOM_PATH})
find_path(TEST123
NAMES ${OPENSSL_CUSTOM_PATH}
)
message(STATUS ${TEST123})
I created an empty ssl.h file in the above folder, but cmake is not able to find the file. TEST123 is always NOT-FOUND.
Solution:
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl")
find_path(TEST123 NAMES ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
Update
This more concrete example does not work as expected:
project(CMAKETEST)
cmake_minimum_required(VERSION 3.16)
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/")
find_path(TEST123
NAMES openssl/ssl.h HINTS "${OPENSSL_CUSTOM_PATH}"
PATH_SUFFIX include
NO_DEFAULT_PATH
)
message(STATUS ${TEST123})
when removing NO_DEFAULT_PATH then it finds the system openssl library in /usr/include
Update 2
https://github.com/Kitware/CMake/blob/master/Modules/FindOpenSSL.cmake#L195-L204
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_INCLUDEDIR}
${_OPENSSL_INCLUDE_DIRS}
PATH_SUFFIXES
include
)
finds first the path in /usr/include, if I add NO_DEFAULT_PATH it finds it. Probably it was because some caching that it was not found during I wrote this question.
It isn't working because you use it incorrectly, for your case it should be like this:
set(OPENSSL_CUSTOM_PATH "/home/user/Documents/CMakeTest/openssl/include/openssl")
find_path(TEST123 NAMES ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
Or simply find_path(TEST123 ssl.h PATHS "${OPENSSL_CUSTOM_PATH}")
In your update you have a error PATH_SUFFIX should be PATH_SUFFIXES.
In my project, I have a subdir named foo, and I want a list of all .cpp files under foo, and its subdirectories. So - it's GLOB_RECURSE for me. Now, looking at the CMake documentation, I see the syntax is:
file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
[LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
[<globbing-expressions>...])
and in my case:
file(GLOB_RECURSE my_list "foo/" "*.cpp")
Unfortunately, what I'm getting is the paths of all .cpp files in my project - not just in foo/. Why is that?
You have misunderstood the role of the <path> placeholder in the syntax. It is only relevant when using the RELATIVE keyword - and you aren't using RELATIVE.
Thus, what you've actually provided GLOB_RECURSE is two globbing expressions.
Strangely enough, each globbing expression is considered to contain both the root directory for recursion and the globbing pattern at the same time. In your case this would be:
file(GLOB_RECURSE my_list "foo/*.cpp")
CMake will split that string up, so that it looks for .cpp files in all subdirectories of foo/.
First, I am sorry if the question has been answered but I couldn't find any solution.
I am trying to compile a simple program with cmake. But I can't seem to include absolute paths.
My project (located in C:/path/to/my/project for the understanding) is simple with an include directory with header files. However, I must include another directory completely somewhere else.
My include_directories looks like this:
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "C:/path/to/my/other/directory/include")
However when I do :
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
To check my include directories I have the following answer:
-- dir='/c/path/to/my/project/include'
-- dir='/c/path/to/my/project/C:/path/to/my/other/directory/include'
So cmake interprets the paths as relative to my project folder.
How can I force cmake to interpret them as absolute ?
I am using cmake v3.17.3.
EDIT
I have tried doing so but it doesn't seem to work either since the path is not appended to the INCLUDE_DIRECTORIES property of my target.
add_executable(app src1.c src2.c)
target_include_directories(app BEFORE PRIVATE "C:/path/to/my/other/directory/include")
Thank you by advance.
So after some research the answer is :
add_executable(app src1.c src2.c)
target_include_directories(app BEFORE PRIVATE "/C/path/to/my/other/directory/include")
The path I was referring to was wrong since I am on msys. Therefore c:/ should become /c/.
You can also write the path as:
add_executable(app src1.c src2.c)
target_include_directories(app BEFORE PRIVATE "C:\\path\\to\\my\\other\\directory\\include")
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.
I've just read this:
CMake - Automatically add all files in a folder to a target?
With the answer suggesting a file glob, e.g.:
file(GLOB "*.h" "*.cpp")
now, what if I want my target to depend on all files of a certain type under a certain folder - which might be within multiple subfolders? I tried using
execute_process(COMMAND find src/baz/ -name "*.cpp" OUTPUT_VARIABLE BAR)
and then
add_executable(foo ${BAR}
but this gives me the error:
Cannot find source file:
src/baz/some/file/here
src/baz/some/other_file/here
src/baz/some/other_file/here2
(yes, with that spacing.)
What am I doing wrong here?
Turning my comment into an answer
If you want to add recursive searching for files use file(GLOB_RECURSE ...)
file(GLOB_RECURSE source_list "*.cpp" "*.hpp")
Your second example would translate into
file(GLOB_RECURSE BAR "src/baz/*.cpp")
References
file(...)
Is it better to specify source files with GLOB or each file individually in CMake?