0

Is there a modern approach to use target architecture within a condition for a generator expression in CMake? There are some answers that are somewhat outdated. I am looking for a modern or at least very robust and reliable custom script for using target architecture within a generator expression. The docs do not seem to contain that kind of info.

One of the ideas for a workaround I see is to use $<<STRING:MY_DETECTED_ARCH:ARCH_ARM>:src_for_arm.cpp>

Sergey Kolesnik
  • 3,009
  • 1
  • 8
  • 28
  • 1
    I do not think I see a way for an architecture to change between generator configurations. Just use an old plain `if`. – KamilCuk Jul 26 '22 at 11:45
  • @KamilCuk generator expressions can be resolved for target properties such as include directories, sources, link libraries, preprocessor definictions, etc. They exist for convenience over using a standalone `if` block. For several and nested conditional expressions that would be a mess (i.e. Debug AND Platfrom). There are expressions to evaluete config type, platform, compiler ID, flags. options, etc. But there does not seem to be a property for target architecture. That is to write clean code to use one .cpp for arm builds and other for x86_64. Hence the question. – Sergey Kolesnik Jul 26 '22 at 12:48
  • 1
    `They exist for convenience over using a standalone if block` No, they exist to handle generators with multi-configurations. Because I don't think architecture can change between generator configurations, I don't see a reason why there should be a generator expression for architecture configuration. Aaand I think there isn't. – KamilCuk Jul 26 '22 at 12:51
  • @KamilCuk yet they can be used for single-config generators and work exactly like `if` blocks, but with less verbosity. Since you can evaluate expression based on things like compiler id I don't see why it wouldn't be reasonable to also use target architecture. Speaking of multiple-config generators, VS solution can target multiple architectures – Sergey Kolesnik Jul 26 '22 at 13:00

1 Answers1

0

I checked a solution from this answer and it worked.

cmake_minimum_required(VERSION 3.14.2 FATAL_ERROR)
project(cmake_target_arch)

set(CMAKE_CXX_STANDARD 17)
include(TargetArch.cmake)

target_architecture(TARGET_ARCH)
message(STATUS "target_architecture: ${TARGET_ARCH}")

add_executable(cmake_target_arch
        main.cpp
        $<$<STREQUAL:"${TARGET_ARCH}","x86_64">:x86_64.cpp>
        $<$<STREQUAL:"${TARGET_ARCH}","i386">:i386.cpp>
        $<$<STREQUAL:"${TARGET_ARCH}","armv7">:armv7.cpp>
        )

main.cpp

#include <iostream>

#include <string>

extern std::string hello_message();

int main()
{
    std::cout << hello_message() << std::endl;
    return 0;
}

i386.cpp


#include <string>

std::string hello_message()
{
    return "Hello i386!";
}

Example output for i386 binary:

C:\Users\serge\dev\repos\cmake_target_arch\cmake-build-release-visual-studio-win32\cmake_target_arch.exe
Hello i386!

I guess one can come up with a CMake Macro to wrap strings comparison

Sergey Kolesnik
  • 3,009
  • 1
  • 8
  • 28