Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CMakeToolchain] Adding Xcode flags #10985

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion conan/tools/apple/apple.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

from conans.util.runners import check_output_runner

Expand Down
61 changes: 58 additions & 3 deletions conan/tools/cmake/toolchain/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,47 @@ class AppleSystemBlock(Block):
# Setting CMAKE_OSX_DEPLOYMENT_TARGET if "os.version" is defined by the used conan profile
set(CMAKE_OSX_DEPLOYMENT_TARGET "{{ cmake_osx_deployment_target }}" CACHE STRING "")
{% endif %}
set(BITCODE "")
lasote marked this conversation as resolved.
Show resolved Hide resolved
set(FOBJC_ARC "")
set(VISIBILITY "")
{% if enable_bitcode %}
# Bitcode ON
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode")
{% if enable_bitcode_marker %}
set(BITCODE "-fembed-bitcode-marker")
{% else %}
set(BITCODE "-fembed-bitcode")
{% endif %}
{% elif enable_bitcode is not none %}
# Bitcode OFF
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
{% endif %}
{% if enable_arc %}
# ARC ON
set(FOBJC_ARC "-fobjc-arc")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES")
{% elif enable_arc is not none %}
# ARC OFF
set(FOBJC_ARC "-fno-objc-arc")
franramirez688 marked this conversation as resolved.
Show resolved Hide resolved
set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO")
{% endif %}
{% if enable_visibility %}
# Visibility ON
set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO")
set(VISIBILITY "-fvisibility=default")
{% elif enable_visibility is not none %}
# Visibility OFF
set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden")
set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES")
{% endif %}
#Check if Xcode generator is used, since that will handle these flags automagically
if(CMAKE_GENERATOR MATCHES "Xcode")
message(DEBUG "Not setting any manual command-line buildflags, since Xcode is selected as generator.")
else()
string(APPEND CONAN_C_FLAGS " ${BITCODE} ${FOBJC_ARC}")
string(APPEND CONAN_CXX_FLAGS " ${BITCODE} ${VISIBILITY} ${FOBJC_ARC}")
endif()
""")

def _apple_sdk_name(self):
Expand Down Expand Up @@ -357,15 +398,28 @@ def _apple_sdk_name(self):

def context(self):
os_ = self._conanfile.settings.get_safe("os")
if os_ not in ['Macos', 'iOS', 'watchOS', 'tvOS']:
if not is_apple_os(os_):
return None

arch = self._conanfile.settings.get_safe("arch")
host_architecture = to_apple_arch(arch)
host_os_version = self._conanfile.settings.get_safe("os.version")
host_sdk_name = self._apple_sdk_name()
is_debug = self._conanfile.settings.get_safe('build_type') == "Debug"

# Reading some configurations to enable or disable some Xcode toolchain flags and variables
# Issue related: https://github.com/conan-io/conan/issues/9448
# Based on https://github.com/leetal/ios-cmake repository
enable_bitcode = self._conanfile.conf.get("tools.apple:enable_bitcode", check_type=bool)
enable_arc = self._conanfile.conf.get("tools.apple:enable_arc", check_type=bool)
enable_visibility = self._conanfile.conf.get("tools.apple:enable_visibility", check_type=bool)

ctxt_toolchain = {}
ctxt_toolchain = {
"enable_bitcode": enable_bitcode,
"enable_bitcode_marker": all([enable_bitcode, is_debug]),
"enable_arc": enable_arc,
"enable_visibility": enable_visibility
}
if host_sdk_name:
ctxt_toolchain["cmake_osx_sysroot"] = host_sdk_name
# this is used to initialize the OSX_ARCHITECTURES property on each target as it is created
Expand Down Expand Up @@ -723,7 +777,8 @@ def _is_apple_cross_building(self):
os_host = self._conanfile.settings.get_safe("os")
arch_host = self._conanfile.settings.get_safe("arch")
arch_build = self._conanfile.settings_build.get_safe("arch")
return os_host in ('iOS', 'watchOS', 'tvOS') or (os_host == 'Macos' and arch_host != arch_build)
return os_host in ('iOS', 'watchOS', 'tvOS') or (
os_host == 'Macos' and arch_host != arch_build)

def _get_cross_build(self):
user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain")
Expand Down
3 changes: 3 additions & 0 deletions conans/model/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"tools.system.package_manager:sudo": "Use 'sudo' when invoking the package manager tools in Linux (False by default)",
"tools.system.package_manager:sudo_askpass": "Use the '-A' argument if using sudo in Linux to invoke the system package manager (False by default)",
"tools.apple.xcodebuild:verbosity": "Verbosity level for xcodebuild: 'verbose' or 'quiet",
"tools.apple:enable_bitcode": "(boolean) Enable/Disable Bitcode Apple Clang flags",
"tools.apple:enable_arc": "(boolean) Enable/Disable ARC Apple Clang flags",
"tools.apple:enable_visibility": "(boolean) Enable/Disable Visibility Apple Clang flags",
# Flags configuration
"tools.build:cxxflags": "List of extra CXX flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain",
"tools.build:cflags": "List of extra C flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import textwrap
import platform
import os

import pytest

from conans.test.utils.tools import TestClient


def _add_message_status_flags(client):
cmakelists_path = os.path.join(client.current_folder, "CMakeLists.txt")
with open(cmakelists_path, "a") as cmakelists_file:
cmakelists_file.write('message(STATUS "CONAN_C_FLAGS: ${CONAN_C_FLAGS}")\n')
cmakelists_file.write('message(STATUS "CONAN_CXX_FLAGS: ${CONAN_CXX_FLAGS}")\n')


@pytest.mark.skipif(platform.system() != "Darwin", reason="Only OSX")
@pytest.mark.parametrize("op_system,os_version,sdk,arch", [
("watchOS", "8.1", "watchos", "armv7k"),
("tvOS", "13.2", "appletvos", "armv8")
])
def test_cmake_apple_bitcode_arc_and_visibility_flags_enabled(op_system, os_version, sdk, arch):
profile = textwrap.dedent("""
include(default)
[settings]
os={}
os.version={}
os.sdk={}
arch={}
[conf]
tools.apple:enable_bitcode=True
tools.apple:enable_arc=True
tools.apple:enable_visibility=True
""".format(op_system, os_version, sdk, arch))

client = TestClient(path_with_spaces=False)
client.save({"host": profile}, clean_first=True)
client.run("new hello/0.1 --template=cmake_lib")
_add_message_status_flags(client)
client.run("install . --profile:build=default --profile:host=host")
toolchain = client.load(os.path.join("cmake-build-release", "conan", "conan_toolchain.cmake"))
# bitcode
assert 'set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")' in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode")' in toolchain
assert 'set(BITCODE "-fembed-bitcode")' in toolchain
# arc
assert 'set(FOBJC_ARC "-fobjc-arc")' in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES")' in toolchain
# visibility
assert 'set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO")' in toolchain
assert 'set(VISIBILITY "-fvisibility=default")' in toolchain

client.run("create . --profile:build=default --profile:host=host -tf None")
# flags
assert "-- CONAN_C_FLAGS: -fembed-bitcode -fobjc-arc" in client.out
assert "-- CONAN_CXX_FLAGS: -fembed-bitcode -fvisibility=default -fobjc-arc" in client.out
assert "[100%] Built target hello" in client.out


@pytest.mark.skipif(platform.system() != "Darwin", reason="Only OSX")
@pytest.mark.parametrize("op_system,os_version,sdk,arch", [
("watchOS", "8.1", "watchos", "armv7k"),
("tvOS", "13.2", "appletvos", "armv8")
])
def test_cmake_apple_bitcode_arc_and_visibility_flags_enabled_and_xcode_generator(op_system, os_version, sdk, arch):
"""
Testing when all the Bitcode, ARC and Visibility are enabled, and Xcode as generator.

