Changing target output path based on architecture

Sometimes, I might need to modify the output directory based on whether my build is 32-bit or 64-bit . Currently, this is what I have in place:

# Decide where to put the target based on the architecture (32/64 bit)

if(CMAKE_SIZEOF_VOID_P EQUAL 8) # If it is 64-bit...

	set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../build/bin/${CMAKE_SYSTEM_NAME}/64-bit/")

endif()

if(CMAKE_SIZEOF_VOID_P EQUAL 4) # If it is 32-bit...

	set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../build/bin/${CMAKE_SYSTEM_NAME}/32-bit/")

endif()

I then use this path for the targets using the following approach:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY}/exe/$<CONFIG>")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY}/lib_dynamic/$<CONFIG>")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY}/lib_static/$<CONFIG>")

For the time being, this approach works just fine. Nonetheless, I’m curious if there is a better method to approach the problem since not every system out there would necessarily be 32 or 64 bit. In addition, as I am not experienced with CMake, there might be more problems to this method that I may not be able to spot at the current time.

You may want to include ${CMAKE_ARCHITECTURE} in there as there are other processors out there. Note that this does not work for universal binaries on macOS where one artifact has code for multiple architectures. Also note that CMAKE_SIZEOF_VOID_P is now consistent for universal builds, but was not when 32 and 64 bit Intel architectures co-existed in them.

1 Like

I must admit that I am feeling a little confused. Does the code provided below align with your intended meaning?


# Replacing the hardcoded architecture (32-bit/64-bit) with "${CMAKE_ARCHITECTURE}".

set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../build/bin/${CMAKE_SYSTEM_NAME}/${CMAKE_ARCHITECTURE}/")

If that’s the case, considering that ${CMAKE_ARCHITECTURE} may lead to inaccuracies under macOS, what would be the solution for that platform?

That would help if you want to overlay things with different architectures, yes. For macOS with universal binaries, I’d just use the “architecture” universal2.