Why does xcodebuild fail when trying to link to test target? - objective-c

I have an Objective-C Xcode project. Previously, there were no test targets in this project. We added a Swift-based test target and a few basic tests. The project continues to build from the Xcode GUI just fine. However, building from the command line fails when trying to link the test target.
% xcodebuild -project Foo.xcodeproj -scheme Foo -configuration AdHoc -sdk iphoneos build
...output...
The following build commands failed:
Ld /Users/mluton/Library/Developer/Xcode/DerivedData/Foo-hkljicipwnivteazylcxtobonsbc/Build/Intermediates/Foo.build/AdHoc-iphoneos/FooTests.build/Objects-normal/armv7/FooTests normal armv7
Ld /Users/mluton/Library/Developer/Xcode/DerivedData/Foo-hkljicipwnivteazylcxtobonsbc/Build/Intermediates/Foo.build/AdHoc-iphoneos/FooTests.build/Objects-normal/arm64/FooTests normal arm64
Running the Ld command manually results in this...
ld: file not found: /Users/mluton/Library/Developer/Xcode/DerivedData/Foo-hkljicipwnivteazylcxtobonsbc/Build/Intermediates/Foo.build/AdHoc-iphoneos/FooTests.build/Objects-normal/armv7/FooTests
If I navigate to that directory I see the file is indeed not there. I do see bunch of AFNetworking related files along with FooTest* files. Most have extensions like .d, .dia, and .o. But there's no FooTests which is what the linker is looking for.
If I edit the 'Foo' scheme I see there are two targets in the Build item. Foo and FooTests. If I uncheck everything associated with FooTests then the command line build will work fine.
Has anyone else tried this and run into the same problem? Am I missing a build setting somewhere? Am I asking for trouble by trying to do unit tests for an Objective-C project in Swift?

Related

libclang_rt.asan_osx_dynamic.dylib in release builds

I just noticed that libclang_rt.asan_osx_dynamic.dylib is in the release build of my macOS app's Contents/Frameworks/ directory. I was under the impression that the address sanitizer is a debug feature, so I was surprised to see this. I'm using xcodebuild in a custom build script to generate the release build of the app.
2 questions:
Is it wrong for that dylib to be in release builds?
How do I prevent Xcode from including it?
You're right, you should not ship your app with runtime sanitizers enabled, they cost unnecessary performance and are often only targeting a small range of supported macOS versions.
But as far as I know, they're not included if you do the preferred release process of creating an archive (Product > Archive). I'm not aware of enabling them other than the schemes, and here they shouldn't affect your archive builds. So in case you're currently just building in Xcode and try to ship the resulting app, that's not what you should ship.
after investigation, it seems to be an issue with xcodebuild's caching. I have a script that analyzes, builds, bundles, and uploads the app to our content server. At the start of the script it would run the static analyzer:
xcodebuild analyze -project "$SCRIPT_DIR/Redacted.xcodeproj" -destination generic/platform=macOS -scheme Redacted -configuration Release CONFIGURATION_BUILD_DIR="$BUILD_DIRECTORY" ...etc...
later it would build the project:
xcodebuild -project "$SCRIPT_DIR/REDACTED.xcodeproj" -target REDACTED -target REDACTED -target REDACTED -parallelizeTargets -destination generic/platform=macOS -configuration Release CONFIGURATION_BUILD_DIR="$BUILD_DIRECTORY" build ...etc...
the second xcodebuild was reusing artifacts created by the first xcodebuild, which caused the address sanitizer dylib to be included in the release build of the app.
To fix it, I made the script delete the $BUILD_DIRECTORY after the static analysis.

xcodebuild archive failing on Xcode 13.x due to resolving to wrong target header

I have this project with multiple iOS targets. Each target has its own AppDelegate.h and AppDelegate.m which inherits from either AppDelegateBase or AppDelegateServiceBase. I am using Xcode 13.4.1 - the build works fine but archive fails. For Xcode 12.x, this works just fine.
The moment I try to archive, it resolves to wrong header from a different target but same name and naturally gives error because of difference in imports.
Any idea how to fix this?
I use xcodebuild -project client/Onyz.xcodeproj -scheme IQW -configuration DEBUG -sdk iphoneos15.5 archive … this gives me error as the path for a file referring to AppDelegate resolves to target IMW (which is the other target). Part of logs are below. Initially this problem was extending to build command as well, but changing from -target to -scheme fixed it. This pattern of failure holds across xcodebuild and Xcode but limited to 13 and above.
In file included from /Volumes/ZX_2TB_SSD/j1/workspace/Onyz/client/iOS/WebBrowserMenuViewController.m:19: In file included from /Volumes/ZX_2TB_SSD/j1/workspace/Onyz/client/iOS/Targets/IMW/AppDelegate.h:10: In file included from /Volumes/ZX_2TB_SSD/j1/workspace/Onyz/client/iOS/AppDelegateServiceBase.h:20: In file included from /Volumes/ZX_2TB_SSD/j1/workspace/Onyz/client/iOS/SDK/AdSupport/AotAdWindow.h:10: /Volumes/ZX_2TB_SSD/j1/workspace/Onyz/client/iOS/SDK/AdSupport/AotAdNetworkManager.h:13:9: fatal error: 'GoogleMobileAds/GoogleMobileAds.h' file not found #import <GoogleMobileAds/GoogleMobileAds.h>
On 2nd line - instead of IMW, it should be IQW and after that the rest of header resolution chain will change.

