def test_apple_meson_toolchain_cross_compiling(arch, os_, os_version, sdk): profile = textwrap.dedent(""" include(default) [settings] os = {os} os.version = {os_version} os.sdk = {os_sdk} arch = {arch} compiler = apple-clang compiler.version = 12.0 compiler.libcxx = libc++ [conf] tools.apple:sdk_path={sdk_path} """) xcrun = XCRun(None, sdk) sdk_path = xcrun.sdk_path hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", preprocessor=["STRING_DEFINITION"]) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) profile = profile.format(os=os_, os_version=os_version, os_sdk=sdk, arch=arch, sdk_path=sdk_path) t = TestClient() t.save({ "conanfile.py": _conanfile_py, "meson.build": _meson_build, "meson_options.txt": _meson_options_txt, "hello.h": hello_h, "hello.cpp": hello_cpp, "main.cpp": app, "profile_host": profile }) t.run("install . --profile:build=default --profile:host=profile_host") t.run("build .") libhello = os.path.join(t.current_folder, "build", "libhello.a") assert os.path.isfile(libhello) is True demo = os.path.join(t.current_folder, "build", "demo") assert os.path.isfile(demo) is True lipo = xcrun.find('lipo') t.run_command('"%s" -info "%s"' % (lipo, libhello)) assert "architecture: %s" % to_apple_arch(arch) in t.out t.run_command('"%s" -info "%s"' % (lipo, demo)) assert "architecture: %s" % to_apple_arch(arch) in t.out
def test_catalyst(self, arch): profile = textwrap.dedent(""" include(default) [settings] os = Macos os.version = 12.0 os.sdk = macosx os.subsystem = catalyst os.subsystem.ios_version = 13.1 arch = {arch} """).format(arch=arch) self.t = TestClient() hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello") main_cpp = textwrap.dedent(""" #include "hello.h" #include <TargetConditionals.h> #include <iostream> int main() { #if TARGET_OS_MACCATALYST std::cout << "running catalyst " << __IPHONE_OS_VERSION_MIN_REQUIRED << std::endl; #else #error "not building for Apple Catalyst" #endif } """) self.t.save({ "Makefile": self.makefile, "hello.h": hello_h, "hello.cpp": hello_cpp, "app.cpp": main_cpp, "conanfile.py": self.conanfile_py, "profile": profile }) self.t.run("install . --profile:host=profile") self.t.run("build .") libhello = os.path.join(self.t.current_folder, "libhello.a") app = os.path.join(self.t.current_folder, "app") self.assertTrue(os.path.isfile(libhello)) self.assertTrue(os.path.isfile(app)) expected_arch = to_apple_arch(arch) self.t.run_command('lipo -info "%s"' % libhello) self.assertIn("architecture: %s" % expected_arch, self.t.out) self.t.run_command('lipo -info "%s"' % app) self.assertIn("architecture: %s" % expected_arch, self.t.out) if arch == "x86_64": self.t.run_command('"%s"' % app) self.assertIn("running catalyst 130100", self.t.out)
def test_meson_toolchain(self, arch, os_, os_version, sdk): self.xcrun = XCRun(None, sdk) self.arch = arch self.os = os_ self.os_version = os_version hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello", preprocessor=["STRING_DEFINITION"]) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) self.t = TestClient() self.t.save({ "conanfile.py": self._conanfile_py, "meson.build": self._meson_build, "meson_options.txt": self._meson_options_txt, "hello.h": hello_h, "hello.cpp": hello_cpp, "main.cpp": app, "profile_host": self.profile() }) self.t.run( "install . --profile:build=default --profile:host=profile_host") self.t.run("build .") libhello = os.path.join(self.t.current_folder, "build", "libhello.a") self.assertTrue(os.path.isfile(libhello)) demo = os.path.join(self.t.current_folder, "build", "demo") self.assertTrue(os.path.isfile(demo)) lipo = self.xcrun.find('lipo') self.t.run_command('"%s" -info "%s"' % (lipo, libhello)) self.assertIn("architecture: %s" % to_apple_arch(self.arch), self.t.out) self.t.run_command('"%s" -info "%s"' % (lipo, demo)) self.assertIn("architecture: %s" % to_apple_arch(self.arch), self.t.out)
def env(self): cc = self.xcrun.cc cxx = self.xcrun.cxx cflags = apple_deployment_target_flag(self.os, self.os_version) cflags += " -isysroot " + self.xcrun.sdk_path cflags += " -arch " + to_apple_arch(self.arch) cxxflags = cflags return {'CC': cc, 'CXX': cxx, 'CFLAGS': cflags, 'CXXFLAGS': cxxflags}
def architecture_flag(settings): """ returns flags specific to the target architecture and compiler """ compiler = settings.get_safe("compiler") compiler_base = settings.get_safe("compiler.base") arch = settings.get_safe("arch") the_os = settings.get_safe("os") subsystem = settings.get_safe("os.subsystem") if not compiler or not arch: return "" if the_os == "Android": return "" if str(compiler) in ['gcc', 'apple-clang', 'clang', 'sun-cc']: if str(the_os) == 'Macos' and str(subsystem) == 'catalyst': # FIXME: This might be conflicting with Autotools --target cli arg apple_arch = to_apple_arch(arch) if apple_arch: return '--target=%s-apple-ios-macabi' % apple_arch elif str(arch) in ['x86_64', 'sparcv9', 's390x']: return '-m64' elif str(arch) in ['x86', 'sparc']: return '-m32' elif str(arch) in ['s390']: return '-m31' elif str(the_os) == 'AIX': if str(arch) in ['ppc32']: return '-maix32' elif str(arch) in ['ppc64']: return '-maix64' elif str(compiler) == "intel": # https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-m32-m64-qm32-qm64 if str(arch) == "x86": return "/Qm32" if str(compiler_base) == "Visual Studio" else "-m32" elif str(arch) == "x86_64": return "/Qm64" if str(compiler_base) == "Visual Studio" else "-m64" elif str(compiler) == "intel-cc": # https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-m32-m64-qm32-qm64 if str(arch) == "x86": return "/Qm32" if the_os == "Windows" else "-m32" elif str(arch) == "x86_64": return "/Qm64" if the_os == "Windows" else "-m64" elif str(compiler) == "mcst-lcc": return { "e2k-v2": "-march=elbrus-v2", "e2k-v3": "-march=elbrus-v3", "e2k-v4": "-march=elbrus-v4", "e2k-v5": "-march=elbrus-v5", "e2k-v6": "-march=elbrus-v6", "e2k-v7": "-march=elbrus-v7" }.get(str(arch), "") return ""
def env(self): cc = self.xcrun.cc cxx = self.xcrun.cxx deployment_flag = apple_deployment_target_flag(self.os, self.os_version) sysroot_flag = " -isysroot " + self.xcrun.sdk_path arch_flag = " -arch " + to_apple_arch(self.arch) flags = deployment_flag + sysroot_flag + arch_flag return { 'CC': cc, 'CXX': cxx, 'CFLAGS': flags, 'CXXFLAGS': flags, 'LDFLAGS': flags }
def test_makefile_arch(self, arch, os_, os_version): self.arch = arch self.os = os_ self.os_version = os_version profile = textwrap.dedent(""" include(default) [settings] os = {os} os.version = {os_version} arch = {arch} """).format(os=self.os, arch=self.arch, os_version=self.os_version) self.t = TestClient() hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello") main_cpp = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) self.t.save({ "Makefile": self.makefile, "hello.h": hello_h, "hello.cpp": hello_cpp, "main.cpp": main_cpp, "conanfile.py": self.conanfile_py, "profile": profile }) self.t.run("install . --profile:host=profile") self.t.run("build .") libhello = os.path.join(self.t.current_folder, "libhello.a") app = os.path.join(self.t.current_folder, "app") self.assertTrue(os.path.isfile(libhello)) self.assertTrue(os.path.isfile(app)) expected_arch = to_apple_arch(self.arch) self.t.run_command('lipo -info "%s"' % libhello) self.assertIn("architecture: %s" % expected_arch, self.t.out) self.t.run_command('lipo -info "%s"' % app) self.assertIn("architecture: %s" % expected_arch, self.t.out)
def test_makefile_arch(self, arch, os_, os_version): self.arch = arch self.os = os_ self.os_version = os_version makefile = textwrap.dedent(""" .PHONY: all all: libhello.a app app: main.o libhello.a $(CXX) $(CFLAGS) -o app main.o -lhello -L. libhello.a: hello.o $(AR) rcs libhello.a hello.o main.o: main.cpp $(CXX) $(CFLAGS) -c -o main.o main.cpp hello.o: hello.cpp $(CXX) $(CFLAGS) -c -o hello.o hello.cpp """) profile = textwrap.dedent(""" include(default) [settings] os = {os} os.version = {os_version} arch = {arch} """).format(os=self.os, arch=self.arch, os_version=self.os_version) conanfile_py = textwrap.dedent(""" from conans import ConanFile, tools, AutoToolsBuildEnvironment class App(ConanFile): settings = "os", "arch", "compiler", "build_type" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} def config_options(self): if self.settings.os == "Windows": del self.options.fPIC def build(self): env_build = AutoToolsBuildEnvironment(self) env_build.make() """) self.t = TestClient() hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello") main_cpp = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) self.t.save({ "Makefile": makefile, "hello.h": hello_h, "hello.cpp": hello_cpp, "main.cpp": main_cpp, "conanfile.py": conanfile_py, "profile": profile }) self.t.run("install . --profile:host=profile") self.t.run("build .") libhello = os.path.join(self.t.current_folder, "libhello.a") app = os.path.join(self.t.current_folder, "app") self.assertTrue(os.path.isfile(libhello)) self.assertTrue(os.path.isfile(app)) expected_arch = to_apple_arch(self.arch) self.t.run_command('lipo -info "%s"' % libhello) self.assertIn("architecture: %s" % expected_arch, self.t.out) self.t.run_command('lipo -info "%s"' % app) self.assertIn("architecture: %s" % expected_arch, self.t.out)
def test_ios(): xcrun = XCRun(None, sdk='iphoneos') cflags = "" cflags += " -isysroot " + xcrun.sdk_path cflags += " -arch " + to_apple_arch('armv8') cxxflags = cflags ldflags = cflags profile = textwrap.dedent(""" include(default) [settings] os=iOS os.version=12.0 arch=armv8 [env] CC={cc} CXX={cxx} CFLAGS={cflags} CXXFLAGS={cxxflags} LDFLAGS={ldflags} """).format(cc=xcrun.cc, cxx=xcrun.cxx, cflags=cflags, cxxflags=cxxflags, ldflags=ldflags) client = TestClient(path_with_spaces=False) client.save({"m1": profile}, clean_first=True) client.run("new hello/0.1 --template=v2_cmake") client.run("create . --profile:build=default --profile:host=m1 -tf None") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import Autotools class TestConan(ConanFile): requires = "hello/0.1" settings = "os", "compiler", "arch", "build_type" exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsGen" def build(self): self.run("aclocal") self.run("autoconf") self.run("automake --add-missing --foreign") autotools = Autotools(self) autotools.configure() autotools.make() """) client.save({"conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main, "m1": profile}, clean_first=True) client.run("install . --profile:build=default --profile:host=m1") client.run("build .") client.run_command("./main", assert_error=True) assert "Bad CPU type in executable" in client.out client.run_command("lipo -info main") assert "Non-fat file: main is architecture: arm64" in client.out js = client.load("conanbuild.json") assert '"build": "x86_64-apple-darwin"' in js assert '"host": "aarch64-apple-ios"' in js
def test_ios(): xcrun = XCRun(None, sdk='iphoneos') cflags = "" cflags += " -isysroot " + xcrun.sdk_path cflags += " -arch " + to_apple_arch('armv8') cxxflags = cflags ldflags = cflags profile = textwrap.dedent(""" include(default) [settings] os=iOS os.sdk=iphoneos os.version=12.0 arch=armv8 [env] CC={cc} CXX={cxx} CFLAGS={cflags} CXXFLAGS={cxxflags} LDFLAGS={ldflags} """).format(cc=xcrun.cc, cxx=xcrun.cxx, cflags=cflags, cxxflags=cxxflags, ldflags=ldflags) client = TestClient(path_with_spaces=False) client.save({"m1": profile}, clean_first=True) client.run("new hello/0.1 --template=cmake_lib") client.run("create . --profile:build=default --profile:host=m1 -tf None") main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) makefile_am = gen_makefile_am(main="main", main_srcs="main.cpp") configure_ac = gen_configure_ac() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.gnu import Autotools class TestConan(ConanFile): requires = "hello/0.1" settings = "os", "compiler", "arch", "build_type" exports_sources = "configure.ac", "Makefile.am", "main.cpp" generators = "AutotoolsToolchain", "AutotoolsDeps" def build(self): autotools = Autotools(self) autotools.autoreconf() autotools.configure() autotools.make() """) client.save( { "conanfile.py": conanfile, "configure.ac": configure_ac, "Makefile.am": makefile_am, "main.cpp": main, "m1": profile }, clean_first=True) client.run("install . --profile:build=default --profile:host=m1") client.run("build .") client.run_command("./main", assert_error=True) assert "Bad CPU type in executable" in client.out client.run_command("lipo -info main") assert "Non-fat file: main is architecture: arm64" in client.out conanbuild = load_toolchain_args(client.current_folder) configure_args = conanbuild["configure_args"] make_args = conanbuild["make_args"] autoreconf_args = conanbuild["autoreconf_args"] assert configure_args == "'--prefix=/' '--bindir=${prefix}/bin' '--sbindir=${prefix}/bin' " \ "'--libdir=${prefix}/lib' '--includedir=${prefix}/include' " \ "'--oldincludedir=${prefix}/include' '--datarootdir=${prefix}/res' " \ "'--host=aarch64-apple-ios' '--build=x86_64-apple-darwin'" assert make_args == "" assert autoreconf_args == "'--force' '--install'"