views:

133

answers:

3

I'm about to upload a project I've been working on onto Sourceforge under the GPL, and was hoping to get some advice on how to organize the code in a fashion that is easy to understand and use by any developers that might look at it, that works well with git, and the way Sourceforge presents things.

My projects is a cross-platform C++ application, and consists of the following:

  • A library portion, which does the actual work
  • A separate GUI portion, which uses the library portion
  • Open source libraries, whose include paths are needed to compile the library
  • Modified open source libraries, which have been altered, and hence are in some sense a direct part of this project as well
  • Compiled output of all of the libraries

What's the best way to organize this?

While working on it myself, from the project root I have it like this:
/LibPortion
/GuiPortion
/libs/open source libraries
/libs/modified open source libraries
/libs/compiled/ to hold the compiled libraries, including when compiling for Windows some that aren't from the open source libraries, such as the Cygwin library files

Is this a sensible way to organize things? Does that match conventions and expectations?

When checking in my project, does it make sense to check in the open source libraries as well as part of the project? I figure that it makes sense to do so, because that minimizes friction with getting the project set up and running for a new dev. Certainly I should at least check in the modified open source libraries.

Also, what does it make sense to include in the repository under compiled libraries? I'm thinking it might be best to tell git to ignore that directory and leave it empty, since its contents will be different on every build target, since my project is cross-platform.

However, it also seems really nice for people who don't want to hassle with building and/or downloading all the libraries themselves to offer the libraries pre-compiled for major platforms. What's the smartest way to also share those? I'm looking at Sourceforge, and it's not readily apparent to me how I should share those if not as part of my git repository.

+3  A: 

If I were you I would first separate the project between you own code and third parties libraries. The following tree could work :

/
|- GUI
|- lib
|- third parties
    |- compiled targets
    |- "your first library"
    |- "another library"
    |- ...

You shouldn't host compiled libraries on your repository imho. It's more flexible to let the developers compile them on their own computer, but if you want to have a deliverable tarball, it should include precompiled libraries.

Opera
So what would you do with third party libraries that have been modified for this project?
Nantucket
It depends on the modifications you made. If they are slightly modified, maybe a patch directory can be enough. If the modifications are more important, try moving the directory into your lib directory and renaming it into something more meaningful than just the name (i.e. myGorgeousCPPLibrary).
Opera
What about compiled binaries? Where do they go? Where do internally compiled libraries go?
Simon
+3  A: 

/
|- bin - Compiled binaries go here (not submitted to source-control)
|- build - buildscripts, tools used to build your code.
|- lib - Compiled libraries go here (not submitted to source-control)
|- local - (not submitted to source control)
   |- obj - Compiled object-files (not submitted to source-control)
   |- msvc - Autogenerated solution files for visual studio (not submitted to source control) (if applicable)
   |- scripts - Autogenerated script files (if applicable)
|- units
   |- libportion
      |- include - external headers for other units to see
      |- src
   |- guiportion
      |- include
      |- src
|- external
   |- externallib1
      |- include
      |- src

build - simplified build-script calling the correct convention to your buildscripts.
README - text-file explaining your software and the layout of your source.

This is the organization that I've been using lately and it's been greatly appriciated by everyone included. It also makes it easy to separate libraries between each others and make it easy to provide internal headers and external headers in libraries.

Edit: Added the "local" dir.

Simon
+1  A: 

In general, separate your work from that of third parties. On the most basic level, your root folder could look like:

|- GUI
|- Library
|- Third-party
    |- lib
    |- source

I separated the "third-party" folder into two subfolders for the purposes of license compliance and ease of use. How exactly you distribute third party libs will depend entirely on their licenses. Set up your makefiles so that compiled libs will land in the third-party\lib folder (which is where you will also place any pre-compiled libs). That way the user can download the pre-compiled libs and ignore the source folder or download the source code and ignore the lib folder depending on whether or not they want to re-build the third-party libs.

If you are required to distribute your modified version in binary and source code form, then you will need to host your modified version in your source repository (providing a pre-compiled lib is your choice).

If you are using an unmodified library and you are using a Subversion repository (or similar), you can use the externals property to link your repository to the third party library's repository such that when a user gets a copy of your source code, it grabs the lib's source from its own repo. That way, you don't have to keep a local mirror of the library source. Depending on what the third-party lib has available in its repo, you may be able to use externals to link to a pre-compiled version of the third-party lib as well. This will not only lessen the amount of code that you will have to host in your repo, but it will also more clearly indicate that the particular third-party lib has not been modified.

When using unmodified libraries, it would be even better to not include the source or binary in your source tree at all. Simply make a note in your documentation that your project depends on library X (specify the version as well, if it is important) and provide a link to that library's project homepage/Sourceforge page/repository. Let the developer decide whether they want to compile the library, download a pre-compiled version, or possibly use the version that they already have installed. This means that you also can't assume that the library or its headers will exist in a particular directory relative to your source code; instead, you will have to trust the user to install the libraries where the compiler can find them. Your code will simply assume that they are in the compiler's search path.

It is also possible that your modified libraries are implemented such that an externals property will cause the unmodified source to be retrieved from the third-party repo, and your build system can apply a patch containing your modifications. This way, you would not technically be distributing modified code, which might mean several fewer license terms to which you have to comply.

Typically, I wouldn't recommend distributing pre-compiled versions of your library inside your source repository. With Sourceforge, you can pre-compile your library (or any other "end product") for major platforms and offer them as downloads.

bta