RSS for tag

Find the path to a macOS SDK version on disk using the xcselect function.

Posts under xcselect tag

5 Posts
Sort by:






xcrun/xcodebuild command hangs after installing xcode 16 beta & iOS 18 beta
Hello, The issues over new Xcode major version beta always drive me crazy around this time of the year. This year we are trying to install both Xcode 15.x & 16 beta on the same mac with Sonoma 14.5, along with all supported iOS/tvOS/watchOS/xrOS simulators available including beta via dmgs distributed on Apple Developer Downloads. After setups, xcrun simctl related commands or xcodebuild (actually carthage bootstrap) commands hang much longer than usual. Happens both on M1 mac mini 16GB ram and Intel i7 mac mini 2018 32GB ram. Rebooting mac, killing processes like CoreSimulatorService, Xcode-related ones or simdiskimaged seemed never helpful. We found that simdiskimaged process tops over 440% of CPU% on Activity Monitor when hanging. It takes over 2m 30s to execute only simple command like xcrun simctl list, whether or not using Xcode 16 beta. (same thing happens on DEVELOPER_DIR=Xcode 15.4 too) What is weird is: opening Xcode on GUI also hangs (Not Responding) but if I force quit it and re-execute, this symptom would be gone after opening Simulator.app on GUI. Anyone who suffered from this kind of behavior? as a iOS CI maintainer? Should I file FBA which will be checked as 'normal behavior'?
Running Developer Tools from a Sandboxed App
I’ve talked about this a bunch of times here on DevForums but, reviewing those posts today, I realised that they’re quite fragmented. This post is my attempt to create a single post that collects together all the bits. If you have questions or comments, please put them in a new thread. Tag it with App Sandbox so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Running Developer Tools from a Sandboxed App If you attempt to run a developer tool, like otool, from a sandboxed app, it fails with an error like this: xcrun: error: cannot be used within an App Sandbox. In this case I was trying to run /usr/bin/otool directly, so how did xcrun come into it? Well, the developer tools that come pre-installed on macOS, like otool, are actually trampolines that use xcrun to bounce to the the real tools within Xcode. Specifically, xcrun defaults to the tools within the currently selected Xcode or Command Line Tools package. So, if you have Xcode installed in the usual place and are using it for your currently selected tools, the actual sequence is /usr/bin/otool, which runs xcrun, which runs /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool. The user can change the currently selected tools with xcode-select. You can get around this problem by running otool from within Xcode. This skips the first two steps, allowing the tool to run. However, there are some serious problems here. The first is that there’s no guarantee that the user has Xcode installed, or that they want to use that specific Xcode. They might have the Command Line Tools package installed. Or they might prefer to store Xcode somewhere outside of the Applications directory. You can get around this by running xcode-select with the --print-path argument: % xcode-select --print-path /Applications/Xcode.app/Contents/Developer However, that results in two more problems: xcode-select prints the root of the Developer directory. The location of, say, otool within that directory isn’t considered API. As a sandboxed app, you might not have access to the path returned. That second point deserves a deeper explanation. To understand this, you’ll need to understand the difference between your static and dynamic sandbox. I talk about this in On File System Permissions. Running otool from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool works because /Applications is in the sandbox’s built-in allowlist. This is part of your static sandbox, so you can run executables from there. But what happens if the user’s selected Xcode is in a different directory? (Personally, I keep numerous copies of Xcode in ~/XcodeZone.) That might not be part of your static sandbox so, by default, you won’t be able to run tools from it. For normal files you can dynamically extend your sandbox to allow this, for example, by presenting a standard open panel. However, this doesn’t work for executable access. There is currently no way to get a dynamic sandbox extension that grants executable access. On File System Permissions has a link to a post that explains this in detail. Finally, there’s a big picture concern: Does the tool actually work when run in a sandbox? Remember, when a sandboxed app runs a command-line tool like this, the tool inherits the app’s sandbox. For more about the mechanics of that, see the documentation linked to by On File System Permissions. For a simple tool, like otool, you can reasonably assume that the tool will work in a sandbox. Well, you have to make sure that any path arguments you pass in point to locations that the sandbox allows access to, but that’ll usually do the trick. OTOH, a complex tool, like say the Swift compiler, might do things that don’t work in the sandbox. Moreover, it’s possible that this behaviour might change over time. The tool might work in a sandbox today but, sometime in the future, an updated tool might not. So what should you do? The only approach I’m prepared to actively recommend is to not sandbox your app. That avoids all of the issues discussed above. If you must sandbox your app then I see two paths forward. The first is to just live with the limitations discussed above. Specifically: You can only use a tool that’s within your static sandbox. For complex tools, you run the risk of the tool not working in the future. The alternative is to embed the tool within your app. This is only feasible if the tool is open source with a licence that’s compatible with your plans. That way you can build your own copy of the tool from the source. Of course this has its own drawbacks: It increases the size of your app. You can only run that version of the tool, which might not be the version that the user wants.
Feb ’24
Investigating Third-Party IDE Integration Problems
I regularly see questions from folks who’ve run into problems with their third-party IDE on macOS. Specifically, the issue is that their IDE is invoking Apple’s command-line tools — things like clang and ld — and that’s failing in some way. This post collects my ideas on how to investigate, and potentially resolve, issues like this. If you have any questions or comments, please put them in a new thread here on DevForums. Tag it appropriately so that I see it. Good tags include Compiler, Linker, LLVM, and Command Line Tools. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Investigating Third-Party IDE Integration Problems Many third-party IDEs rely on Apple tools. For example, the IDE might run clang to compile C code or run ld to link object files. These IDEs typically don’t include the tools themselves. Rather, they rely on you to install Xcode or Apple’s Command Line Tools package. These are available at Apple > Developer > Downloads Occasionally I see folks having problems with this. They most typically report that basic stuff, like compiling a simple C program, fails with some mysterious error. If you’re having such a problem, follow the steps below to investigate it. IMPORTANT Some IDEs come with their own tools for compiling and linking. Such IDEs are not the focus of this post. If you have problems with an IDE like that, contact its vendor. Select Your Tools macOS has a concept of the current command-line tools. This can either point to the tools within Xcode or to an installed Command Line Tools package. To see which tools are currently selected, run xcode-select with the --print-path argument. This is what you’ll see if you have Xcode installed in the Applications folder: % xcode-select --print-path /Applications/Xcode.app/Contents/Developer Note All of the tools I discuss here are documented in man pages. If you’re not familiar with those, see Reading UNIX Manual Pages. And this is what you’ll see with a Command Line Tools package selected. % xcode-select --print-path /Library/Developer/CommandLineTools There are two common problems with this: It points to something you’ve deleted. It points to something unexpected. Run the command above to see the current state. If necessary, change the state using the --switch option. For example: % xcode-select --print-path /Applications/Xcode.app/Contents/Developer % clang -v Apple clang version 14.0.3 (clang-1403. … % sudo xcode-select --switch ~/XcodeZone/Xcode-beta.app % clang -v Apple clang version 15.0.0 (clang-1500.0.38.1) … I have Xcode 14.3 in the Applications foledr and thus clang runs Clang 14.0.3. I have Xcode 15.0b5 in ~/XcodeZone, so switching to that yields Clang 15.0.0. It’s possible to run one specific command with different tools. See Select Your Tools Temporarily, below. Run a Simple Test A good diagnostic test is to use the selected command-line tools to compile a trivial test program. Consider this C [1] example: % cat hello.c #include <stdio.h> int main(int argc, char ** argv) { printf("Hello Cruel World!\n"); return 0; } % clang -o hello hello.c % ./hello Hello Cruel World! IMPORTANT If possible, run this from Terminal rather than, say, over SSH. You may need to expand this test program to exercise your specific case. For example, if your program is hitting an error when it tries to import the Core Foundation framework, add that import to your test program: % cat hello.c #include <stdio.h> #include <CoreFoundation/CoreFoundation.h> int main(int argc, char ** argv) { printf("Hello Cruel World!\n"); return 0; } When you compile your test program, you might see one of these results: Your test program compiles. Your test program fails with a similar error. Your test program fails with a different error. I’ll explore each case in turn. [1] For a C++ example, see C++ Issues, below. If your test program compiles… If your test program compiles from the shell, that proves that your basic command-line tools setup is fine. If the same program fails to compile in your IDE, there’s something IDE-specific going on here. I can’t help you with that. I recommend that you escalate the issue via the support channel for your IDE. If your test program fails with a similar error… If your test program fails with an error similar to the one you’re seeing in your IDE, there are two possibilities: There’s a bug in your test program’s code. There’s an environmental issue that’s affecting your command-line tools setup. Don’t rule out the first possibility. I regularly see folks bump into problems like this, where it turns out to be a bug in their code. For a specific example, see C++ Issues, below. Assuming, however, that your test program’s code is OK, it’s time to investigate environmental issues. See Vary Your Environment, below. If your test program fails with a different error… If your test program fails with a different error, look at the test program’s code to confirm that it’s correct, and that it accurately reflects the code you’re trying to run in your IDE. Vary Your Environment If your test program fails with the same error as you’re seeing in your IDE, and you are sure that the code is correct, it’s time to look for environmental factors. I typically do this with the steps described in the next sections, which are listed from most to least complex. These steps only tell you where things are going wrong, not what is going wrong. However, that’s often enough to continue the investigation of your issue. Vary Your Shell Try running your commands in a different shell. macOS’s default shell is zsh. Try running your commands in bash instead: % bash … bash-3.2$ clang -o hello hello.c bash-3.2$ ./hello Hello Cruel World! Or if you’ve switched your shell to bash, try it in zsh. Vary Your User Account Some problems are caused by settings tied to your user account. To investigate whether that’s an issue here: Use System Settings > Users & Groups to create a new user. Log in as that user. Run your test again. Vary Your Mac Some problems are system wide, so you need to test on a different Mac. The easiest way to do that is to set up a virtual machine (VM) and run your test there. Or, if you have a separate physical Mac, run your test on that. Vary Your Site If you’re working for an organisation, they may have installed software on your Mac that causes problems. If you have a Mac at home, try running your test there. It’s also possible that your network is causing problems [1]. If you have a laptop, try taking it to a different location to see if that changes things. [1] I rarely see this when building a simple test program, but it do see it with other stuff, like code signing. C++ Issues If you’re using C++, here’s a simple test you can try: % cat hello.cpp #include <iostream> int main() { std::cout << "Hello Cruel World!\n"; } % clang++ -o hello hello.cpp % ./hello Hello Cruel World! A classic problem with C++ relates to name mangling. Consider this example: % cat hello.c #include <stdio.h> #include "hello-core.h" int main(int argc, char ** argv) { HCSayHello(); return 0; } % cat hello-core.cpp #include "hello-core.h" #include <iostream> extern void HCSayHello() { std::cout << "Hello Cruel World!\n"; } % cat hello-core.h extern void HCSayHello(); % clang -c hello.c % clang++ -c hello-core.cpp % clang++ -o hello hello.o hello-core.o Undefined symbols for architecture x86_64: "_HCSayHello", referenced from: _main in hello.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) The issue here is that C++ generates a mangled name for HCSayHello: % nm hello-core.o | grep HCSayHello 0000000000000000 T __Z10HCSayHellov whereas C uses the non-mangled name: % nm hello.o | grep HCSayHello U _HCSayHello The fix is an appropriate application of extern "C": % cat hello-core.h extern "C" { extern void HCSayHello(); }; Select Your Tools Temporarily Sometimes you want to temporarily run a command from a particular tools package. To continue my earlier example, I currently have Xcode 14.3 installed in the Applications folder and Xcode 15.0b5 in ~/XcodeZone. Xcode 14.3 is the default but I can override that with the DEVELOPER_DIR environment variable: % clang -v Apple clang version 14.0.3 (clang-1403. … % DEVELOPER_DIR=~/XcodeZone/Xcode-beta.app/Contents/Developer clang -v Apple clang version 15.0.0 (clang-1500.0.38.1) …
Jul ’23
Cmake and ninja still referencing old SDK after upgrading to XCode command line tools 14.3.1
I was on 14.3 and building my project fine. After upgrading to XCode command line tools 14.3.1 (MacOS SDK 13.3), I'm unable to build my project any more: /Library/Developer/CommandLineTools/usr/bin/make build BUILD_DIR=debug -j 16 cmake --build _build/debug -j 16 ninja: error: '/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/lib/libz.tbd', needed by 'project1', missing and no known rule to make it make[1]: *** [build] Error 1 make: *** [debug] Error 2 NOte that the error message shows it's looking for libz.tbd still under the old SDK MacOSX13.1.sdk, while the just installed version is MacOSX13.3.sdk $ ls -lht /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd lrwxr-xr-x 1 root wheel 10B Jun 11 21:29 /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/lib/libz.tbd -> libz.1.tbd Reinstalling cmake and ninja didn't help. I also tried reverting to the previous veresion by downloading and installing XCode command line tools 14.3, but then even more problems were found that many tools/libs were referring to MacOSX13.3.sdk instead of MacOSX13.1.sdk and reinstalling them didn't help. Can someone help please?
Sep ’23