Append variable to <BUILD_DIR> in ExternalProject_Add command

I have an ExternalProject_Add call that looks like this…

ExternalProject_Add(
    SDL2 
    URL https://www.libsdl.org/release/SDL2-2.0.12.tar.gz
    URL_HASH MD5=783b6f2df8ff02b19bb5ce492b99c8ff
    INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}
    BINARY_DIR <BINARY_DIR>/${CMAKE_BUILD_TYPE}
    CMAKE_ARGS -D CMAKE_INSTALL_PREFIX=<INSTALL_DIR>
               -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})

The problem line is BINARY_DIR <BINARY_DIR>/${CMAKE_BUILD_TYPE} - This does not seem to expand to what I’d expect. Essentially all I’d like to do is add either Debug or Release to the default <BINARY_DIR> path (which in this case is SDL2-prefix/src/SDL2-build).

Is there a way to do this? I would really like for this to work and to not have to manually replicate the path with ${CMAKE_CURRENT_BINARY_DIR}/SDL2-prefix/src/SDL2-build/${CMAKE_BUILD_TYPE} hardcoded.

Any pointers on how to achieve this or a better idiomatic way for building both Debug and Release configurations using ExternalProject_Add please do let me know! :slight_smile:

Thank you very much for your time,

Tom

I think we’d need something like <DEFAULT_BINARY_DIR> for such use cases.

Thanks for getting back to me Ben,

I see, and I take it that currently doesn’t exist? It seems like it would be really useful in certain contexts and follow a similar pattern to other CMake variables.

I might also just be taking the wrong approach and there’s a better way to build multiple configurations using ExternalProject_Add.

The reason I was trying to do it this way instead of creating a separate build folder would be the library would need to be downloaded twice which seemed redundant/wasteful and if I don’t make a separate configuration folder, then if you build Debug, then Release and then Debug again, the Debug build will start over again which is sometimes a pain as it’ll have been stomped by Release.

I can just fallback to a custom override like ${CURRENT_CMAKE_BINARY_DIR}/SDL2/Debug, but reusing <BINARY_DIR> felt cleaner.

Thanks!

Tom

I’ve been experimenting with getting a reliable cross-platform ExternalProject_Add command to work and have now got something that looks like this…

ExternalProject_Add(
    SDL2
    URL https://www.libsdl.org/release/SDL2-2.0.12.tar.gz
    URL_HASH MD5=783b6f2df8ff02b19bb5ce492b99c8ff
    CMAKE_GENERATOR Ninja
    BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/SDL2/build/${CMAKE_BUILD_TYPE}
    INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}
    CMAKE_ARGS -D CMAKE_INSTALL_PREFIX=<INSTALL_DIR>
               -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})

The reason for setting the CMAKE_GENERATOR explicitly to Ninja is so I can get consistent behaviour across Windows and macOS (the differences between single and multi-config generators I’ve found complicated things…).

It does feel like there should be an easier way to do this though, ideally all I would like to write is this:

ExternalProject_Add(
    SDL2
    URL https://www.libsdl.org/release/SDL2-2.0.12.tar.gz
    URL_HASH MD5=783b6f2df8ff02b19bb5ce492b99c8ff
    INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}
    CMAKE_ARGS -D CMAKE_INSTALL_PREFIX=<INSTALL_DIR>)

And then externally build both Debug and Release and ideally have the build artefacts wind up in separate folders. It feels like this must be a common pattern, I just feel like I must be missing something.

Any suggestions on how to improve this solution would be greatly appreciated,

Thanks!

Tom