how to organize my files/projects properly?

T

thomas

Hi,

I wrote a utility class, say Util, which will be used by several
projects.
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.

--tom
 
I

Ian Collins

Hi,

I wrote a utility class, say Util, which will be used by several
projects.
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.

Put it in a library.
 
V

Vladimir Jovic

thomas said:
Hi,

I wrote a utility class, say Util, which will be used by several
projects.
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.


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?
 
Á

Ángel José Riesgo

Hi,

    I wrote a utility class, say Util, which will be used by several
projects.
    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.

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.
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.

I agree. This would be a nightmare in terms of maintenance.
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.

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
 
J

Jorgen Grahn

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".

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/util.cc 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.

....
I agree. This would be a nightmare in terms of maintenance.

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
 
Á

Ángel José Riesgo

[...] 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".

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

Sure. Sorry about the typo.
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/util.cc 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.

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.
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.)

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
 
J

Jorgen Grahn

[...] 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".

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

Sure. Sorry about the typo.
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/util.cc 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.

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.

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.
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.

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
 
A

Andrew

Why not good or not elegant? Making it a library is fine. However, by
default it should be a static library as it is an order of a magnitude
easier to manage than a dynamic library. The latter should be used only if
really necessary.

hth
Paavo

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
 
P

Puppet_Sock

[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.
Socks
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top