Why did my changes suddenly disappear?

  • Well, actually I know why. I'm looking for a way to avoid it...

    Over the last few weeks I've been fighting with Xcode workspaces, nested
    projects and public header files. I know from looking at places like
    stackoverflow that I'm not the first to this battle. My conclusion in that
    it's either shockingly broken or shockingly badly documented. Either way
    it's shocking.

    That said I did finally get some kind of reasonable behavior when building
    and consuming static libraries. It even works for archive builds and isn't
    particularly onerous to set up.

    But I have an annoying problem. During the build static library public
    headers are copied to a location in the derived data directory.
    Occasionally I end up opening this copy of the header in Xcode (probably by
    right clicking on a type declared in the header and selecting Jump To
    Definition.) I sometimes forget this (Xcode doesn't make it particularly
    obvious that I'm looking at the copy - a slightly different jump bar path
    is the only difference) and make changes to the copy, which are promptly
    overwritten by the next clean build. Annoying, to say the least.

    So I'm looking for possible solutions to this. Ideally Xcode would know to
    open the original and not the copy (somehow) but I would settle for just
    making the copy read only in Xcode as a way to guard against editing it. I
    suppose I could do this with a custom build step.

    Has anyone else found a good way to deal with this?

    Brian
  • On May 22, 2013, at 10:34 , Brian Syme <briansyme...> wrote:

    > But I have an annoying problem. During the build static library public headers are copied to a location in the derived data directory. Occasionally I end up opening this copy of the header in Xcode (probably by right clicking on a type declared in the header and selecting Jump To Definition.) I sometimes forget this (Xcode doesn't make it particularly obvious that I'm looking at the copy - a slightly different jump bar path is the only difference) and make changes to the copy, which are promptly overwritten by the next clean build. Annoying, to say the least.
    >
    > So I'm looking for possible solutions to this. Ideally Xcode would know to open the original and not the copy (somehow) but I would settle for just making the copy read only in Xcode as a way to guard against editing it. I suppose I could do this with a custom build step.

    You shouldn't really be adding files from a derived data directory to your main project. The derived data is (by design, as I understand it) intended to be a throwaway intermediate set of files.

    Instead, add the library project to your main project's workspace, and add the library's product to the main project's Link With Binaries build phase. That way, if you edit any library public headers, you're editing the files in the real library source folder(s). Then Xcode (in effect -- it may take some shortcuts transparent to the build process, in your normal debugging workflow) will re-build the library for you, and recompile main project files that depend on the library header files. Using this approach also allows Xcode to use the appropriate library configuration (Debug, Release, etc) if you switch configurations for the main project.

    If you need to build a distributable library separate from the main project, use Project --> Archive on the library target.
  • > You shouldn't really be adding files from a derived data directory to
    your main project. The derived data is (by design, as I understand it)
    intended to be a throwaway intermediate set of files.

    That's what I thought too. But the xcode build system allows libraries to
    mark headers as private, project or public. The public headers are copied
    to a derived data directory. And this directory is in the default search
    path. So you would think that's the intended use. Maybe I'm missing
    something.

    Your suggestion is what I've ended up doing though in order to work around
    the problem I described. It avoids a few other kinks as well. Apple should
    probably just remove the broken public/private/project header functionality
    - it seems too broken to be useful.

    On Wed, May 22, 2013 at 11:18 AM, Quincey Morris <
    <quinceymorris...> wrote:

    > On May 22, 2013, at 10:34 , Brian Syme <briansyme...> wrote:
    >
    > But I have an annoying problem. During the build static library public
    > headers are copied to a location in the derived data directory.
    > Occasionally I end up opening this copy of the header in Xcode (probably by
    > right clicking on a type declared in the header and selecting Jump To
    > Definition.) I sometimes forget this (Xcode doesn't make it particularly
    > obvious that I'm looking at the copy - a slightly different jump bar path
    > is the only difference) and make changes to the copy, which are promptly
    > overwritten by the next clean build. Annoying, to say the least.
    >
    > So I'm looking for possible solutions to this. Ideally Xcode would know to
    > open the original and not the copy (somehow) but I would settle for just
    > making the copy read only in Xcode as a way to guard against editing it. I
    > suppose I could do this with a custom build step.
    >
    >
    > You shouldn't really be adding files from a derived data directory to your
    > main project. The derived data is (by design, as I understand it) intended
    > to be a throwaway intermediate set of files.
    >
    > Instead, add the library project to your main project's workspace, and add
    > the library's product to the main project's Link With Binaries build phase.
    > That way, if you edit any library public headers, you're editing the files
    > in the real library source folder(s). Then Xcode (in effect -- it may take
    > some shortcuts transparent to the build process, in your normal debugging
    > workflow) will re-build the library for you, and recompile main project
    > files that depend on the library header files. Using this approach also
    > allows Xcode to use the appropriate library configuration (Debug, Release,
    > etc) if you switch configurations for the main project.
    >
    > If you need to build a distributable library separate from the main
    > project, use Project --> Archive on the library target.
    >
    >
  • On May 22, 2013, at 16:04 , Brian Syme <briansyme...> wrote:

    > That's what I thought too. But the xcode build system allows libraries to mark headers as private, project or public. The public headers are copied to a derived data directory. And this directory is in the default search path. So you would think that's the intended use. Maybe I'm missing something.

    The public (and private) headers are copied to the derived data directory because they're a build product, just like object files produced by the compiler. Like object files, that's just an intermediate thing for the build.

    If your search path ends up pointing to a derived directory, you should remove that directory from the search path. If you don't, one unintended consequence is that your main project builds always use that particular build configuration, and don't "switch" automatically when you build a different configuration. For example, you might find that you're debugging with the release version of the library, or that you're releasing your product with a debug version of the library.

    I can't remember the rules for static libraries (I mostly use private frameworks instead), but you may not need anything in the search paths for libraries included in the workspace, so I'd try that first.

    Also IIRC, Xcode 4.6 is better than Xcode 4.5 or earlier at setting up the proper dependency without jumping through hoops. Before 4.6 it seemed easier to end up with the wrong thing. Unfortunately, the way this works isn't very well explained anywhere. In my experience, the best way to configure dependent libraries and frameworks is to use the "+" button in the Link With build phase and choose the library from the list that pops up.
  • > If your search path ends up pointing to a derived directory, you should
    remove that directory from the search path.

    It's the default. Also it's based on xcode build settings, so it changes to
    pick up the right build type - debug, release, archive, etc. I think that
    is the intended design, but the implementation is pretty much broken.

    The scenarios I'm talking about are workspaces and nested projects. I don't
    have some independent project pointing into a random derived data directory
    or anything like that!

    On Wed, May 22, 2013 at 4:21 PM, Quincey Morris <
    <quinceymorris...> wrote:

    > On May 22, 2013, at 16:04 , Brian Syme <briansyme...> wrote:
    >
    > That's what I thought too. But the xcode build system allows libraries to
    > mark headers as private, project or public. The public headers are copied
    > to a derived data directory. And this directory is in the default search
    > path. So you would think that's the intended use. Maybe I'm missing
    > something.
    >
    >
    > The public (and private) headers are copied to the derived data directory
    > because they're a build product, just like object files produced by the
    > compiler. Like object files, that's just an intermediate thing for the
    > build.
    >
    > If your search path ends up pointing to a derived directory, you should
    > remove that directory from the search path. If you don't, one unintended
    > consequence is that your main project builds always use that particular
    > build configuration, and don't "switch" automatically when you build a
    > different configuration. For example, you might find that you're debugging
    > with the release version of the library, or that you're releasing your
    > product with a debug version of the library.
    >
    > I can't remember the rules for static libraries (I mostly use private
    > frameworks instead), but you may not need anything in the search paths for
    > libraries included in the workspace, so I'd try that first.
    >
    > Also IIRC, Xcode 4.6 is better than Xcode 4.5 or earlier at setting up the
    > proper dependency without jumping through hoops. Before 4.6 it seemed
    > easier to end up with the wrong thing. Unfortunately, the way this works
    > isn't very well explained anywhere. In my experience, the best way to
    > configure dependent libraries and frameworks is to use the "+" button in
    > the Link With build phase and choose the library from the list that pops up.
    >
    >
previous month may 2013 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today