String manipulation in Build Rule output files field
String manipulation in Build Rule output files field
- Subject: String manipulation in Build Rule output files field
- From: BJ Homer <email@hidden>
- Date: Fri, 19 Feb 2010 10:39:31 -0700
Hi all.
I'm working on a project that involves a few automatically generated source files. We're using Ragel (a parser generator). Instead of manually generating the files and adding the generated files to the project, I'd like to be able to have Xcode automatically generate the .cpp files from the .rl files. I understand that build rules (in the "Rules" tab of a build target) are intended for precisely this situation.
I've created a rule that matches .rl files. It runs the ragel command-line tool to generate the .cpp file as follows:
#!/usr/bin/bash
ragel -o "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.cpp" "${INPUT_FILE_PATH}"
The output file on the rule is naturally set to $(DERIVED_FILES_DIR)/$(INPUT_FILE_BASE).cpp as well. For the most part, this is working great.
However, I've run into a problem. These files are ultimately compiled down into a static library. Among the files being compiled are html/parser.rl and xml/parser.rl. (That is, both files are called parser.rl, but are in different directories.) Unfortunately, that means that the generated .cpp files end up overwriting each other in the DerivedSources directory. The simplest solution, of course, would be to rename the parser.rl files to be unique. Unfortunately, this is for a cross-platform library, and I don't have much control over the code. The Windows and Linux build processes already handle this situation just fine, so if I can get it to work without renaming the files, it would be more pleasant for everyone involved.
A simple solution to this problem would be to prepend the parent directory name, so that the generated files are called html_parser.cpp and xml_parser.cpp. This is fairly easy to do in the script itself:
#!/usr/bin/bash
ragel -o "${DERIVED_FILES_DIR}/$(/usr/bin/basename ${INPUT_FILE_DIR})_${INPUT_FILE_BASE}.cpp" "${INPUT_FILE_PATH}"
However, I can't use /usr/bin/basename in the output files portion of the rule definition. As a result, Xcode doesn't know about the new file, and it never gets compiled. I've looked at the various supported environment variables[1] for build rules, and nothing appears to work. I tried using the full path instead of just using base name (ragel -o "${DERIVED_FILES_DIR}${INPUT_FILE_PATH}.cpp, which would produce DerivedSources/Users/myuser/Projects/nameOfProject/Source/html/parser.cpp) , but that doesn't change the filename itself; it just nests it further inside the DerivedSources folder.
Further, I discovered that if I tell Xcode that the file type of .rl files is "sourcecode" instead of "text", I can add per-file compiler flags. These are made available in the OTHER_INPUT_FILE_FLAGS environment variable. Unfortunately, while these are available inside the script, this variable is not defined when processing the output files, so it still doesn't solve my problem.
So, my questions:
1) Is there a way to perform string substitution in the "output files" portion of a build rule, such that I could use INPUT_FILE_PATH, but turn all '/' into '_'?
2) Is there some other way to solve this problem without renaming the .rl files?
Thanks for your help,
-BJ Homer
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden