1

What I'm doing I'm writing a CMakeLists.txt to build a C++ project that will need to use R.

what is my problem Usually, when I would like to find a package/program, I would use find_package/program function. But this only finds the first one in the path. What if I want to find all the executables with the same name?

For example, if somebody has multiple versions of R installed on the computer, can I find them all and return a list? An alternative can be that is there a way to detect if there are multiple R executables installed?

Thank you!

Weiming Hu
  • 193
  • 1
  • 1
  • 11
  • 1
    @BenBolker From the [tag:cmake] tag and the commands shown it seems this is about a cross-platform way of finding all programs with the same name in CMake. – Florian Jun 25 '17 at 20:11
  • The question is pretty clear, voted for reopen. – Tsyvarev Jun 26 '17 at 09:17
  • @Tsyvarev How do I close this question? I already have the answer. Thank you. – Weiming Hu Jun 27 '17 at 14:16
  • @WeimingHu: Questions are *closed* only when they have **inappropriate content** for the site, see [help pages](https://stackoverflow.com/help/closed-questions) for more info. As for your question, simply having an answer doesn't imply that it should be closed. They said, Stack Overflow is **Question/Answer** (Q/A) site, that is having answered questions is the main purpose of it. If you find an answer fitting for your purpose, you may mark it as [accepted](https://stackoverflow.com/help/accepted-answer). – Tsyvarev Jun 27 '17 at 14:48
  • @Tsyvarev Thank you! – Weiming Hu Jun 27 '17 at 16:41

2 Answers2

3

As @Tsyvarev has answered there is not build-in way in , but you can always do this within a loop.

So here is my cross-platform version of the missing find_program_all() CMake function:

CMakeLists.txt

cmake_minimum_required(VERSION 3.3)

project(TestFindProgramAll NONE)

function(find_program_all _var)
    if (NOT DEFINED ${_var})
        while(1)
            unset(_found CACHE)
            find_program(_found ${ARGN})
            if (_found AND NOT _found IN_LIST ${_var})
                set(${_var} "${${_var}};${_found}" CACHE FILEPATH "Path to a program." FORCE)
                # ignore with the next try
                get_filename_component(_dir "${_found}" DIRECTORY)
                list(APPEND CMAKE_IGNORE_PATH "${_dir}")
            else()
                unset(_found CACHE)
                break()
            endif()
        endwhile()
    endif()
endfunction()

find_program_all(_gcc "gcc")
message(STATUS "_gcc = ${_gcc}")

It mimics the find_program() behavior and caches the result.

Tested it with my multiple gcc installations.

References

Florian
  • 39,996
  • 9
  • 133
  • 149
1

CMake has no ready-to-use functionality to return list of matched programs.

You may iterate over search paths manually, or use other utilities, like which -a suggested by @BenBolker in the comments.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153