How to pass CMAKE_OSX_ARCHITECTURES to ExternalProject_Add

I am trying to compile a fat binary with ExternalProject_Add. In order to do so, I need to pass x86_64;arm64 in the CMAKE_OSX_ARCHITECTURES variable to ExternalProject_Add. However, my attempts at it do not work:

include( ExternalProject )

message( "ARCHS=" ${CMAKE_OSX_ARCHITECTURES} )

ExternalProject_Add(
  ZLIB
#  URL "https://zlib.net/zlib-1.2.11.tar.gz"  # not compatible with Linux-3.3
  URL "https://zlib.net/fossils/zlib-1.2.8.tar.gz"
  CMAKE_ARGS
  -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}
  -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
  -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
  -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
  -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
  -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
  )

I would assume this has to do with the semi-colon inside CMAKE_OSX_ARCHITECTURES, which needs escaping so that it makes its way into the invocation of ExternalProject_Add, instead of being used to separate its arguments. So I’d write it like this:

ExternalProject_Add(
# ... as before, but:
  "-DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}"
  )
1 Like

ExternalProject_Add has a mechanism for passing semicolons through. You can do:

set(semicolon_smuggle "-+-")
string(REPLACE ";" "${semicolon_smuggle}" cmake_osx_archs_epa "${CMAKE_OSX_ARCHITECTURES}")
ExternalProject_Add(LIST_SEPARATOR "${semicolon_smuggle}" …)

Based on the idea of @ben.boeckel but requiring less tweaking:

string(REPLACE ";" "$<SEMICOLON>" CMAKE_OSX_ARCHITECTURES_ "${CMAKE_OSX_ARCHITECTURES}")

Oh, that is indeed better. I’ll note that in the ExternalProject-using project, the command is extracted and written to a CMake script so that we can also apply environment settings to it, so the smuggling is still required there.