Search code examples
c++macoscmakeapple-m1

Convert CMake for compiling Apple ARM CPU


We inherited an old source code that compiles well for macOS with Intel CPU. However, it doesn't seem to indicate the architecture in the compiler flags.

What are the required changes for generating a binary compatible with Apple ARM CPU (M1/M2), by using the same Intel-based machine?

Here is the simplified CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(MyLib)

set (CMAKE_CXX_STANDARD 17)

# Define specific Debug settings.
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")

# Define specific Release settings.
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D NDEBUG -O3")

# Define clang C++ defines for both Debug and Release
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra")

# Define specific Debug settings.
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")

# Define specific Release settings.
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D NDEBUG -O3")

INCLUDE_REGULAR_EXPRESSION("^.*$")

# Defines the source code for the library
option (BUILD_TESTING "Build tests" ON)

SET(CROSSPLATFORM_SRCS
  ${CMAKE_CURRENT_SOURCE_DIR}/../../file1.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/../../file2.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/../../file3.cpp
)

add_library(MyLib-macOS SHARED ${CROSSPLATFORM_SRCS})

#Setting properties for shared o dynamic library 
set_target_properties(MyLib-macOS
  PROPERTIES
  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
  PREFIX ""
)


Solution

  • Don't mess with flags directly.

    The variable controlling the target for macOS is CMAKE_OSX_ARCHITECTURES. It initializes the OSX_ARCHITECTURES target property. Just set it to arm64 to compile for ARM.

    There are a number of ways to do this. Here are a few, in my personal order of preference:

    1. Set it at the command line via the -D flag.
    2. Put it in a preset.
    3. Put it in a toolchain file.
    4. Set the target property directly on a target(s) that needs it via set_property or set_target_properties
    5. Set it as a cache variable in your project.
    6. Set it as a normal variable in your project (only appropriate if all targets in the project must build for ARM).

    For (4), here's an easy snippet to copy/paste.

    set_target_properties(MyLib-macOS
      PROPERTIES
      OSX_ARCHITECTURES "arm64"
      LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
      RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
      PREFIX ""
    )
    

    For (5), here's an easy snippet to copy/paste. Put it after project(), before you create any targets.

    set(CMAKE_OSX_ARCHITECTURES "arm64"
        CACHE STRING "The list of target architectures to build")