3
votes

I'm porting a compiler project to use Automated Reference Counting. I set up the project in Xcode some time ago, and it continues to build and run fine in Xcode 4.6 without ARC. Now I've ported the bulk of it to ARC, but I've found that the Objective-C files generated by Bison and Flex needs to have ARC disabled.

(The specific reason is because YYSTYPE was id the pre-ARC version of my project. I can declare it as __unsafe_unretained id and it will compile, but the ARC-compiled code doesn't put objects in the autorelease pool with the same lifetime that my old non-ARC code did, so it crashes at runtime.)

I can't figure out how to disable ARC for generated files, however. The normal process is that you add the --fno_objc_arc option to the particular Objective-C file in the Build Phases tab. When I try to add that option to the Flex and Bison source files, the build fails because Flex/Bison don't understand the option.

The generated files are in the DerivedSources directory, pointed by the DERIVED_FILE_DIR variable. But they don't appear in the Xcode Project Navigator or Build Phases tab. I can't add them to the project, because the path varies between Debug and Release builds. So I don't know how to apply the --fno_objc_arc to them.

Does anyone have any tips on setting per-file build options for Flex/Bison derived sources in Xcode?

1

1 Answers

3
votes

I figured out a workaround:

Put the Bison/Flex files in a separate Xcode target, and disable ARC on that target. This "Parser" target builds a static library. The Flex- and Bison-generated Objective-C files are compiled within this target. Then make this target a dependency of the main target in the project, so that the latter links with the parser code.

The tricky part is making the Flex- and Bison-generated headers accessible to the main target. One can't mark them as "Public Headers" because they are generated, not added to the project. So you need to add the following build setting to the main target:

USER_HEADER_SEARCH_PATHS = $(CONFIGURATION_TEMP_DIR)/Parser.build/DerivedSources (where "Parser" is the name of the static library target that builds your Bison/Flex files)

This solution is rather brittle, because it hard-codes the name of the target in the build settings. If anyone has a real solution for disabling ARC on derived sources, please post it.