how to organize my files/projects properly?

Discussion in 'C++' started by thomas, Sep 6, 2010.

  1. thomas

    thomas Guest


    I wrote a utility class, say Util, which will be used by several
    It's like the following senario:

    Util.h, Util.cpp --> will be used by project A, project B.

    option1: I can make Util.cpp a dll, which can be shared by A and by B.
    --> but exporting a class is not good, also not elegant.

    option2: I can put a Util.cpp in A and B.
    --> obviously bad because I need to change Util.cpp in every
    projects if necessary.

    option3: I can put the implementation in Util.cpp to Util.h, i.e.,
    merging the two files into one -- Util.h
    --> also seems bad because the header file is becoming exploding.

    Any suggestions how to handle this? Thanks.

    thomas, Sep 6, 2010
    1. Advertisements

  2. thomas

    Ian Collins Guest

    Put it in a library.
    Ian Collins, Sep 6, 2010
    1. Advertisements

  3. I thought someone asked the same question recently.

    I would go for option 1. Why do you think it is not good and elegant?

    From your analysis, every option is bad. Which option would you pick?
    Vladimir Jovic, Sep 6, 2010
  4. I agree that exporting a class is not elegant. I personally prefer to
    restrict dynamic libraries to things like a plug-in system. If your
    intention is simply to re-use the functionality declared in Util.h
    from several projects, I think it is better to compile it as a static
    library. The way I would do this consists in creating a "util"
    directory with four subdirectories: "build", "bin", "include" and
    "source". Then I would put the Util.h file in the "util/include"
    directory and Util.cpp in "util/source", and I would create the
    development project in the "util/build" directory so that it outputs a
    static library (util.lib) to the "util/bin" directory. In this way,
    you can view the two directories "include" and "source" as the public
    and private areas of the util library. In order to use these utilities
    from the projects A and B, you would need to add the "util/include"
    path to the search paths for #included files and make those projects
    link against "utils/include/util.lib".

    Since you mention dll's, I suppose you're using Windows and maybe
    Microsoft Visual Studio. If that's the case, remember that in that
    environment you can set up a solution with multiple projects (you can
    right-click on a solution name and select the "Add Existing
    Project..." option). So, once you have your Util project (a vcproj(x)
    file created as a "Win32Project -> static library") you can add that
    project to any other solution (the .sln file), where you can use the
    "Project Dependencies" dialog to establish that the .exe project is
    dependent on the .lib project(s). In this way you can compile and
    debug the code in Util.cpp from every solution that uses it, but the
    source code will be in just one file. I suppose other development
    environments provide similar options.
    I agree. This would be a nightmare in terms of maintenance.
    This is definitely bad. Among other things, you may be dragging
    unnecessary dependencies (like #includes for a third-party library
    your implementation uses) into the header file.

    Ángel José Riesgo
    Ángel José Riesgo, Sep 6, 2010
  5. thomas

    Jorgen Grahn Guest

    You mean "utils/bin/util.lib" here.

    I very much prefer flat structures. I don't see any rational reason
    for the very fine-grained directory structures I encounter all the time.

    In this case, I'd have utils/ and utils/util.h, and user code
    would #include <utils/util.h>. Requiring callers to add utils or
    utils/include/ to the include search path doesn't scale, and
    complicates the Makefile more than you'd think.

    That seems to be a common reaction to the idea, but I cannot see a
    rational reason for that either. Exactly /what/ is nightmarish about
    it? Remember, we're talking general utility functions here, stuff we
    cannot even be bothered to name properly. (Yes, I use the name in my
    own code, too.)

    Jorgen Grahn, Sep 7, 2010
  6. Sure. Sorry about the typo.
    There are several factors involved, and there is no perfect solution,
    but what I like about having two separate "include" and "source"
    directories is that there is then a clear distinction between the
    source code that is needed for the client users of the Util library
    and the source code that is required for building the library. For
    example, you may want to put some of the header files in the "source"
    directory if those files are not meant to be used outside the library
    source code (because they declare some utility functions that we don't
    want to expose as part of the public interface of the library, or some
    implementation classes that the client code will access
    polymorphically through factories and abstract base classes). In such
    a case, the .hpp files that are in "source" are clearly marked as off-
    limits to the client code of the Utils library. This is the sort of
    approach that I was thinking when I wrote that the "include" and
    "source" directories can be seen as the public and private areas of
    the library.
    I suppose it depends on the size and extent of use of such utilities,
    but if you end up using them in many places, it may be difficult to
    keep them in sync when fixing errors, etc.

    Ángel José Riesgo
    Ángel José Riesgo, Sep 8, 2010
  7. thomas

    Jorgen Grahn Guest

    I understand that point of view; I just don't think it's worth the
    effort, given the negative effects of doing so. Remember that this
    something /you/ both create and use; it isn't a third-party library.
    That's a much better description, and I kind of agree. But my gut
    feeling is that you're more likely to have foo/util and bar/util
    diverge over time as they are adapted to the specific needs of 'foo'
    and 'bar'.

    The "difficulty" is also mostly a matter of "if you fix a bug here,
    try to remember to apply the same patch there". That's something you
    already do to other things. For example, if you discover a better way
    of handling command-line options, you probably apply this better way
    to all your software sooner or later, even though separate programs
    have separate command-line parsers (separate getopt(3) loops in Unix).

    Jorgen Grahn, Sep 8, 2010
  8. thomas

    Andrew Guest

    IMO it should be possible to build the library as a DLL, even if you
    only ever ship the static lib. Building libs as DLLs helps you find
    cyclic dependencies, since they cause fatal build errors.

    -Andrew Marlow
    Andrew, Sep 9, 2010
  9. thomas

    Puppet_Sock Guest

    [how to arrange shared code]

    There is no one-size-fits-all answer.

    If the code is going to get included in
    several stand-alone codes, then it might
    be a good idea to put it in a library.
    Whether you use a .lib (or whatever your
    compiler calls it) or a DLL or whatever,
    depends on whether you expect the apps
    to run at the same time on the same platform.
    If you expect concurrent operation and you
    find the shared space (RAM and disk) to be
    important, then DLL might be the way.

    There is also the aspect of whether
    you expect the client apps and the lib
    to go through versions independently.
    If yes, a DLL might be the thing. If not,
    a .lib is probably the thing.

    A DLL is not cost free though. It involves
    fighting version control battles, and a
    (slightly?) more complicated install.
    So don't just automatically assume DLL
    unless there is some significant benefit.

    If the multiple apps are not going to run
    concurrently, and the library and the apps
    will version in parallel, then there's not
    much value in a DLL. Indeed, until you get
    multiple apps from multiple work groups
    using it, you probably just want to keep
    the .obj and the .h around, and add that
    to each project.
    Puppet_Sock, Sep 9, 2010
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.