Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a list of prefix paths to ExternalProject_Add in CMAKE_ARGS

Tags:

cmake

I have a CMake project that I want to build with the ExternalProject_Add command. In the CMAKE_ARGS parameter, I want to pass a list of prefix paths which contain CMake packages that are needed by the external project.

set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} 
   ${CMAKE_SOURCE_DIR}/MyProject/cmake_packages
   ${CMAKE_SOURCE_DIR}/OtherProjects/cmake_packages)

ExternalProject_Add(MyProject
   DOWNLOAD_COMMAND ""
   SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/source
   BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/MyProjectBuild
   INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/MyProjectInstall
   CMAKE_ARGS 
              -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/MyProjectInstall
              -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
   )

Unfortunately, this won't work, as the resulting file MyProject-configure-Debug.cmake in the build directory contains something like this (simplyfied):

set(command "C:/Path/to/cmake.exe;-DCMAKE_PREFIX_PATH=D:/path/to/MyProject/cmake_packages;D:/path/to/OtherProjects/cmake_packages;-GCodeBlocks - Ninja;D:/path/to/my/source/dir")
execute_process(
  COMMAND ${command}
  RESULT_VARIABLE result
  OUTPUT_FILE "D:/.../MyProject-configure-out.log"
  ERROR_FILE "D:/.../MyProject-configure-err.log"
  )

As there will be a variable named command that contains a list which is passed to execute_process, only the first path of the CMAKE_PREFIX_PATH is passed to the externals CMake call as CMAKE_PREFIX_PATH. The other parameters are passed as commandline parameters to CMake.

I've found two solutions:

  1. This answer mentioned a solution with creating a new .cmake file that will be included by the external project.
  2. Also it would be possible to pass something like -DCMAKE_EXTRA_PREFIX_PATH to the CMAKE_ARGS parameter.

Both solutions require the external CMakeLists.txt project file to be modified either by including an extra .cmake file or by appending an extra path to CMAKE_PREFIX_PATH. But this is no option, as I want to leaf the external project untouched.

Is it possible to handle this without any additional .cmake file or extra variables?

Maybe I'm just missing some "quoting-magic" that has to be done?

like image 590
tomvodi Avatar asked Jul 31 '17 11:07

tomvodi


1 Answers

After some more searching I've found on this page that the LIST_SEPARATOR parameter of ExternalProject_Add does the trick. Unfortunately the documentation about the use of this parameter isn't very meaningful.

Here is the solution for my problem:

set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} 
   ${CMAKE_SOURCE_DIR}/MyProject/cmake_packages
   ${CMAKE_SOURCE_DIR}/OtherProjects/cmake_packages)

# Create a list with an alternate separator e.g. pipe symbol
string(REPLACE ";" "|" CMAKE_PREFIX_PATH_ALT_SEP "${CMAKE_PREFIX_PATH}")

ExternalProject_Add(MyProject
   DOWNLOAD_COMMAND ""
   SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/source
   BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/MyProjectBuild
   INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/MyProjectInstall
   LIST_SEPARATOR | # Use the alternate list separator
   CMAKE_ARGS 
              -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/MyProjectInstall
              -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_ALT_SEP}
   )
like image 79
tomvodi Avatar answered Nov 05 '22 16:11

tomvodi