From 2e34c6f82050ebdf89f46831598659eaf2f26348 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Tue, 2 Jan 2024 14:33:53 +0800 Subject: [PATCH 1/6] fix: implement proper download limit for uTP (#6416) * fix: return read buffer size in libutp read buffer size callback * refactor: clamp amount of data processed in `can_read_wrapper()` * chore: housekeeping * refactor: call `utp_read_drained()` in on-read callback so that uTP acks can be sent out in a more timely fashion (cherry picked from commit 5000edef0191e5dc4ea5b8dec37da11510a08c16) --- libtransmission/peer-io.cc | 42 ++++++++++++++++++---------------- libtransmission/peer-io.h | 2 ++ libtransmission/peer-socket.cc | 12 +++------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 65e39ca92..2c528806f 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -350,7 +350,13 @@ void tr_peerIo::can_read_wrapper() auto done = bool{ false }; auto err = bool{ false }; - while (!done && !err) + // In normal conditions, only continue processing if we still have bandwidth + // quota for it. + // + // The read buffer will grow indefinitely if libutp or the TCP stack keeps buffering + // data faster than the bandwidth limit allows. To safeguard against that, we keep + // processing if the read buffer is more than twice as large as the target size. + while (!done && !err && (read_buffer_size() > RcvBuf * 2U || bandwidth().clamp(TR_DOWN, read_buffer_size()) != 0U)) { size_t piece = 0; auto const old_len = read_buffer_size(); @@ -358,17 +364,14 @@ void tr_peerIo::can_read_wrapper() auto const used = old_len - read_buffer_size(); auto const overhead = socket_.guess_packet_overhead(used); - if (piece != 0 || piece != used) + if (piece != 0) { - if (piece != 0) - { - bandwidth().notifyBandwidthConsumed(TR_DOWN, piece, true, now); - } + bandwidth().notifyBandwidthConsumed(TR_DOWN, piece, true, now); + } - if (used != piece) - { - bandwidth().notifyBandwidthConsumed(TR_DOWN, used - piece, false, now); - } + if (used != piece) + { + bandwidth().notifyBandwidthConsumed(TR_DOWN, used - piece, false, now); } if (overhead > 0) @@ -722,6 +725,14 @@ void tr_peerIo::utp_init([[maybe_unused]] struct_utp_context* ctx) io->inbuf_.add(args->buf, args->len); io->set_enabled(TR_DOWN, true); io->can_read_wrapper(); + + // utp_read_drained() notifies libutp that this read buffer is empty. + // It opens up the congestion window by sending an ACK (soonish) if + // one was not going to be sent. + if (std::empty(io->inbuf_)) + { + utp_read_drained(io->socket_.handle.utp); + } } return {}; }); @@ -733,16 +744,7 @@ void tr_peerIo::utp_init([[maybe_unused]] struct_utp_context* ctx) { if (auto const* const io = static_cast(utp_get_userdata(args->socket)); io != nullptr) { - // We use this callback to enforce speed limits by telling - // libutp to read no more than `target_dl_bytes` bytes. - auto const target_dl_bytes = io->bandwidth_.clamp(TR_DOWN, RcvBuf); - - // libutp's private function get_rcv_window() allows libutp - // to read up to (UTP_RCVBUF - READ_BUFFER_SIZE) bytes and - // UTP_RCVBUF is set to `RcvBuf` by tr_peerIo::utp_init(). - // So to limit dl to `target_dl_bytes`, we need to return - // N where (`target_dl_bytes` == RcvBuf - N). - return RcvBuf - target_dl_bytes; + return io->read_buffer_size(); } return {}; }); diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index 0d7157bcc..a0c0cd3d6 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -298,8 +298,10 @@ private: filter_.encrypt(buflen, buf); } +#ifdef WITH_UTP void on_utp_state_change(int new_state); void on_utp_error(int errcode); +#endif void close(); diff --git a/libtransmission/peer-socket.cc b/libtransmission/peer-socket.cc index fa45c1cdb..380ed11c6 100644 --- a/libtransmission/peer-socket.cc +++ b/libtransmission/peer-socket.cc @@ -119,15 +119,9 @@ size_t tr_peer_socket::try_read(Buffer& buf, size_t max, tr_error** error) const return buf.add_socket(handle.tcp, max, error); } -#ifdef WITH_UTP - // utp_read_drained() notifies libutp that this read buffer is empty. - // It opens up the congestion window by sending an ACK (soonish) if - // one was not going to be sent. - if (is_utp() && std::empty(buf)) - { - utp_read_drained(handle.utp); - } -#endif + // Unlike conventional BSD-style socket API, libutp pushes incoming data to the + // caller via a callback, instead of allowing the caller to pull data from + // its buffers. Therefore, reading data from a uTP socket is not handled here. return {}; } From d5a555c6bbb95c9d9b9fbe2c6d6e8923b37b6831 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Thu, 4 Jan 2024 01:27:11 +0800 Subject: [PATCH 2/6] fixup! fix: implement proper download limit for uTP (#6416) (#6481) (cherry picked from commit dce0d37130ec6feb4af2f6791b4b87bd4fd44c29) --- libtransmission/peer-io.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 2c528806f..8d57b21e9 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -731,7 +731,7 @@ void tr_peerIo::utp_init([[maybe_unused]] struct_utp_context* ctx) // one was not going to be sent. if (std::empty(io->inbuf_)) { - utp_read_drained(io->socket_.handle.utp); + utp_read_drained(args->socket); } } return {}; From 64b87b376ff225f75ff264e429c347001f1c6653 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Mon, 15 Jan 2024 14:28:50 +0800 Subject: [PATCH 3/6] fix: always schedule uTP ack after receiving a packet (#6508) * fix: always schedule uTP ack after receiving a packet * chore: add comment to explain change (cherry picked from commit 0ce4adf07ce4b6cfabf81e2d027f96197bb9a305) --- libtransmission/peer-io.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 8d57b21e9..68877d22d 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -726,13 +726,10 @@ void tr_peerIo::utp_init([[maybe_unused]] struct_utp_context* ctx) io->set_enabled(TR_DOWN, true); io->can_read_wrapper(); - // utp_read_drained() notifies libutp that this read buffer is empty. + // utp_read_drained() notifies libutp that we read a packet from them. // It opens up the congestion window by sending an ACK (soonish) if // one was not going to be sent. - if (std::empty(io->inbuf_)) - { - utp_read_drained(args->socket); - } + utp_read_drained(args->socket); } return {}; }); From 71904b9de2b0ae23bc2bbf8355d148f7f9fb4762 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Sun, 21 Jan 2024 08:09:28 +0800 Subject: [PATCH 4/6] fix: keep peer io alive inside utp callback (#6507) (cherry picked from commit a1160f15562d72d69382f0ad729cf781683afac5) --- libtransmission/peer-io.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 68877d22d..3c22e4446 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -722,6 +722,11 @@ void tr_peerIo::utp_init([[maybe_unused]] struct_utp_context* ctx) { if (auto* const io = static_cast(utp_get_userdata(args->socket)); io != nullptr) { + // The peer io object can destruct inside can_read_wrapper(), so keep + // it alive for the duration of this code block. This can happen when + // a BT handshake did not complete successfully for example. + auto const keep_alive = io->shared_from_this(); + io->inbuf_.add(args->buf, args->len); io->set_enabled(TR_DOWN, true); io->can_read_wrapper(); From 4a37b979ccc2684f394825ca136838f784c028ad Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Wed, 15 Nov 2023 03:24:18 +0800 Subject: [PATCH 5/6] chore: bump libutp (#6251) (cherry picked from commit cf077bbba08a7da7c85629a2a635211650ec15a9) --- CMakeLists.txt | 14 +++++++------- third-party/libutp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6be895e5a..ffada1f47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,13 @@ string(APPEND TR_PEER_ID_PREFIX "-") set(TR_VCS_REVISION_FILE "${CMAKE_SOURCE_DIR}/REVISION") +## Compiler standard version + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + if(EXISTS ${CMAKE_SOURCE_DIR}/.git) find_package(Git) endif() @@ -594,13 +601,6 @@ endif() unset(CMAKE_FOLDER) -## Compiler standard version - -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - ### Compiler Warnings set(C_WARNING_FLAGS) diff --git a/third-party/libutp b/third-party/libutp index c95738b1a..52645d6d0 160000 --- a/third-party/libutp +++ b/third-party/libutp @@ -1 +1 @@ -Subproject commit c95738b1a6644b919e5b64d3ea9736cfc5894e0b +Subproject commit 52645d6d0fb16009e11d2f84469d2e43b7b6b48a From f8ec54a898a2be8760065822f82501264b16b5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C5=93ur?= Date: Sun, 12 Nov 2023 17:56:22 +0100 Subject: [PATCH 6/6] build: bump pbxproj to C11/C++17 for all targets (#6242) (cherry picked from commit 0f3d1468537eb3f97a622eb4bb4366598b6b33ab) --- Transmission.xcodeproj/project.pbxproj | 33 +++++--------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index f20694f91..2a9c718c7 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -3715,7 +3715,6 @@ 0053D3D40C86774200545606 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -3757,7 +3756,6 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = macosx/Transmission.entitlements; @@ -3787,7 +3785,6 @@ 0053D3D60C86774200545606 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -3808,7 +3805,6 @@ 0053D3D70C86774200545606 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -3833,7 +3829,6 @@ 0053D3D80C86774200545606 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -3856,6 +3851,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; @@ -3882,6 +3878,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = c11; GCC_DYNAMIC_NO_PIC = YES; GCC_ENABLE_PASCAL_STRINGS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -3958,7 +3955,6 @@ 4D18389C09DEC01E0047D688 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -3999,7 +3995,6 @@ 4DDBB71E09E16BF100284745 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4021,7 +4016,6 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = macosx/Transmission.entitlements; @@ -4053,6 +4047,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; @@ -4078,6 +4073,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = c11; GCC_DYNAMIC_NO_PIC = YES; GCC_ENABLE_PASCAL_STRINGS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -4152,6 +4148,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; @@ -4179,6 +4176,7 @@ DEPLOYMENT_POSTPROCESSING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = c11; GCC_DYNAMIC_NO_PIC = YES; GCC_ENABLE_PASCAL_STRINGS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -4222,7 +4220,6 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = macosx/Transmission.entitlements; @@ -4252,7 +4249,6 @@ A250CFED0CDA19680068B4B6 /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4273,7 +4269,6 @@ A250CFEE0CDA19680068B4B6 /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -4314,7 +4309,6 @@ A250CFEF0CDA19680068B4B6 /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4339,7 +4333,6 @@ A250CFF00CDA19680068B4B6 /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4410,7 +4403,6 @@ A2F35BD115C5A0A100EBF632 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch"; @@ -4439,7 +4431,6 @@ A2F35BD215C5A0A100EBF632 /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch"; @@ -4468,7 +4459,6 @@ A2F35BD315C5A0A100EBF632 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; GCC_PREFIX_HEADER = "macosx/QuickLookPlugin/QuickLookPlugin-Prefix.pch"; @@ -4541,7 +4531,6 @@ BEFC1C0A0C07753800B0BB3C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4566,7 +4555,6 @@ BEFC1CF80C07822400B0BB3C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4758,7 +4746,6 @@ C8B27B7C28153F2B00A22B5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4779,7 +4766,6 @@ C8B27B7D28153F2B00A22B5D /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4800,7 +4786,6 @@ C8B27B7E28153F2B00A22B5D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4821,7 +4806,6 @@ C8B27B8D28153F3100A22B5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4842,7 +4826,6 @@ C8B27B8E28153F3100A22B5D /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4863,7 +4846,6 @@ C8B27B8F28153F3100A22B5D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4884,7 +4866,6 @@ C8B27B9E28153F3400A22B5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4905,7 +4886,6 @@ C8B27B9F28153F3400A22B5D /* Release - Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-"; @@ -4926,7 +4906,6 @@ C8B27BA028153F3400A22B5D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = NO; CODE_SIGN_IDENTITY = "-";