i'm coming into C++ from Java/AS3-land, and i'm used to the package-cum-folder structure for my classes. and i like it.
i understand the very basics of namespaces in c++, and i'm happy to leave it at just the basics. but, as my project gets more complex, i'd like to keep my folder structure organized in a way i can keep in my head. i.e. something similar to Java/AS3.
1) is there any reason to not have a folder structure like:
src/
model/
view/
controller/
possibly with subfolders? (this is just an MVC example, the folder structure could be whatever depending on the project's needs.) it just seems unruly to have a src/ folder with a huge pile of header and source files within.
2) if the answer to 1) could be "go ahead and do what you want", would it be unwise/unnecessary to create a namespace for each folder, similar to Java/AS3's way of creating a package for each folder? my understanding is that namespaces are not usually used like this, nested deeply and folder-related.
I've always liked the namespace for each folder. Mostly because when I have to maintain somebody else's code, the namespace helps me find where the class was originally defined.
Well named header files can also help with this though. I also wouldn't suggest going more than 2-3 namespaces, as then it just becomes obnoxious. You'll find yourself using "using namespace blah;" a lot which I always find to be a red flag for C++ code. And you can't use "using namespace" inside a header file without some severe problems occurring.
It's all completely optional though in C++.
You may want to have a look at John Lakos Large-Scale C++ Software Design. Basically, you can do that, but your packages should (as in Java) have an acyclic dependency graph. Also, it may be opportune for each package to document which headers are exported and which aren't, maybe like so:
src/
|- package1/
|- exported_symbols_1.hh
|- exported_symbols_2.hh
|- src/
|- impl_1.hh
|- impl_1.cc
|- package2/
|- sub_package_2_1/
|- exported.hh
|- src/
...
|- src/
...
Each package is only allowed to #include the top-level headers of another package, never ones in src/ directories.
Also, when you want to use Autotools in a large project and intend to distribute headers, it may prove to be prudent to call the top-level directory not src/ but by the PACKAGE_TARNAME of that project. This makes installing headers with the help of the Autotools easier.
(And, of course, the actual file names do not look as silly as illustrated above.)
There's no reason not to divide your source code into different directories; it makes sense if there are many files and clear logical groupings.
It is not necessary to create a distinct file for each small class though - in large projects, that tends to slow compilation (as the implementation files often have to include a lot of the same headers just to compile their couple dozen lines).
As well as the use of namespaces for reflecting the logical divisions in the code, the exact thresholds at which code is subdivided into further namespaces tends to be driven by some other forces, for example:
factors suggesting use of more namespaces
very volatile code (often edited, constant additional/changed identifier use, often short and/or common words)
more developers
factors reducing the need for namespaces
tight coordination by a central body
planned formal releases with thorough checks for conflicts
Namespaces can also be used as a way to allow easy switching between alternative implementations (e.g. different versions of a protocol, thread-safe versus unsafe support functions, OS-specific implementations), so sometimes catering for such needs involves use of distinct namespaces.
It can definitely be painful digging through unintuitive and/or deeply nested namespaces to reach the variables you want, and "using namespace" is less effective if you're likely to need to use several that define the same identifiers anyway, but can suit more modal code that tends to use one or the other namespace more heavily at a time.
So, you may want to consider these factors when deciding whether to put each folder's code (or some other logically distinct group) into distinct namespaces.
There's no reason not to and will really help people reading your code. Some things to watch out for:
Don't over-nest folders, this can be confusing for readers of your code.
Be consistent in the organization of your code, e.g. don't put any view code in the controllers sub-directory, or vice-versa.
Keep the layout clean.
The src/ is a common place there c/c++ programmers put their sources within the project root.
For example:
doc/ <- documentation
libs/ <- additional libraries
po/ <- gettext translations
src/ <- sources
it common to create subdirectories underneath src/ if you've got a lot of sources files but there are no limitations how to organize this substructure.
Keep in mind that a directory structure in completely optional in c++. That is no connection between c++ namespaces and the directory structure.
You can arrange your files however you like; you'll just need to adjust your build tools' include paths and source paths to match.
Giving each directory it's own namespace is overkill and probably a bad idea, as it will make for confusing code. I'd recommend one namespace per project at most, or even just one namespace per company (since presumably within your company you have the power to rename things if necessary to resolve name collisions. Namespaces' main purpose is to handle the case where two codebases under the control of two different organizations both use the same name, and you as a third party want to use them both in the same project, but don't have the ability to modify either codebase).
Related
For a scientific project, I have a templated analysis tool (module A) that uses a type of statistical test (module B). The analysis tool (module A) is used on two types of problems (modules C and D). Modules C and D define functions for serializing from different file types.
All modules (A, B, C, and D) use common utilities (module E). Each module consists of several files. I'd really like to organize the modules so that each has its own namespace, and so the source files are in different directories (i.e. emphasize the modularity in the organization).
It's trivial to define the namespace in each file. But I was hoping to use some sort of source tree where the file to #include for each module would include all others inside its own namespace.
I'm not really sure of a good way to organize this. Should I simply use one folder per module and #include using relative paths? Should each module have its own git repository, and compile down to a single library file, which lives in a specified UNIX folder (this would require a true installation for the project to run).
Right now I'm using gcc-4.7, make, and emacs.
Do you know of a way to organize these files to bring out the modularity?
Please forgive me and suggest if there is some other StackOverflow affiliate that is more well-suited for this question. My project runs, but it's much more of a mess than it needs to be!
But I was hoping to use some sort of source tree where the file to #include for each module would include all others inside its own namespace.
This is the wrong approach. Even if A depends on E at the module level, that does not necessarily entail that all components inside A depend on all components inside E, and you should not force that through the includes.
Includes should be explicit (include everything you really need) and precise (don't include anything on which you don't depend).
That being said, I would organize the code in modules where each module has a separate directory. If a module becomes complex enough to require splitting in submodules, then you can add nested directories, but a single two level hierarchy can be enough.
I have traditionally used the same folder structure for production and test code as demonstrated below:
src/myproject/core.clj
test/myproject/core_test.clj
For test files I have added _test in the filename.
I recently noticed that several projects follow this structure (this is also what Leiningen generates by default):
src/myproject/core.clj
test/myproject/test/core.clj
Is there a convention regarding this or some clear advantage of using one over the other?
I believe this is just convention - I don't think there is any technical advantage either way.
I personally prefer the first version for entirely non-technical reasons:
It seems redundant to have two "test" directories in the path.
It can cause confusion to have the test .clj files with the same names as the main .clj files
Sometimes you want to create tests that don't perfectly line up with specific namespaces, e.g. full_system_test.clj for end-to-end testing
It's easier to pattern-match on all the *_test.clj files
Also worth noting that the Maven standard directory layout convention is also used in quite a few Clojure projects (this can be handy if you build polyglot projects that also contain Java source code):
src/main/clojure/myproject/core.clj
src/test/clojure/myproject/core_test.clj
src/main/resources/....
src/test/resources/....
I'm working on a fairly large C++ project on Linux. We are trying to come up with criteria for organizing our source file directory structure.
One thought we have is to have the directory structure reflect our architecture choices. For instance, we would have one root level for our domain classes and another for our boundary classes, and one for our domain-agnostic infrastructure classes.
So in a banking application, we might have a directory called src/domain/accounts, src/domain/customerTransactions, src/boundary/customerInputViews, etc. We might then have another directory called src/infra/collections, src/infra/threading, etc.
Also, within that structure, we'd isolate interface classes from implementation classes. We'd do that so clients of interfaces would not be dependent on the directory structure of the implementation classes.
Any thoughts?
Breaking code into independent parts sounds like a good idea. That would allow you to potentially break stuff into separate units (for autotools: you could have convenience libs for organization, and later even separate them complete into shared libs).
Of course the submodules should contain everything needed to build: headers, sources and build infrastructure (maybe only missing a top-level build definition file which gets included). This will make sure that work can be done on small units (but test the whole thing).
In my project, I currently use relative paths to include my files, which admittedly doesn't change often. However, it yields pretty weird include patterns, because I usually nest my files in alot of folders.
For example, in my current project I have network/server/myfile.hpp. It needs to include common/log.hpp. Current I use #include "../../common/log.hpp" which is pretty verbose, but works.
If i instead add my main include directory on the path, I could simply include "common/log.hpp".
I know this question might be more about preference than anything else, but is there any objective pros and cons concerning cross platform applications and what about C++ conventions?
Relative includes paths with .. in it look a bit ugly and expect a certain filesystem structure, that is, "../../common/log.hpp" is two folders up. It makes sense to avoid unnecessary dependencies in general and on filesystem structure in particular, so that moving a header file from one directory to another does not force you to update all source files that include that header.
It is also elegant to have your includes correspond to namespaces and classes. If, for example, you have:
namespace foo { namespace bar { struct Baz; } }
It is convenient and intuitive to include it like:
#include "foo/bar/Baz.h"
By having #include <common/log.hpp> in your source file and having path to common/log.hpp in your project settings (compiler options) you are protecting your source code from changes in case common/log.hpp moves to some other place so I would recommend this approach. Note using angle brackets in this case - compiler should search for the header in directories which paths are specified by the /I compiler option.
I always strive to make my projects independent of location. If I work on a new computer/platform, I want to be able to compile and keep working with a minimum of required setup. As you're asking a subjective question, my subjective answer would be that I definitely prefer using relative paths.
No CONVENTIONS as such, you may do it either way, the way you prefer.
I mean, if you want to keep it tidy
though then obviously go for 2nd
option, I'd myself go for the second
one cause its not that you'll have to
move a boulder but just a few files,
say main.
And moreover relative paths provide you freedom to port you application, So just do it :)
I have a rule that each individual component may not use more than one directory, and that component have dependent components' directories in the include path.
Thus, each component uses its own include files with the "" syntax, and other components' includes using <>, which nicely avoids unpleasant surprises with one component using the header that the last deployed version installed into the system include directory rather than the one from the source tree; it also has the nice effect of forcing me to componentize my projects early on.
Simple question. I'm new to Clojure.
How can I use one file from my project in another file? Basically how can I include, import, or require another file? Not from libraries but fro my own code.
Thanks,
Alex
Normally you'll want to use the same method that you use with library code, which is to use / require your namespaces (through an ns form at the top of the file and sometimes the use / require functions at the REPL). For this to work, you have to make sure they are on the classpath. A short guide to that:
Follow the usual Clojure project structure: a src/ directory containing all your source files, where file src/foo/bar/baz.clj defines a namespace called foo.bar.baz. Note that you must maintain the directory structure / namespace name structure correspondence; things won't work otherwise. Also note that you must not use the _ character in namespace names or the - character (the hyphen) in filenames and whenever you use _ in filenames you must use a - in namespace names (and the other way around.) Finally, the directory hierarchy will be slightly more complicated with Maven projects, but don't worry about this for now (unless you're already a proficient user of Maven, in which case this won't be a problem for you).
Also see this answer of mine to an earlier SO question about Java classpath handling with Clojure for a more detailed step-by-step explanation of the filesystem hierarchy / classpath hierarchy correspondence.
If your code from the foo.bar namespace needs to use code from the foo.quux.baz namespace, do something like (ns foo.bar (:require [foo.quux.baz :as baz])) in foo/bar.clj and call functions from baz as baz/some-function. Or you can put (:use foo.quux.baz) in the ns form instead to call them directly (without the namespace qualifier, e.g. some-function). That's exactly the same thing as what you'd do for library code.
When working with your project's code from the REPL, make sure you include the src/ directory (the directory itself, not any of the files therein) on the classpath. You should probably consider using some tool to automate the REPL setup (including classpath management) for you; Leiningen is very popular with Clojurians and there are plugins for using Maven with Clojure too.
Warning: Your JVM-launching command might (in fact, probably will) recognise an environment variable called $CLASSPATH. As for its relationship to your Clojure projects, well, basically there should be none. More likely than not, your projects will require a different classpath each, with some possibly using versions of certain jars incompatible with those required by others (notably if you're using Clojure 1.1 -- latest stable release -- for some projects, while experimenting with 1.2 snapshots with others). Thus the correct way of managing the classpath is to prepare a minimal version for each project and pass that to the JVM launching command. As mentioned previously, you should invest some time in learning to use a good tool (like the above mentioned Leiningen) to set up the classpath for you as soon as possible so you don't need to care about this yourself.
(As a side note, you might have to add more than just the src/ directory and your jars to the classpath in some scenarios, e.g. if you plan on calling compile to produce .class files, you'll have to put the target directory on the classpath too. That's beyond the scope of this question, though.)
BTW, I've started this answer with the word "normally", because you could also use things like load & in-ns to split a single namespace into multiple files. Most of the time this won't be what you really want to do, though; just use a well thought out namespace layout instead.