Re: Dependency Checking Woes - Successful Workaround
Re: Dependency Checking Woes - Successful Workaround
- Subject: Re: Dependency Checking Woes - Successful Workaround
- From: Rush Manbert <email@hidden>
- Date: Fri, 17 Mar 2006 14:25:36 -0800
Rush Manbert wrote:
Rush Manbert wrote:
Scott Fraser wrote:
On Mar 17, 2006, at 03:44 AM, email@hidden wrote:
Perhaps something similar can be done in your case: have another
target that does nothing but touch one of your source files (a small
one, preferably) and have your main target depend on that. Every time
you press build, it should build one small file (mine is a two line
file containing two global variables, the date--in a particular
format--and the build number) and then link with your modified
libraries.
I used to do something similar in a multi-step MPW build script. The
intermediate target could touch, not one of your source files, but a
fake, empty source file that is part of your App target, and whose
only job is to be touched. Sounds like it should work.
Thank you Scott and Steve for your responses. That's a clever workaround.
I have been thinking about this approach for a bit and I think I can
almost get what I really want (relink when the library is rebuilt, not
every time) by doing this:
Add a Run Script build phase to the end of my library target. The
script would just touch a file called MyLibBuildProxy.cpp that lives
in the MyLib project directory. The script definition panel specifies
no output files, so it runs every time. This file is NOT added to the
library project, it just gets touched every time the library builds
(in either Debug or Release).
I add MyLib/MyLibBuildProxy.cpp to the MyApp target.
Every time MyLib gets rebuilt, the file gets touched. This triggers a
rebuild of MyApp. The remaining issue is that the build proxy file
can't be specific to the build configuration. Any time the file gets
touched it triggers a recompile and link for all build configurations
of the app target. If I could make the proxy files be specific to the
build configuration, I would probably get the same effective behavior.
If I changed a file in the library project, I need to rebuild both
versions of the library, so would need to relink both versions of the
app.
I have added this to one of my app/library project pairs and it works
as described. Now I have more work to do, because my top level library
depends on two other libraries that I build. Adding all this is going
to be a tedious exercise.
It turns out that this workaround is not more selective than yours. I
neglected to test the case where I just build MyApp twice in succession.
When I do that, the file gets touched by MyLib, even though nothing else
is done in that project. This ALWAYS triggers a relink in MyApp.
That's not the worst thing in the world. Better to link when you don't
need it than to not link when you do need it, but it's really annoying,
and can get to be a big pain if link times get long.
I'm going to keep tinkering with this. The script could do a Make that
only touches the file if either of the library versions have been
rebuilt. I guess I can just do that in the script too. Sigh.
I have a workaround that exhibits the correct behavior. It works like
the original, but you can't just touch the build proxy file.
My script that touches the build proxy file looks like this:
# If the library being built is newer than the Build Proxy
# file, touch the latter
find -d ${BUILT_PRODUCTS_DIR} -type f -name lib${PRODUCT_NAME}.a -newer
./MyLibBuildProxy.cpp -print -exec touch ./MyLibBuildProxy.cpp \;
This will only touch the build proxy file if the library we are
currently building (would work for other types of output as well) is
newer than the build proxy file. The -print is not required. It just
makes it easier to see when the file gets touched.
I first tried the logic the other way around (find the build proxy file
and only exec if it is not newer than the library) but that has a race
condition and you end up touching the proxy file twice if you do back to
back builds where nothing changes in between.
The next problem to overcome was the fact that in my real case, MyLib
depends on two other libraries. Call then MyUtils and MyExceptions. The
MyUtils library also depends on the MyExceptions library. When I
extended the scheme to all of the libraries, I ended up with three proxy
files, MyExceptionsBuildProxy.cpp, MyUtilsBuildProxy.cpp, and
MyLibBuildProxy.cpp. The MyExceptionsBuildProxy.cpp file was included in
the MyUtils project AND in the MyLib project, because both libraries
link against the MyExceptions library. When I was trying to decide what
to put in the build proxy files, I first tried:
static int MyLibBuildProxy;
and similar, but that generates a warning about an unused variable, and
I have a rule against warnings (and treat them as errors).
So my next attempt was to put this into the proxy file (adjusted for the
lib name):
#include <stdio.h>
void MyLibBuildProxy (void)
void MyLibBuildProxy (void)
{
printf ("MyLibBuildProxy is linked in\n");
}
I figured this would be okay. Fast compile, puts a string in the
executable that I can find, etc.
The problem comes when you link MyLib, because you end up with two
definitions for MyExceptionsBuildProxy(). The build dies there.
So the final solution was to put the entire thing inside #if 0/#endif.
The compiler has no trouble with this at all. I'll probably put
something inside the #if 0/#endif that's generic. I don't know if the
compiler would like a file that looks like:
#if 0
#endif
with nothing else in it, so I probably won't go that far.
It's a hack, but it works around the Xcode shortcomings, and it's not
too hard to manage as you create more libraries. I am, of course, open
to suggestions and improvements.
- Rush
_______________________________________________
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