"Use of undeclared identifier 'strchr'" when building in Xcode

My Objective-C project has compiled fine up til now either in the Xcode IDE or using the following script lines:
xcodebuild -scheme ObjCHelper -sdk iphonesimulator -configuration Debug -xcconfig ./ObjCHelper.xcconfig clean build
echo "Built ObjCHelper for simulator"
xcodebuild -scheme ObjCHelper -sdk iphoneos -configuration Debug -xcconfig ObjCHelper.xcconfig clean build
echo "Built ObjCHelper for iPhone"
(similar for Release).
After upgrading to Xcode 12.5 (12E262), I now get many errors of the above kind. Here is a sample from the build output:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cstring:77:9: error: no member named 'strncmp' in the global namespace
using ::strncmp;
~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cstring:78:9: error: no member named 'strcoll' in the global namespace
using ::strcoll;
~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cstring:79:9: error: no member named 'strxfrm' in the global namespace
using ::strxfrm;
~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cstring:82:9: error: no member named 'strcspn' in the global namespace
using ::strcspn;
~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
Both the simulator and iphoneos builds fail in the same way.
It seems that part of the C++ SDK can't be found since the upgrade - how can I best mend this?
I've tried deinstalling Xcode and reinstalling it, but the problem was the same.
Edit: It builds OK in Xcode 12.5 on a colleague's Mac. I tried taking the version back to 12.3 anyway, but the problem is still there.
The Framework and Header Search paths are set as follows:
When I uninstalled and reinstalled Xcode, I deleted Application/Xcode.app. As far as I understand, the toolchains are here, in Contents/Developer/Toolchains. If I've understood correctly, Xcode should not be searching for C++ files outside this location?

XCode 4, ParseKit and Archive Target

I'm trying to archive an iPad application that used ParseKit. I'm able to run the app fine, utilizing ParseKit, for any build using the Debug Configuration (ie, Run on device / simulator ana analyze.) When I use the Release Configuration, however, I get the following linker error:
ld: library not found for -lparsekit
collect2: ld returned 1 exit status
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2 failed with exit code 1
I had the same error. The fix for me was to select:
ParseKit.xcodeproj (subproject within my project)
-> Target: ParseKitMobile
-> Build Settings
-> Product Name
...and change the name from 'parsekit' to 'libparsekit'. Curious that this is necessary for XCode4, but it's now working for me at least.
Check your flags in your release target: your debug and release builds will probably have different compiler flags set. In XCode4, go into your target's build settings and look for the "Other Linker Flags" section. You will hopefully find your release linker flags don't have a '-lparsekit' flag.

Error "Couldn't discover the 'ccc-analyzer'" when running scan-build

I'm triying to find leaks in my project chibi-ORM using the tool of scan-build as suggested in other threads.
But when run from the terminal:
/Users/mamcx/Downloads/checker-0.138/scan-build -k -V xcodebuild
I get this:
009-01-13 10:33:18.296 xcodebuild[14025:4213] Warning: Couldn't discover the 'ccc-analyzer' compiler's built-in search paths and preprocessor definitions for language dialect 'objective-c'. This may lead to indexing issues.
Compiler: /Users/mamcx/Downloads/checker-0.138/ccc-analyzer
Reason: gcc-4.0: installation problem, cannot exec '/Developer/usr/bin/arm-apple-darwin9-gcc-4.0.1': No such file or directory
However, I can build & debug just fine from the XCode Ide. This is a problem with this tool or something wrong on my side?
There's no need to change the project, just add the -sdk flag to the xcodebuild command, for example:
scan-build -k -V xcodebuild -configuration Debug -sdk iphonesimulator2.0
You can change the 2.0 to be 2.1, 2.2, 2.2.1, or 3.0 to match your target SDK.
the build is failing due to code signing reasons
the fix for iphone apps would be to just go to the project’s properties and set the “Base SDK” to “Simulator - iPhone OS 2.1″ rather than “Device”
check in your case what it would be
What I did to get this to work was to create a new build configuration (which was a dupe of my debug config), which I called Clang, then did the following in the project settings:
set "base SDK" to "Simulator - iPhone OS x.xx"
set Code signing Identity to - "Don't Code Sign"
then, when I run scan-build I do:
scan-build xcodebuild -configuration Clang
(obviously if you named your new build config something different use that name there).
Then it all worked fine and found no bugs in my code (except one false positive) :-)
Also, make sure you do a clean before each scan-build with:
xcodebuild -configuration Clang clean
Otherwise scan-build won't scan the files that have already been built.
Make sure that you can first run xcodebuild on the command-line for your project. In my case I discovered that my project was doing the release build by default and was trying to build for the device. Xcode must add some magic to make it work with certificates because I got the same error messages.
Once I explicitly told it to build with the Debug configuration all worked well. So you may have to run CLang/LLVM with scan-build xcodebuild -configuration Debug.