Note: When using CMake and Xcode as generator, the C/CXX flags do not need to be appended.
"""
profile = textwrap.dedent("""
include(default)
[settings]
os={}
os.version={}
os.sdk={}
arch={}
[conf]
tools.apple:enable_bitcode=True
tools.apple:enable_arc=True
tools.apple:enable_visibility=True
""".format(op_system, os_version, sdk, arch))

client = TestClient(path_with_spaces=False)
client.save({"host": profile}, clean_first=True)
client.run("new hello/0.1 --template=cmake_lib")
_add_message_status_flags(client)
client.run("create . --profile:build=default --profile:host=host -tf None "
"-c tools.cmake.cmaketoolchain:generator=Xcode")
assert "** BUILD SUCCEEDED **" in client.out
# flags are not appended when Xcode generator is used
for line in str(client.out).splitlines():
if "CONAN_C_FLAGS:" in line:
assert "-- CONAN_C_FLAGS:" == line.strip()
if "CONAN_CXX_FLAGS:" in line:
assert "-- CONAN_CXX_FLAGS: -stdlib=libc++" == line.strip()
break


@pytest.mark.skipif(platform.system() != "Darwin", reason="Only OSX")
@pytest.mark.parametrize("op_system,os_version,sdk,arch", [
("watchOS", "8.1", "watchos", "armv7k"),
("tvOS", "13.2", "appletvos", "armv8")
])
def test_cmake_apple_bitcode_arc_and_visibility_flags_disabled(op_system, os_version, sdk, arch):
profile = textwrap.dedent("""
include(default)
[settings]
os={}
os.version={}
os.sdk={}
arch={}
[conf]
tools.apple:enable_bitcode=False
tools.apple:enable_arc=False
tools.apple:enable_visibility=False
""".format(op_system, os_version, sdk, arch))

client = TestClient(path_with_spaces=False)
client.save({"host": profile}, clean_first=True)
client.run("new hello/0.1 --template=cmake_lib")
_add_message_status_flags(client)
client.run("install . --profile:build=default --profile:host=host")
toolchain = client.load(os.path.join("cmake-build-release", "conan", "conan_toolchain.cmake"))
# bitcode
assert 'set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")' in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode")' not in toolchain
assert 'set(BITCODE "-fembed-bitcode")' not in toolchain
# arc
assert 'set(FOBJC_ARC "-fno-objc-arc")' in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO")' in toolchain
# visibility
assert 'set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES")' in toolchain
assert 'set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden")' in toolchain

client.run("create . --profile:build=default --profile:host=host -tf None")
# flags
assert "-- CONAN_C_FLAGS: -fno-objc-arc" in client.out
assert "-- CONAN_CXX_FLAGS: -fvisibility=hidden -fvisibility-inlines-hidden -fno-objc-arc" in client.out
assert "[100%] Built target hello" in client.out


@pytest.mark.skipif(platform.system() != "Darwin", reason="Only OSX")
@pytest.mark.parametrize("op_system,os_version,sdk,arch", [
("watchOS", "8.1", "watchos", "armv7k"),
("tvOS", "13.2", "appletvos", "armv8")
])
def test_cmake_apple_bitcode_arc_and_visibility_flags_are_none(op_system, os_version, sdk, arch):
"""
Testing what happens when any of the Bitcode, ARC or Visibility configurations are not defined.
"""
profile = textwrap.dedent("""
include(default)
[settings]
os={}
os.version={}
os.sdk={}
arch={}
""".format(op_system, os_version, sdk, arch))

client = TestClient(path_with_spaces=False)
client.save({"host": profile}, clean_first=True)
client.run("new hello/0.1 --template=cmake_lib")
_add_message_status_flags(client)
client.run("install . --profile:build=default --profile:host=host")
toolchain = client.load(os.path.join("cmake-build-release", "conan", "conan_toolchain.cmake"))
# bitcode
assert 'set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")' not in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode")' not in toolchain
assert 'set(BITCODE "-fembed-bitcode")' not in toolchain
# arc
assert 'set(FOBJC_ARC "-' not in toolchain
assert 'set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC' not in toolchain
# visibility
assert 'set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN' not in toolchain
assert 'set(VISIBILITY "-' not in toolchain

client.run("create . --profile:build=default --profile:host=host -tf None")
# flags are not appended
for flag in ["-fembed-bitcode", "-fno-objc-arc", "-fobjc-arc", "-fvisibility"]:
assert flag not in client.out
assert "[100%] Built target hello" in client.out