From 2debbfccf627437a6d3d4d049568f9cfb6e42c1e Mon Sep 17 00:00:00 2001 From: Mikko Lehtonen Date: Wed, 2 Oct 2024 10:46:21 +0300 Subject: [PATCH] Implement features required by Xcode (#2257) * Mark `-index-store-path` as Hard Xcode sets it by default, but it can be disabled with `COMPILER_INDEX_STORE_ENABLE=NO` Xcode build setting. * Mark serialize-diagnostics and deps as artifacts Xcode requires these files to be present after compiling, so they need to be stored and restored for the build to complete. * Update tests for the dep changes * Add test for `-index-store-path` * Add documentation for Xcode use * Xcode integration test * Add comment about wrapper script use --- .github/workflows/integration-tests.yml | 54 ++++ docs/Xcode.md | 116 ++++++++ src/compiler/gcc.rs | 123 +++++++- src/compiler/msvc.rs | 3 +- src/compiler/nvcc.rs | 7 + src/compiler/nvhpc.rs | 7 + tests/xcode/main.cpp | 6 + tests/xcode/sccache.xcconfig | 3 + .../xcode-test.xcodeproj/project.pbxproj | 279 ++++++++++++++++++ 9 files changed, 581 insertions(+), 17 deletions(-) create mode 100644 docs/Xcode.md create mode 100644 tests/xcode/main.cpp create mode 100644 tests/xcode/sccache.xcconfig create mode 100644 tests/xcode/xcode-test.xcodeproj/project.pbxproj diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 8cb398ec0..2a3eb08e9 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -894,3 +894,57 @@ jobs: cargo clean && cargo build - name: lv10-stats-use run: ${SCCACHE_PATH} --show-stats + + xcode: + runs-on: macos-latest + env: + SCCACHE_PATH: target/debug/sccache + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install rust + uses: ./.github/actions/rust-toolchain + with: + toolchain: "stable" + + - name: Build sccache + run: | + cargo build + + # Wrapper for the compiler invocation, so that we have a single command + # that calls sccache with the actual compiler argument. + # Just setting CC to be `sccache clang++` doesn't work as it is + # interpreted as the whole command that just happens to contain spaces. + - name: Create wrapper script + working-directory: tests/xcode + run: | + echo '#!/bin/sh' > wrapper.sh + echo "$GITHUB_WORKSPACE/${SCCACHE_PATH} $(xcrun -f cc) \$@" >> wrapper.sh + chmod +x wrapper.sh + echo "Wrapper script:" + cat wrapper.sh + + - name: Start server + run: ${SCCACHE_PATH} --start-server + + - name: Test compile xcode + working-directory: tests/xcode + run: | + xcodebuild -version + xcodebuild -xcconfig sccache.xcconfig + + - name: Output + run: | + ${SCCACHE_PATH} --show-stats + + - name: Test compile xcode cached + working-directory: tests/xcode + run: | + xcodebuild clean + xcodebuild -xcconfig sccache.xcconfig + + - name: Output + run: | + ${SCCACHE_PATH} --show-stats + ${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]" diff --git a/docs/Xcode.md b/docs/Xcode.md new file mode 100644 index 000000000..83a3bbfda --- /dev/null +++ b/docs/Xcode.md @@ -0,0 +1,116 @@ +# Using `sccache` with Xcode + +It is possible to use `sccache` with Xcode with some setup. + +### Running the daemon +Before building, you need to run the daemon outside of Xcode. This needs to be done because if `sccache` invocation happens to implicitly start the server daemon, the Xcode build will hang on the `sccache` invocation, waiting for the process to idle timeout. + +You can do this in another terminal windows by calling +```sh +SCCACHE_LOG=info SCCACHE_START_SERVER=1 SCCACHE_NO_DAEMON=1 sccache +``` + +Or by setting it up in a `launchd` configuration, perhaps as `~/Library/LaunchAgents/sccache.plist` (note the paths in the plist): +```xml + + + + + Label + sccache.server + ProgramArguments + + /path/to/sccache + + EnvironmentVariables + + SCCACHE_START_SERVER + 1 + SCCACHE_NO_DAEMON + 1 + SCCACHE_IDLE_TIMEOUT + 0 + SCCACHE_LOG + info + + + StandardOutPath + /tmp/sccache.log + StandardErrorPath + /tmp/sccache.log + + + +``` + +### Setting it up for `xcodebuild` +When you override the `CC` variable for `xcodebuild`, it seems to always escape the spaces, so its not enough to just set it, but we need a wrapper script, something like + +```sh +echo "#\!/bin/sh\nsccache $(xcrun -f cc) \$@" > wrapper.sh +chmod +x wrapper.sh +``` +(YMMV if you need to select another sdk or toolchain for the xcrun) + +Then you can invoke `xcodebuild` like so +```sh +xcodebuild CC="$(pwd)/wrapper.sh" + CLANG_ENABLE_MODULES=NO + COMPILER_INDEX_STORE_ENABLE=NO +``` +Where the additional arguments are for disabling some features that `sccache` can't cache currently. + +These build settings can also be put in a xcconfig file, like `sccache.xcconfig` +``` +CC=$(SRCROOT)/wrapper.sh +CLANG_ENABLE_MODULES=NO +COMPILER_INDEX_STORE_ENABLE=NO +``` +Which can then be invoked with +```sh +xcodebuild -xcconfig sccache.xcconfig +``` + + +### Setting it up for `cmake` Xcode generator +While `cmake` has the convenient `CMAKE__COMPILER_LAUNCHER` for prepending tools like `sccache`, it is not supported for the Xcode generator. + +It can be then integrated with having a template file for the wrapper script, `launcher.sh.in`: +```sh +#!/bin/sh +exec "${CCACHE_EXE}" "${LAUNCHER_COMPILER}" "$@" +``` + +And then configuring it something like +```cmake + +# This bit before the first `project()`, as the COMPILER_LAUNCHER variables are read in then +if(DEFINED CCACHE) + find_program(CCACHE_EXE ${CCACHE} REQUIRED) + if(NOT CMAKE_GENERATOR STREQUAL "Xcode") + # Support for other generators should work with these + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXE}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXE}") + endif() +endif() + +# .. your project stuff .. + +# This bit needs to be after the first `project()` call, to have valid `CMAKE_C_COMPILER` variable. +# Alternatively in a file included with CMAKE_PROJECT_INCLUDE +if(DEFINED CCACHE) + if(CMAKE_GENERATOR STREQUAL "Xcode") + set(LAUNCHER_COMPILER ${CMAKE_C_COMPILER}) + configure_file(${CMAKE_CURRENT_LIST_DIR}/launcher.sh.in launcher-cc.sh) + execute_process(COMMAND chmod a+rx + "${CMAKE_CURRENT_BINARY_DIR}/launcher-cc.sh") + set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launcher-cc.sh") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "NO") + set(CMAKE_XCODE_ATTRIBUTE_COMPILER_INDEX_STORE_ENABLE "NO") + endif() +endif() +``` +Then configuring with `-DCCACHE=sccache` should work on all generators. + + + diff --git a/src/compiler/gcc.rs b/src/compiler/gcc.rs index f987e0ce0..d37326431 100644 --- a/src/compiler/gcc.rs +++ b/src/compiler/gcc.rs @@ -148,6 +148,7 @@ ArgData! { pub Arch(OsString), PedanticFlag, Standard(OsString), + SerializeDiagnostics(PathBuf), } use self::ArgData::*; @@ -160,7 +161,7 @@ counted_array!(pub static ARGS: [ArgInfo; _] = [ flag!("--coverage", Coverage), take_arg!("--param", OsString, Separated, PassThrough), flag!("--save-temps", TooHardFlag), - take_arg!("--serialize-diagnostics", PathBuf, Separated, PassThroughPath), + take_arg!("--serialize-diagnostics", PathBuf, Separated, SerializeDiagnostics), take_arg!("--sysroot", PathBuf, Separated, PassThroughPath), take_arg!("-A", OsString, Separated, PassThrough), take_arg!("-B", PathBuf, CanBeSeparated, PassThroughPath), @@ -210,6 +211,7 @@ counted_array!(pub static ARGS: [ArgInfo; _] = [ take_arg!("-imacros", PathBuf, CanBeSeparated, PreprocessorArgumentPath), take_arg!("-imultilib", PathBuf, CanBeSeparated, PreprocessorArgumentPath), take_arg!("-include", PathBuf, CanBeSeparated, PreprocessorArgumentPath), + take_arg!("-index-store-path", OsString, Separated, TooHard), take_arg!("-install_name", OsString, Separated, PassThrough), take_arg!("-iprefix", PathBuf, CanBeSeparated, PreprocessorArgumentPath), take_arg!("-iquote", PathBuf, CanBeSeparated, PreprocessorArgumentPath), @@ -270,6 +272,7 @@ where let mut language_extensions = true; // by default, GCC allows extensions let mut split_dwarf = false; let mut need_explicit_dep_target = false; + let mut dep_path = None; enum DepArgumentRequirePath { NotNeeded, Missing, @@ -283,6 +286,7 @@ where let mut xclangs: Vec = vec![]; let mut color_mode = ColorMode::Auto; let mut seen_arch = None; + let mut serialize_diagnostics = None; let dont_cache_multiarch = env::var("SCCACHE_CACHE_MULTIARCH").is_err(); // Custom iterator to expand `@` arguments which stand for reading a file @@ -360,8 +364,12 @@ where dep_flag = OsString::from(arg.flag_str().expect("Dep target flag expected")); dep_target = Some(s.clone()); } - Some(DepArgumentPath(_)) => { - need_explicit_dep_argument_path = DepArgumentRequirePath::Provided + Some(DepArgumentPath(path)) => { + need_explicit_dep_argument_path = DepArgumentRequirePath::Provided; + dep_path = Some(path.clone()); + } + Some(SerializeDiagnostics(path)) => { + serialize_diagnostics = Some(path.clone()); } Some(ExtraHashFile(_)) | Some(PassThroughFlag) @@ -446,8 +454,12 @@ where &mut preprocessor_args } Some(DepArgumentPath(_)) | Some(NeedDepTarget) => &mut dependency_args, - Some(DoCompilation) | Some(Language(_)) | Some(Output(_)) | Some(XClang(_)) - | Some(DepTarget(_)) => continue, + Some(DoCompilation) + | Some(Language(_)) + | Some(Output(_)) + | Some(XClang(_)) + | Some(DepTarget(_)) + | Some(SerializeDiagnostics(_)) => continue, Some(TooHardFlag) | Some(TooHard(_)) => unreachable!(), None => match arg { Argument::Raw(_) => continue, @@ -506,7 +518,8 @@ where | Some(Arch(_)) | Some(PassThrough(_)) | Some(PassThroughFlag) - | Some(PassThroughPath(_)) => &mut common_args, + | Some(PassThroughPath(_)) + | Some(SerializeDiagnostics(_)) => &mut common_args, Some(Unhashed(_)) => &mut unhashed_args, Some(ExtraHashFile(path)) => { extra_hash_files.push(cwd.join(path)); @@ -607,6 +620,27 @@ where dependency_args.push(OsString::from("-MF")); dependency_args.push(Path::new(&output).with_extension("d").into_os_string()); } + + if let Some(path) = dep_path { + outputs.insert( + "d", + ArtifactDescriptor { + path: path.clone(), + optional: false, + }, + ); + } + + if let Some(path) = serialize_diagnostics { + outputs.insert( + "dia", + ArtifactDescriptor { + path: path.clone(), + optional: false, + }, + ); + } + outputs.insert( "obj", ArtifactDescriptor { @@ -801,6 +835,7 @@ pub fn generate_compile_commands( out_file.into(), ]); arguments.extend_from_slice(&parsed_args.preprocessor_args); + arguments.extend_from_slice(&parsed_args.dependency_args); arguments.extend_from_slice(&parsed_args.unhashed_args); arguments.extend_from_slice(&parsed_args.common_args); arguments.extend_from_slice(&parsed_args.arch_args); @@ -1332,7 +1367,7 @@ mod test { "foo.c", "-fabc", "-MF", - "file", + "foo.o.d", "-o", "foo.o", "-MQ", @@ -1362,9 +1397,16 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); - assert_eq!(ovec!["-MF", "file"], dependency_args); + assert_eq!(ovec!["-MF", "foo.o.d"], dependency_args); assert_eq!(ovec!["-nostdinc"], preprocessor_args); assert_eq!(ovec!["-fabc"], common_args); assert!(!msvc_show_includes); @@ -1432,7 +1474,7 @@ mod test { #[test] fn test_parse_arguments_explicit_dep_target() { let args = - stringvec!["-c", "foo.c", "-MT", "depfile", "-fabc", "-MF", "file", "-o", "foo.o"]; + stringvec!["-c", "foo.c", "-MT", "depfile", "-fabc", "-MF", "foo.o.d", "-o", "foo.o"]; let ParsedArguments { input, language, @@ -1455,9 +1497,16 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); - assert_eq!(ovec!["-MF", "file"], dependency_args); + assert_eq!(ovec!["-MF", "foo.o.d"], dependency_args); assert_eq!(ovec!["-fabc"], common_args); assert!(!msvc_show_includes); } @@ -1465,7 +1514,7 @@ mod test { #[test] fn test_parse_arguments_explicit_dep_target_needed() { let args = stringvec![ - "-c", "foo.c", "-MT", "depfile", "-fabc", "-MF", "file", "-o", "foo.o", "-MD" + "-c", "foo.c", "-MT", "depfile", "-fabc", "-MF", "foo.o.d", "-o", "foo.o", "-MD" ]; let ParsedArguments { input, @@ -1490,10 +1539,17 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); assert_eq!( - ovec!["-MF", "file", "-MD", "-MT", "depfile"], + ovec!["-MF", "foo.o.d", "-MD", "-MT", "depfile"], dependency_args ); assert!(preprocessor_args.is_empty()); @@ -1504,7 +1560,7 @@ mod test { #[test] fn test_parse_arguments_explicit_mq_dep_target_needed() { let args = stringvec![ - "-c", "foo.c", "-MQ", "depfile", "-fabc", "-MF", "file", "-o", "foo.o", "-MD" + "-c", "foo.c", "-MQ", "depfile", "-fabc", "-MF", "foo.o.d", "-o", "foo.o", "-MD" ]; let ParsedArguments { input, @@ -1529,10 +1585,17 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); assert_eq!( - ovec!["-MF", "file", "-MD", "-MQ", "depfile"], + ovec!["-MF", "foo.o.d", "-MD", "-MQ", "depfile"], dependency_args ); assert!(preprocessor_args.is_empty()); @@ -1740,7 +1803,7 @@ mod test { #[test] fn test_parse_arguments_dep_target_needed() { - let args = stringvec!["-c", "foo.c", "-fabc", "-MF", "file", "-o", "foo.o", "-MD"]; + let args = stringvec!["-c", "foo.c", "-fabc", "-MF", "foo.o.d", "-o", "foo.o", "-MD"]; let ParsedArguments { input, language, @@ -1763,9 +1826,19 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); - assert_eq!(ovec!["-MF", "file", "-MD", "-MT", "foo.o"], dependency_args); + assert_eq!( + ovec!["-MF", "foo.o.d", "-MD", "-MT", "foo.o"], + dependency_args + ); assert_eq!(ovec!["-fabc"], common_args); assert!(!msvc_show_includes); } @@ -1884,6 +1957,24 @@ mod test { ); } + #[test] + fn test_parse_index_store_path() { + assert_eq!( + CompilerArguments::CannotCache("-index-store-path", None), + parse_arguments_( + stringvec![ + "-c", + "foo.c", + "-index-store-path", + "index.store", + "-o", + "foo.o" + ], + false + ) + ); + } + #[test] fn test_parse_arguments_multiarch_cache_disabled() { with_var_unset("SCCACHE_CACHE_MULTIARCH", || { diff --git a/src/compiler/msvc.rs b/src/compiler/msvc.rs index b9b797888..198ba5b76 100644 --- a/src/compiler/msvc.rs +++ b/src/compiler/msvc.rs @@ -666,7 +666,8 @@ pub fn parse_arguments( | Some(PassThrough(_)) | Some(PassThroughPath(_)) | Some(PedanticFlag) - | Some(Standard(_)) => &mut common_args, + | Some(Standard(_)) + | Some(SerializeDiagnostics(_)) => &mut common_args, Some(Unhashed(_)) => &mut unhashed_args, Some(ProfileGenerate) => { diff --git a/src/compiler/nvcc.rs b/src/compiler/nvcc.rs index 3915acea7..91f5c0392 100644 --- a/src/compiler/nvcc.rs +++ b/src/compiler/nvcc.rs @@ -613,6 +613,13 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); assert_eq!( diff --git a/src/compiler/nvhpc.rs b/src/compiler/nvhpc.rs index a1fad1878..48a656686 100644 --- a/src/compiler/nvhpc.rs +++ b/src/compiler/nvhpc.rs @@ -340,6 +340,13 @@ mod test { path: "foo.o".into(), optional: false } + ), + ( + "d", + ArtifactDescriptor { + path: "foo.o.d".into(), + optional: false + } ) ); assert_eq!( diff --git a/tests/xcode/main.cpp b/tests/xcode/main.cpp new file mode 100644 index 000000000..e371aa940 --- /dev/null +++ b/tests/xcode/main.cpp @@ -0,0 +1,6 @@ +#include + +int main(int argc, const char * argv[]) { + std::cout << "Hello, World!\n"; + return 0; +} diff --git a/tests/xcode/sccache.xcconfig b/tests/xcode/sccache.xcconfig new file mode 100644 index 000000000..f637a79cb --- /dev/null +++ b/tests/xcode/sccache.xcconfig @@ -0,0 +1,3 @@ +CC=$(SRCROOT)/wrapper.sh +CLANG_ENABLE_MODULES=NO +COMPILER_INDEX_STORE_ENABLE=NO diff --git a/tests/xcode/xcode-test.xcodeproj/project.pbxproj b/tests/xcode/xcode-test.xcodeproj/project.pbxproj new file mode 100644 index 000000000..22e869678 --- /dev/null +++ b/tests/xcode/xcode-test.xcodeproj/project.pbxproj @@ -0,0 +1,279 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 63; + objects = { + +/* Begin PBXBuildFile section */ + 9D52B00E2CABDB80008CF5FD /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9D52B00D2CABDB80008CF5FD /* main.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9D52B0012CABDB40008CF5FD /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 9D52B0032CABDB40008CF5FD /* xcode-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "xcode-test"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9D52B00D2CABDB80008CF5FD /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9D52B0002CABDB40008CF5FD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9D52AFFA2CABDB40008CF5FD = { + isa = PBXGroup; + children = ( + 9D52B00D2CABDB80008CF5FD /* main.cpp */, + 9D52B0042CABDB40008CF5FD /* Products */, + ); + sourceTree = ""; + }; + 9D52B0042CABDB40008CF5FD /* Products */ = { + isa = PBXGroup; + children = ( + 9D52B0032CABDB40008CF5FD /* xcode-test */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 9D52B0022CABDB40008CF5FD /* xcode-test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9D52B00A2CABDB40008CF5FD /* Build configuration list for PBXNativeTarget "xcode-test" */; + buildPhases = ( + 9D52AFFF2CABDB40008CF5FD /* Sources */, + 9D52B0002CABDB40008CF5FD /* Frameworks */, + 9D52B0012CABDB40008CF5FD /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "xcode-test"; + packageProductDependencies = ( + ); + productName = "xcode-test"; + productReference = 9D52B0032CABDB40008CF5FD /* xcode-test */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9D52AFFB2CABDB40008CF5FD /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1600; + TargetAttributes = { + 9D52B0022CABDB40008CF5FD = { + CreatedOnToolsVersion = 16.0; + }; + }; + }; + buildConfigurationList = 9D52AFFE2CABDB40008CF5FD /* Build configuration list for PBXProject "xcode-test" */; + compatibilityVersion = "Xcode 12.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 9D52AFFA2CABDB40008CF5FD; + minimizedProjectReferenceProxies = 1; + productRefGroup = 9D52B0042CABDB40008CF5FD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 9D52B0022CABDB40008CF5FD /* xcode-test */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 9D52AFFF2CABDB40008CF5FD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9D52B00E2CABDB80008CF5FD /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 9D52B0082CABDB40008CF5FD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 11.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 9D52B0092CABDB40008CF5FD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 11.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + }; + name = Release; + }; + 9D52B00B2CABDB40008CF5FD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 9D52B00C2CABDB40008CF5FD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9D52AFFE2CABDB40008CF5FD /* Build configuration list for PBXProject "xcode-test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9D52B0082CABDB40008CF5FD /* Debug */, + 9D52B0092CABDB40008CF5FD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9D52B00A2CABDB40008CF5FD /* Build configuration list for PBXNativeTarget "xcode-test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9D52B00B2CABDB40008CF5FD /* Debug */, + 9D52B00C2CABDB40008CF5FD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9D52AFFB2CABDB40008CF5FD /* Project object */; +}