#!/usr/bin/env ruby require 'xcodeproj' module Xcodeproj class Project module Object # This class represents a custom build rule of a Target. # class PBXBuildRule < AbstractObject attribute :dependency_file, String end end end end $projectVersion = "3.7.10" $macOSDeploymentTarget = "11" $iOSDeploymentTarget = "12.0" $tests = [ "Ice/acm", "Ice/adapterDeactivation", "Ice/admin", "Ice/ami", "Ice/binding", "Ice/defaultServant", "Ice/defaultValue", "Ice/enums", "Ice/exceptions", "Ice/facets", "Ice/hold", "Ice/info", "Ice/inheritance", "Ice/interceptor", "Ice/invoke", "Ice/location", "Ice/objects", "Ice/operations", "Ice/optional", "Ice/properties", "Ice/proxy", "Ice/retry", "Ice/scope", "Ice/servantLocator", "Ice/services", "Ice/slicing/exceptions", "Ice/slicing/objects", "Ice/stream", "Ice/timeout", "Ice/udp", "IceSSL/configuration", "Slice/escape" ] $test_variants = ["Client", "Server", "ServerAMD", "Collocated"] # # Default sources for each test variant # $test_default_sources = { "Client" => ["Client.swift", "AllTests.swift", "*Test.ice", "Client.ice"], "Server" => ["Server.swift", "TestI.swift", "*Test.ice", "Server.ice"], "ServerAMD" => ["ServerAMD.swift", "TestAMDI.swift", "*TestAMD.ice"], "Collocated" => ["Collocated.swift"] } # # Extra test sources if any # $test_extra_sources = { "Ice/objects" => ["Forward.ice"], "Ice/operations/Client" => ["BatchOneways.swift", "BatchOnewaysAMI.swift", "Oneways.swift", "OnewaysAMI.swift", "Twoways.swift", "TwowaysAMI.swift"], "Ice/servantLocator" => ["ServantLocatorI.swift"], "Ice/slicing/exceptions/Client" => ["ClientPrivate.ice"], "Ice/slicing/exceptions/Server" => ["ServerPrivate.ice"], "Ice/slicing/exceptions/ServerAMD" => ["ServerPrivateAMD.ice"], "Ice/slicing/objects/Client" => ["ClientPrivate.ice"], "Ice/slicing/objects/Server" => ["ServerPrivate.ice"], "Ice/slicing/objects/ServerAMD" => ["ServerPrivateAMD.ice"], "Slice/escape" => ["Clash.ice", "Key.ice"] } $test_extra_frameworks = { "Ice/services" => ["Glacier2.xcframework", "IceStorm.xcframework", "IceGrid.xcframework"] } $test_resources = { "IceSSL/configuration" => ["../../../../cpp/test/IceSSL/certs"] } desc "Generate Xcode projects required to build Ice for Swift" task :icesdistproj do create_project("ice.xcodeproj", false) end desc "Generate Xcode projects required to build Ice for Swift test with Carthage binary dist" task :icebdistproj do create_project("ice-test.xcodeproj", true) end def create_project(name, bindist) project = Xcodeproj::Project.new(name) project.build_configurations.each do |config| config.build_settings["CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER"] = "YES" # Disable header maps as they cause problems with parallel builds on Xcode 12 config.build_settings["USE_HEADERMAP"] = "NO" end [:osx, :ios].each do |platform| create_platform_targets(project, platform, bindist) end attributes = project.root_object.attributes attributes["TargetAttributes"] ||= {} project.targets.each do |target| attributes["TargetAttributes"][target.uuid] ||= {} attributes["TargetAttributes"][target.uuid]["ProvisioningStyle"] = "Automatic" end project.root_object.development_region = "en" project.root_object.known_regions = ["Base", "en"] # # Sort the project and save it # project.sort({:groups_position => :above}) project.save() end task :default => [:icesdistproj] def create_platform_targets(project, platform, bindist) platform_name = platform == :osx ? "macOS" : "iOS" unless bindist # # Ice for C++11 static libraries # cpp_components = ["Ice", "IceSSL", "IceDiscovery", "IceLocatorDiscovery"] cpp_source_dirs = { "Ice" => ["IceUtil", "Ice"] } if platform == :ios then cpp_components << "IceIAP" cpp_source_dirs["Ice"] << "Ice/ios" end excludes = { "Ice" => ["Application.cpp", "AsyncResult.cpp", "AsyncResult.cpp", "ConvertUTF.cpp", "DLLMain.cpp", "GCObject.cpp", "ResponseHandler.cpp", "SystemdJournal.cpp", "Unicode.cpp"], "IceSSL" => ["OpenSSL*", "SChannel*"] } if platform == :ios then excludes["Ice"] << "Tcp*" end cpp_targets = [] ice_cpp_target = nil cpp_components.each do | component | target = project.new_target(:static_library, "#{component} C++11 #{platform_name}", platform) cpp_targets << target group = project_group(project, "slice/#{component}") target_add_files(target, group, "../slice/#{component}", ["*.ice"]) target_add_slice2cpp_build_rule(project, target, component) target.build_configurations.each { |config| config.build_settings["HEADER_SEARCH_PATHS"] = [ "$(SRCROOT)/../cpp/include/", "$(SYMROOT)/$(PLATFORM_NAME)/include/", "$(SRCROOT)/../cpp/src/" ] config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"] = [ "ICE_CPP11_MAPPING", "ICE_BUILDING_SRC", "ICE_STATIC_LIBS", "ICE_SWIFT" ] if config.name == "Release" then config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"] << "NDEBUG" end if component == "Ice" then ice_cpp_target = target else target.add_dependency(ice_cpp_target) end } target_set_common_build_settings(target, "#{component}++11#{platform_name}", platform) source_dirs = cpp_source_dirs[component] || [component] source_dirs.each do |d| group = project_group(project, "cpp/src/#{d}") target_add_files(target, group, "../cpp/src/#{d}", ["*.cpp", "*.mm"], excludes[component] || []) end end # # IceImpl framework # iceimpl_target = project.new_target(:framework, "IceImpl", platform) iceimpl_target.name = "IceImpl #{platform_name}" target = iceimpl_target target.frameworks_build_phases.clear() group = project_group(project, "src/IceImpl") target_add_files(target, group, "src/IceImpl", ["*.mm"]) target_add_headers(target, group, "src/IceImpl", ["*.h"], excludes: ["Convert.h", "LoggerWrapperI.h"], attributes: ["Public"]) target_add_headers(target, group, "src/IceImpl", ["Convert.h", "LoggerWrapperI.h"], attributes: ["Private"]) target_set_common_build_settings(target, "IceImpl", platform, plist: "src/IceImpl/Info.plist") # # IceImpl depends on Ice for C++ frameworks # target.frameworks_build_phases.clear() cpp_targets.each do |t| target.frameworks_build_phases.add_file_reference(t.product_reference, true) target.add_dependency(t) end target.build_configurations.each { |config| config.build_settings["HEADER_SEARCH_PATHS"] = [ "$(SRCROOT)/../cpp/include/", "$(SYMROOT)/$(PLATFORM_NAME)/include/", "$(SRCROOT)/../cpp/src/" ] config.build_settings["DEFINES_MODULE"] = "YES" config.build_settings["OTHER_LDFLAGS"] = [ "-lbz2", "-liconv" ] config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"] = [ "ICE_CPP11_MAPPING", "ICE_STATIC_LIBS", "ICE_SWIFT" ] if config.name == "Release" then config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"] << "NDEBUG" end } target_set_framework_build_settings(target) target.add_system_framework("Security") if platform == :ios then target.add_system_framework("ExternalAccessory") target.add_system_framework("CFNetwork") target.add_system_framework("Foundation") target.add_system_framework("UIKit") end # # Ice for Swift framework # ice_target = project.new_target(:framework, "Ice", platform) ice_target.name = "Ice #{platform_name}" ice_target.add_dependency(iceimpl_target) target = ice_target target.frameworks_build_phases.clear() target.frameworks_build_phases.add_file_reference(iceimpl_target.product_reference, true) target_set_common_build_settings(target, "Ice", platform, plist: "src/Ice/Info.plist", swift: true) target.build_configurations.each { |config| config.build_settings["DEFINES_MODULE"] = "NO" } target_set_framework_build_settings(target) target_add_carthage_framework(target, platform, "PromiseKit.xcframework") group = project_group(project, "src/Ice") group_add_files(group, "src/Ice", ["*.plist"]) target_add_headers(target, group, "src/Ice", ["*.h"]) target_add_files(target, group, "src/Ice", ["*.swift"]) slices = ["Ice", "IceSSL"] if platform == :ios then slices << "IceIAP" end slices.each do |item| group = project_group(project, "slice/#{item}") target_add_files(target, group, "../slice/#{item}", ["*.ice"], excludes[item] || []) target_add_slice2swift_build_rule(project, target, item, srcPrefix: "../slice/#{item}") end # # Glacier2, IceStorm and IceGrid Frameworks # glacier2_target = project.new_target(:framework, "Glacier2", platform) icestorm_target = project.new_target(:framework, "IceStorm", platform) icegrid_target = project.new_target(:framework, "IceGrid", platform) framework_targets = { "IceImpl.xcframework" => iceimpl_target, "Ice.xcframework" => ice_target, "Glacier2.xcframework" => glacier2_target, "IceStorm.xcframework" => icestorm_target, "IceGrid.xcframework" => icegrid_target } [glacier2_target, icestorm_target, icegrid_target].each do | t | target = t framework = target.name target.name = "#{target.name} #{platform_name}" target.frameworks_build_phases.clear() target_set_common_build_settings(target, framework, platform, plist: "src/#{framework}/Info.plist", swift: true) target.build_configurations.each { |config| config.build_settings["DEFINES_MODULE"] = "NO" } target_set_framework_build_settings(target) target_add_carthage_framework(target, platform, "PromiseKit.xcframework") group = project_group(project, "src/#{framework}") group_add_files(group, "src/#{framework}", ["*.plist"]) target_add_headers(target, group, "src/#{framework}", ["*.h"]) target_add_files(target, group, "src/#{framework}", ["*.swift"]) group = project_group(project, "slice/#{framework}") target_add_files(target, group, "../slice/#{framework}", ["*.ice"]) target_add_slice2swift_build_rule(project, target, framework, srcPrefix: "../slice/#{framework}") target.frameworks_build_phases.add_file_reference(ice_target.product_reference) target.add_dependency(ice_target) end # # IceGrid requires Glacier2 # icegrid_target.frameworks_build_phases.add_file_reference(glacier2_target.product_reference) icegrid_target.add_dependency(glacier2_target) end # # TestCommon framework # target = project.new_target(:framework, "TestCommon", platform) target.name = "#{target.name} #{platform_name}" target_set_framework_build_settings(target) target_add_carthage_framework(target, platform, "PromiseKit.xcframework") if bindist then target_add_carthage_framework(target, platform, "IceImpl.xcframework") target_add_carthage_framework(target, platform, "Ice.xcframework") else target.frameworks_build_phases.add_file_reference(ice_target.product_reference, true) end target_add_slice2swift_build_rule(project, target, "test/TestCommon", test: true) test_common_target = target # # Add .ice and .swift files to the target # group = project_group(project, "test/TestCommon") group_add_files(group, "test/TestCommon", ["*.plist"]) target_add_files(target, group, "test/TestCommon", ["*.ice", "*.swift"]) target_set_common_build_settings(target, "TestCommon", platform, plist: "test/TestCommon/Info.plist", swift: true) # # TestDriver app # target = project.new_target(:application, "TestDriver", platform) target.name = "#{target.name} #{platform_name}" target_set_common_build_settings(target, "TestDriver", platform, plist: "test/TestDriver/#{platform_name}/Info.plist", swift: true, identifier: "com.zeroc.Swift-Test-Controller") target_add_slice2swift_build_rule(project, target, "test/TestDriver", srcPrefix: "../scripts", test: true) group = project_group(project, "test/TestDriver") target_add_files(target, group, "test/TestDriver", ["*.ice", "*.swift"]) group = project_group(project, "test/TestDriver/#{platform_name}") target_add_files(target, group, "test/TestDriver/#{platform_name}", ["*.ice", "*.swift"]) if platform == :ios then target_add_files(target, group, "../scripts", ["*.ice"]) target_add_files(target, group, "test/TestDriver/#{platform_name}", ["*.xcassets"]) target_add_files(target, group, "test/TestDriver/#{platform_name}/Base.lproj", ["*.storyboard"]) target.add_resources(group_add_files(group, "..", ["certs"])) target.build_configurations.each { |config| config.build_settings["ONLY_ACTIVE_ARCH"] = "YES" } end # # Copy IceImpl, Ice and TestCommon frameworks to the test driver # copy_phase = target.new_copy_files_build_phase("Copy Frameworks") copy_phase.dst_subfolder_spec = Xcodeproj::Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[:frameworks] copy_symbols = target.new_copy_files_build_phase("Copy Symbols") copy_symbols.dst_subfolder_spec = Xcodeproj::Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[:products_directory] target_set_framework_build_settings(target) if bindist then target_add_carthage_framework(target, platform, "IceImpl.xcframework", true) target_add_carthage_framework(target, platform, "Ice.xcframework", true) target_add_carthage_framework(target, platform, "Glacier2.xcframework", true) target_add_carthage_framework(target, platform, "IceStorm.xcframework", true) target_add_carthage_framework(target, platform, "IceGrid.xcframework", true) else framework_targets.each do |name, t| file = copy_phase.add_file_reference(t.product_reference) file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] } target.frameworks_build_phases.add_file_reference(t.product_reference) target.add_dependency(t) end end file = copy_phase.add_file_reference(test_common_target.product_reference) file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] } target_add_carthage_framework(target, platform, "PromiseKit.xcframework", true) test_driver_target = target # # For each test create a bundle target # $tests.each do |test| target = project.new_target(:bundle, target_name("#{test}"), platform) target.name = "#{target.name} #{platform_name}" if bindist target_add_carthage_framework(target, platform, "Ice.xcframework") else target.frameworks_build_phases.add_file_reference(ice_target.product_reference, true) target.add_dependency(ice_target) end target.frameworks_build_phases.add_file_reference(test_common_target.product_reference, true) target.add_dependency(test_common_target) extra_frameworks = $test_extra_frameworks[test] || [] extra_frameworks.each do |f| if bindist target_add_carthage_framework(target, platform, f) else if framework_targets.include? f target_framework = framework_targets[f] target.frameworks_build_phases.add_file_reference(target_framework.product_reference, true) target.add_dependency(target_framework) else target_add_carthage_framework(target, platform, f) end end end target_set_framework_build_settings(target) target.build_configurations.each { |config| config.build_settings["ENABLE_BITCODE"] = "NO" } target_add_carthage_framework(target, platform, "PromiseKit.xcframework") target_add_slice2swift_build_rule(project, target, "test/#{test}", test: true) # # Add .ice and .swift files to the target # group = project_group(project, "test/#{test}") group_add_files(group, "test/#{test}", ["*.plist"]) $test_variants.reject{ |item| item == "ServerAMD" }.each do |variant| unless test_has_variant(test, variant) next end target_add_files(target, group, "test/#{test}", test_variant_sources(test, variant)) end if $test_resources.include? test then target.add_resources(group_add_files(group, "test/#{test}", $test_resources[test])) end target_set_common_build_settings(target, target_name("#{test}"), platform, plist: "test/TestCommon/Info.plist", swift: true) test_driver_target.add_dependency(target) # # Add the bundle to test driver copy phase # file = copy_phase.add_file_reference(target.product_reference) file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] } end # # Create a separate bundle for AMD test if there is an AMD test variant # $tests.each do |test| if test_has_variant(test, "ServerAMD") target = project.new_target(:bundle, target_name("#{test}AMD"), platform) target.name = "#{target.name} #{platform_name}" if bindist target_add_carthage_framework(target, platform, "Ice.xcframework") else target.frameworks_build_phases.add_file_reference(ice_target.product_reference, true) end extra_frameworks = $test_extra_frameworks[test] || [] extra_frameworks.each do |f| if bindist target_add_carthage_framework(target, platform, f) else if framework_targets.include? f target_framework = framework_targets[f] target.frameworks_build_phases.add_file_reference(target_framework.product_reference, true) target.add_dependency(target_framework) else target_add_carthage_framework(target, platform, f) end end end target.frameworks_build_phases.add_file_reference(test_common_target.product_reference, true) target_set_framework_build_settings(target) target.build_configurations.each { |config| config.build_settings["ENABLE_BITCODE"] = "NO" } target_add_carthage_framework(target, platform, "PromiseKit.xcframework") target_add_slice2swift_build_rule(project, target, "test/#{test}", test: true) # # Add .ice and .swift files to the target # group = project_group(project, "test/#{test}") group_add_files(group, "test/#{test}", ["*.plist"]) target_add_files(target, group, "test/#{test}", test_variant_sources(test, "ServerAMD"), ["Test.ice", "Client*.ice"]) target_set_common_build_settings(target, target_name("#{test}AMD"), platform, plist: "test/TestCommon/Info.plist", swift: true) test_driver_target.add_dependency(target) # # Add the bundle to test driver copy phase # file = copy_phase.add_file_reference(target.product_reference) file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] } end end # # Ensure there is a shared scheme to build the frameworks distributed with Carthage builds # unless bindist scheme = Xcodeproj::XCScheme.new scheme.add_build_target(iceimpl_target) scheme.add_build_target(ice_target) scheme.add_build_target(glacier2_target) scheme.add_build_target(icestorm_target) scheme.add_build_target(icegrid_target) scheme.build_action.parallelize_buildables = false scheme.save_as("ice.xcodeproj", "Ice #{platform_name}", true) end end def project_group(project, name) group = project.main_group name.split("/").each { |item| new_group = group[item] unless new_group new_group = group.new_group(item) end group = new_group } group end def target_name(basename, suffix = nil) name = basename.split("/").map{ |item| item[0].upcase + item[1..-1]}.join() suffix ? "#{name} #{suffix}" : name end def target_add_slice2swift_build_rule(project, target, projectPrefix, srcPrefix: nil, test: false) unless srcPrefix srcPrefix = projectPrefix end # # Add Slice Compiler build rule to the target # rule = project.new(Xcodeproj::Project::PBXBuildRule) rule.compiler_spec = "com.apple.compilers.proxy.script" rule.file_type = "pattern.proxy" slic2swift = <<~EOF BREW_PREFIX=$($SHELL -c 'brew --prefix' 2>/dev/null) if [ -f "${ICE_HOME-unset}/bin/slice2swift" ]; then SLICE2SWIFT="$ICE_HOME/bin/slice2swift" elif [ -f "$SRCROOT/../cpp/bin/slice2swift" ]; then SLICE2SWIFT="$SRCROOT/../cpp/bin/slice2swift" elif [ -f "${BREW_PREFIX-unset}/bin/slice2swift" ]; then SLICE2SWIFT=$BREW_PREFIX/bin/slice2swift SLICEDIR=$BREW_PREFIX/share/ice/slice else echo "Failed to locate slice2swift compiler" exit 1 fi EOF rule.name = "Slice Compiler for #{projectPrefix}/*.ice" rule.run_once_per_architecture = "0" rule.file_patterns = "*/#{srcPrefix.delete_prefix('../')}/*.ice" if test then rule.script = <<~EOF #{slic2swift} "$SLICE2SWIFT" -I"$SRCROOT/../slice" -I"$INPUT_FILE_DIR" \ --depend --depend-file "$DERIVED_FILE_DIR/$INPUT_FILE_BASE.d" "$INPUT_FILE_PATH" echo "$INPUT_FILE_BASE.ice: $SLICE2SWIFT" >> "$DERIVED_FILE_DIR/$INPUT_FILE_BASE.d" "$SLICE2SWIFT" -I"$SRCROOT/../slice" -I"$INPUT_FILE_DIR" --output-dir "$DERIVED_FILE_DIR" "$INPUT_FILE_PATH" EOF rule.input_files = find_files(srcPrefix, ["*.ice"]).map { |p| "#{srcPrefix}/#{p}" } rule.output_files = ["$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).swift"] rule.dependency_file = "$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).d" else rule.script = <<~EOF #{slic2swift} BASENAME=$(basename -- "$INPUT_FILE_PATH") BASENAME="${BASENAME%.*}" mkdir -p "$DERIVED_FILE_DIR/#{projectPrefix}" "$SLICE2SWIFT" -I"$SRCROOT/../slice" -I"$INPUT_FILE_DIR" \ --depend --depend-file "$DERIVED_FILE_DIR/#{projectPrefix}_$INPUT_FILE_BASE.d" "$INPUT_FILE_PATH" echo "$INPUT_FILE_BASE.ice: $SLICE2SWIFT" >> "$DERIVED_FILE_DIR/#{projectPrefix}_$INPUT_FILE_BASE.d" "$SLICE2SWIFT" -I"$SRCROOT/../slice" -I"$INPUT_FILE_DIR" --output-dir "$DERIVED_FILE_DIR/#{projectPrefix}" \ "$INPUT_FILE_PATH" mv "$DERIVED_FILE_DIR/#{projectPrefix}/$BASENAME.swift" "$DERIVED_FILE_DIR/#{projectPrefix}_$BASENAME.swift" EOF rule.input_files = find_files(srcPrefix, ["*.ice"]).map { |p| "$SRCROOT/#{srcPrefix}/#{p}" } rule.output_files = ["$(DERIVED_FILE_DIR)/#{projectPrefix}_$(INPUT_FILE_BASE).swift"] rule.dependency_file = "$(DERIVED_FILE_DIR)/#{projectPrefix}_$(INPUT_FILE_BASE).d" end target.build_rules << rule end def target_add_slice2cpp_build_rule(project, target, prefix) # # Add Slice Compiler build rule to the target # rule = project.new(Xcodeproj::Project::PBXBuildRule) rule.compiler_spec = "com.apple.compilers.proxy.script" rule.run_once_per_architecture = "0" rule.file_type = "pattern.proxy" rule.name = "Slice2Cpp Compiler for #{prefix}/*.ice" rule.file_patterns = "*/#{prefix}/*.ice" rule.script = <<~EOF BREW_PREFIX=$($SHELL -c 'brew --prefix' 2>/dev/null) if [ -f "${ICE_HOME-unset}/bin/slice2cpp" ]; then SLICE2CPP="$ICE_HOME/bin/slice2cpp" elif [ -f "$SRCROOT/../cpp/bin/slice2cpp" ]; then SLICE2CPP="$SRCROOT/../cpp/bin/slice2cpp" elif [ -f "${BREW_PREFIX-unset}/bin/slice2cpp" ]; then SLICE2CPP=$BREW_PREFIX/bin/slice2cpp else echo "Failed to locate slice2cpp compiler" exit 1 fi BASENAME=$(basename -- "$INPUT_FILE_PATH") BASENAME="${BASENAME%.*}" mkdir -p "$DERIVED_FILE_DIR/#{prefix}" $SLICE2CPP -I"$SRCROOT/../slice" -D ICE_SWIFT --include-dir #{prefix} \ --output-dir "$DERIVED_FILE_DIR/#{prefix}" \ --depend --depend-file "$DERIVED_FILE_DIR/#{prefix}/$INPUT_FILE_BASE.d" \ "$INPUT_FILE_PATH" echo "$INPUT_FILE_BASE.ice: $SLICE2CPP" >> "$DERIVED_FILE_DIR/#{prefix}/$INPUT_FILE_BASE.d" $SLICE2CPP -I"$SRCROOT/../slice" -D ICE_SWIFT --include-dir #{prefix} \ --output-dir "$DERIVED_FILE_DIR/#{prefix}" \ "$INPUT_FILE_PATH" mkdir -p "$SYMROOT/$PLATFORM_NAME/include/#{prefix}" mv "$DERIVED_FILE_DIR/#{prefix}/$BASENAME.h" "$SYMROOT/$PLATFORM_NAME/include/#{prefix}/$BASENAME.h" EOF rule.output_files = ["$(DERIVED_FILE_DIR)/#{prefix}/$(INPUT_FILE_BASE).cpp", "$(SYMROOT)/$(PLATFORM_NAME)/include/#{prefix}/$(INPUT_FILE_BASE).h"] inputs = find_files("../slice/#{prefix}", ["*.ice"]).map { |p| File.basename(p, ".ice") } rule.input_files = inputs.map { |p| "$SRCROOT/../slice/#{prefix}/#{p}.ice" } rule.dependency_file= "$(DERIVED_FILE_DIR)/#{prefix}/$(INPUT_FILE_BASE).d" target.build_rules << rule end def find_files(basedir, patterns, exclude = []) files = [] Dir.chdir(basedir) do patterns.each do |p| Dir.glob(p) do |file| files << file end end end return files.reject { |item| exclude.any? { |pattern| item.match(pattern) } } end def group_add_files(group, basedir, patterns, exclude = []) find_files(basedir, patterns, exclude).map { |file| group.find_subpath(File.basename(file)) || group.new_file("#{basedir}/#{file}") } end def target_add_files(target, group, basedir, patterns, excludes = []) target.add_file_references(group_add_files(group, basedir, patterns, excludes)) end def target_add_headers(target, group, basedir, patterns, excludes: [], attributes: ["Public"]) files = group_add_files(group, basedir, patterns, excludes) files.each do |file| header = target.headers_build_phase.add_file_reference(file) header.settings = { "ATTRIBUTES" => attributes } end end def target_set_common_build_settings(target, product, platform, plist: nil, swift: false, identifier: nil) target.build_configurations.each { |config| config.build_settings["GCC_SYMBOLS_PRIVATE_EXTERN"] = "YES" config.build_settings["ENABLE_TESTABILITY"] = "NO" config.build_settings["GCC_TREAT_WARNINGS_AS_ERRORS"] = "YES" config.build_settings["CLANG_CXX_LANGUAGE_STANDARD"] = "c++17" config.build_settings["CURRENT_PROJECT_VERSION"] = $projectVersion config.build_settings["DYLIB_CURRENT_VERSION"] = $projectVersion config.build_settings["DYLIB_COMPATIBILITY_VERSION"] = "0" if plist then config.build_settings["INFOPLIST_FILE"] = plist end config.build_settings["PRODUCT_NAME"] = product config.build_settings["PRODUCT_BUNDLE_IDENTIFIER"] = identifier || "com.zeroc.#{product}" if swift then config.build_settings["SWIFT_VERSION"] = "5.2" config.build_settings["SWIFT_TREAT_WARNINGS_AS_ERRORS"] = "YES" end config.build_settings["SUPPORTED_PLATFORMS"] = (target.name.include? "macOS") ? "macosx" : "iphoneos iphonesimulator" config.build_settings["AVAILABLE_PLATFORMS"] = (target.name.include? "macOS") ? "macosx" : "iphoneos iphonesimulator" if ENV.has_key?("DEVELOPMENT_TEAM") then if target.product_type == "com.apple.product-type.application" or target.product_type == "com.apple.product-type.bundle" then config.build_settings["CODE_SIGN_STYLE"] = "Automatic" config.build_settings["CODE_SIGN_IDENTITY"] = "Apple Development" config.build_settings["DEVELOPMENT_TEAM"] = ENV["DEVELOPMENT_TEAM"] end end if target.product_type == "com.apple.product-type.application" or target.product_type == "com.apple.product-type.bundle" then config.build_settings["DEAD_CODE_STRIPPING"] = "YES" end if platform == :osx config.build_settings["MACOSX_DEPLOYMENT_TARGET"] = $macOSDeploymentTarget else config.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] = $iOSDeploymentTarget end } end def target_set_framework_build_settings(target) target.build_configurations.each { |config| config.build_settings["FRAMEWORK_SEARCH_PATHS"] = "$(SRCROOT)/../Carthage/Build/" } end def target_add_carthage_framework(target, platform, framework, copy=false) group = target.project.frameworks_group[(platform == :osx ? "OS X" : "iOS")] group_add_files(group, "../Carthage/Build", [framework]).each do |ref| # When copy is true we copy the framework to the target, for :ios targets we use the carthage copy-frameworks # script for macOS targets we use the regular copy phase. if copy then file = target.copy_files_build_phases[0].add_file_reference(ref) file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] } end # when copy is false or the target platform is ios we also have to add a reference into the target # frameworks build phase. unless copy and platform == :macos then target.frameworks_build_phases.add_file_reference(ref, true) end end end # # Check if the test include the given variant # def test_has_variant(test, variant) return File.file?("test/#{test}/#{variant}.swift") end def test_variant_sources(test, variant) sources = $test_default_sources[variant] if variant == "Collocated" sources += $test_default_sources["Server"].reject { |s| s == "Server.swift" } sources += $test_default_sources["Client"].reject { |s| s == "Client.swift" } sources += $test_extra_sources["#{test}/Server"] || [] sources += $test_extra_sources["#{test}/Client"] || [] end sources += $test_extra_sources[test] || [] sources += $test_extra_sources["#{test}/#{variant}"] || [] return sources end