# find\_program without knowing specific directory structure

**URL:** <https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907>\
**Category:** Code\
**Created:** [September 8, 2023, 1:18pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907 "2023-09-08T13:18:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![fry](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fry/32/613_2.png) [@fry](https://discourse.cmake.org/u/fry)\
**Post date:** [September 8, 2023, 1:18pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/1 "2023-09-08T13:18:10Z")

</div>

I need to find an executable in an SDK where the structure can vary (including the names of intermediary folders). I just know that the executable will be under some root folder, but I don’t know at which level exactly. In a unix shell, I could just invoke:

```sh
cd <path_to_sdk>/root_folder/
find . -name "<program_name>"

```

The problem I am encountering is that `find_program` does not seem to work that way

```cmake
  find_program(
      RE_2D_RENDER_EXECUTABLE RE2DRender
      PATHS "${ARG_RE_2D_RENDER_ROOT}"
      NO_DEFAULT_PATH
  )

```

will not find the program unless `ARG_RE_2D_RENDER_ROOT` is the exact folder in which `RE2DRender` is actually located. I know that I can provide multiple paths to `find_program` but my issue is that I just don’t know the names of those paths, I only know the top one

Or in other words, it doesn’t seem to check in all folder recursively down.

Is there another flavor of `find_program` that would behave like unix `find`?

---

<div class="post-metadata">

**Author:** ![scivision](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a87d85/32.png) [@scivision](https://discourse.cmake.org/u/scivision)\
**Post date:** [September 8, 2023, 5:52pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/2 "2023-09-08T17:52:53Z")

</div>

I solve this kind of issue in my “FindOctave.cmake”, where GNU Octave install folder has the version number in it. I use `find(GLOB)` then `find_program()` [https://github.com/scivision/octave-cmake-mex/blob/main/cmake/FindOctave.cmake#L66](https://github.com/scivision/octave-cmake-mex/blob/main/cmake/FindOctave.cmake#L66)

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [September 8, 2023, 9:13pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/3 "2023-09-08T21:13:43Z")

</div>

> [@fry](#):
>
> Or in other words, it doesn’t seem to check in all folder recursively down.

Correct, `find_program()` doesn’t search recursively. That could be arbitrarily expensive. Instead, it searches well-defined sets of locations, suffixes and subdirectories, as described in the `find_program()` docs. If you need to recurse to arbitrary directory levels, you would have to implement that yourself with your own logic.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [September 13, 2023, 2:38am UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/4 "2023-09-13T02:38:46Z")

</div>

> [@scivision](#):
>
> I solve this kind of issue in my “FindOctave.cmake”, where GNU Octave install folder has the version number in it.

This is typically handled by something like (I’m making up versions since I don’t interact with Octave):

```cmake
set(FindOctave_VERSIONS
  ${Octave_EXTRA_VERSIONS} # forward compat that users can use
  11.0 10.0 9.1 9.0)
set(paths)
foreach (version IN LISTS FindOctave_VERSIONS)
  list(APPEND paths foo-${version} foo/${version})
endforeach ()
# use ${paths} in `find_*` calls.

```

There should really just be some finite set of possible subpaths to search; in that case `PATH_SUFFIXES` is probably the way to go here.

---

<div class="post-metadata">

**Author:** ![scivision](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a87d85/32.png) [@scivision](https://discourse.cmake.org/u/scivision)\
**Post date:** [September 13, 2023, 5:48pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/5 "2023-09-13T17:48:48Z")

</div>

yes I agree, instead of `file(GLOB)` which may not have a stopping condition, a finite list should be searched.

In my FindOctave.cmake, because I don’t use it that much and didn’t want to have to maintain it frequently, I did leave a single `file(GLOB)` just for Windows, though it could have no stopping condition, I feel that would be a rare case for a script I don’t want to maintain that much.

---

<div class="post-metadata">

**Author:** ![fry](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fry/32/613_2.png) [@fry](https://discourse.cmake.org/u/fry)\
**Post date:** [September 15, 2023, 2:33pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/6 "2023-09-15T14:33:03Z")

</div>

> [@craig.scott](#):
>
> Correct, `find_program()` doesn’t search recursively. That could be arbitrarily expensive. Instead, it searches well-defined sets of locations, suffixes and subdirectories, as described in the `find_program()` docs. If you need to recurse to arbitrary directory levels, you would have to implement that yourself with your own logic.

I wasn’t suggesting changing the default behavior of `find_program`. That being said adding a `RECURSE` option to `find_program`, that would then search recursively, would help in not having to reimplement the wheel every time this feature is required.

For the record, I ended up implementing it (note that I am not passing all `find_param` args because I don’t use them, so this implementation is somewhat simplified). It is not easy code to write, so that is why I think it would benefit CMake to have it built-in (optional of course…)

> <https://github.com/pongasoft/re-cmake/blob/81a4962f7f46e616f75cdb088d12a5092a389d5f/sdk.cmake#L67>

Note that since `find_program` sets a CACHE variable, then it is only “expensive” the first time it runs…

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [September 15, 2023, 3:39pm UTC](https://discourse.cmake.org/t/find-program-without-knowing-specific-directory-structure/8907/7 "2023-09-15T15:39:57Z")

</div>

> [@fry](#):
>
> Note that since `find_program` sets a CACHE variable, then it is only “expensive” the first time it runs…

IIRC, it’s only expensive after the first time it _succeeds_.
