   Where to put code so it can be re-used?
  As I've programmed over the last few years, a problem I've come across is where to put code that I've written so it can be reused across different projects. Very often, the code to be reused is being developed just as actively as the project that uses it.A couple examples:1. I've been working on an outboard component based system for my game. I've gotten it factored into a static lib, but I'm not sure where to put it or how to handle it so that it can be integrated into my actual game project, and into future projects. This library and the game need to be able to be developed in parallel.2. Particularly annoying are a bunch of little independent classes and functions, which are usually header-only, although a few of them have .cpp files with them. Right now, these little files are all mixed in with the projects where I first made them, but my programmer-sense tells me that they should have their own neutral place to live. Part of me wants to give them their own version-control repos, but that really seems like overkill.I already have a directory dedicated to libraries, which is where I have installed Boost and SDL, and in which I was planning to put libraries I wrote. I guess the question is how to get my libraries there, in a convenient way that doesn't get in the way of development.In case #1, I'm considering making an export script for the project, that will copy the appropriate files into the lib directory, where other projects will access them as needed. Is this too clumsy, and is there a better way?For case #2, I'm thinking about organizing all my little random code bits into a higher-level library, analogous to Boost. This would at least alleviate the messy, scattered feeling of just sticking them all loose in my lib directory. But I still don't know how to deal with the possibility of modifying them, and keeping track of versions.My main questions are these: How do you interface two projects which are being developed at the same time? How do you organize your libraries, particularly the little code scraps like in case #2? How do namespaces fit into this whole thing? And how do you avoid breaking old projects when you change a library?Thanks.PS: I'm looking for IDE-independent solutions, or at least IDE-agnostic solutions. Also, I'm mostly talking about C++, thought the concepts here should be largely language-independent.[Edited by - theOcelot on May 26, 2009 4:57:39 PM]
  Caveat: I don't have a wealth of experience here, and tend to work as a lone wolf.Quote:Original post by theOcelotIn case #1, I'm considering making an export script for the project, that will copy the appropriate files into the lib directory, where other projects will access them as needed. Is this too clumsy, and is there a better way?It seems clumsy to me, but you might not get better in C++ land. I like to just make two projects, which are then in different solutions in MSVS. Quote:For case #2, I'm thinking about organizing all my little random code bits into a higher-level library, analogous to Boost. This would at least alleviate the messy, scattered feeling of just sticking them all loose in my lib directory. But I still don't know how to deal with the possibility of modifying them, and keeping track of versions.Proper version control is a first step. I like higher level libraries.Quote:My main questions are these: How do you interface two projects which are being developed at the same time?I use MSVS, so it's simply 'add existing project'.Quote: How do you organize your libraries, particularly the little code scraps like in case #2?When I refactor code, certain stable snippets of code get added into libraries rather than the original source that they were needed for.Quote: How do namespaces fit into this whole thing?Not well? They help organize things, but as stuff tends to move they can cause problems.Quote: And how do you avoid breaking old projects when you change a library?You don't change the library. Especially not the interface, and rarely the nuance/behavior of its components. For me, I've found the best way to do this is to only 'promote' things into the library once they've proven themselves useful and stable within a specialized project.   ;Quote:Original post by theOcelot1. I've been working on an outboard component based system for my game. I've gotten it factored into a static lib, but I'm not sure where to put it or how to handle it so that it can be integrated into my actual game project, and into future projects. This library and the game need to be able to be developed in parallel.The library should be a project of its own, which can be added to a solution - these are MSVS-specific instructions. This way, changes to the library project propagate automatically to other solutions that incorporate it.Quote:2. Particularly annoying are a bunch of little independent classes and functions, which are usually header-only, although a few of them have .cpp files with them. Right now, these little files are all mixed in with the projects where I first made them, but my programmer-sense tells me that they should have their own neutral place to live. Part of me wants to give them their own version-control repos, but that really seems like overkill.If they represent a distinct piece or collection of functionality, then make them into a static import library as well.Quote:I already have a directory dedicated to libraries, which is where I have installed Boost and SDL, and in which I was planning to put libraries I wrote. I guess the question is how to get my libraries there, in a convenient way that doesn't get in the way of development.Put your library project in this directory, and have a post-build step for Release builds to copy the output file to the top level Bin directory, or wherever appropriate.Quote:How do namespaces fit into this whole thing?Namespaces are a completely unrelated, orthogonal concept. Namespaces are for resolving identifier collisions in code - so you can have two objects named Value and distinguish them by their namespaces, my::Value vs your::Value.Quote:And how do you avoid breaking old projects when you change a library?You don't.If your old project is closed and the library is a static import library, simply copy the required version of the import library to the project folder (and make sure the project folder is higher on the list of library directories than the external folder location).If your "old" project is being developed concurrently, but is dependent on a specific version, again copy the required version over. If, however, the "old" project may benefit from new developments, then it'll break and you'll fix it.The other big thing is versioning. You can define version symbols and use them to separate interfaces, such that a version of the static import library that eliminates or changes interfaces or substantially alters behaviors will alter versioning symbols such that dependent code will fail to build or run.Quote:PS: I'm looking for IDE-independent solutions, or at least IDE-agnostic solutions. Also, I'm mostly talking about C++, thought the concepts here should be largely language-independent.Build environment is never IDE- or toolchain-independent.   ;Quote:Original post by OluseyiQuote:Original post by theOcelotPS: I'm looking for IDE-independent solutions, or at least IDE-agnostic solutions. Also, I'm mostly talking about C++, thought the concepts here should be largely language-independent.Build environment is never IDE- or toolchain-independent.My game-coding directory is full of lots of different libraries specified in CMakeFiles, which makes it independent in the sense that I can use MSVS, CodeBlocks or GNU-style makefiles.Quote:For case #2, I'm thinking about organizing all my little random code bits into a higher-level library, analogous to Boost. This would at least alleviate the messy, scattered feeling of just sticking them all loose in my lib directory. But I still don't know how to deal with the possibility of modifying them, and keeping track of versions. ... And how do you avoid breaking old projects when you change a library?Each of your libraries should be in version control.When you've got a stable version of a lib that you want to use in a game project, copy (that's a source-control copy, which shouldn't actually copy any data - just branch the history) the library into a named branch - then use this branch in the project.Then if you continue working on the lib (in it's trunk), the old project can continue to use the old branch.If you want to update the old branch of the lib, you can easily merge your new lib features from the trunk into the branch.   ;Quote:Original post by HodgmanQuote:Original post by OluseyiBuild environment is never IDE- or toolchain-independent.My game-coding directory is full of lots of different libraries specified in CMakeFiles, which makes it independent in the sense that I can use MSVS, CodeBlocks or GNU-style makefiles.CMAKE generates platform specific build solutions from a "platform-agnostic" source file. This also means it caters to the lowest common denominator. Yey.   ;Quote:Original post by OluseyiCMAKE generates platform specific build solutions from a "platform-agnostic" source file. This also means it caters to the lowest common denominator. Yey.It still makes project/library organisation independent of IDE or build system... so I don't know what's with the attitude.Not sure what you mean about the LCD either - it spits out perfect MSVS proj/sln files for me even though it does a below average job of supporting CodeBlocks, which means it's adequate for the LCD (C::B) and good for the common case (MSVS).   ;  I'll try to summarize for the regular libs. When I build the library, I need to copy the required files (headers too) to the lib location. When I have a library and another project depends on a specific version of it, I just need to make a copy of that version (either in version control or filesystem) and use the copy, so I can continue developing the trunk.Do you usually put the project files under version control, too?But seriously, does the same go for the tiny "librarylets"? Some of these headers just define one little struct or typedef in less than 10 lines, and I'm only bothering with them for the sake of the DRY principle. It seems silly to make a whole version control repository just for the sake of one file, and it feels equally wrong to put a bunch of unrelated files into one repository, where all their versions are changed when one of them is changed. Is it worth it, either way? Which way?I never said I wanted to be toolchain-independent, though I guess that kind of follows. I just want general ideas rather than specific instructions, ideas that don't rely on an IDE to manage stuff. [smile]   ;  I put everything that is required to build the project under source control (svn).  When I release something, I can apply a tag to the repositories used, and use that tag to regenerate that build exactly at any time in the future.I also tend toward super small, libraries, and now that I've largely internalized templates, I've been running into header-only-itis.  I organize these into library projects, but I'm not quite satisfied with that approach.It sounds like you run into a lot of "breaking" changes in your shared code.  In my experience, there's not much you can do if multiple projects in simultaneous development rely on and change shared code except manage the change as soon as possible.  If I need to break something, I find it works best if I _really_ break it, so that I have to change it everywhere before I can compile again.  It just makes sure that I deal with the issue while the change is still fresh in my mind.Something I do, when it comes to supporting libraries in a common location, is to ape the OS X Frameworks structure a bit:support/boost/1.34.1support/boost/1.38.0support/psdk/vistasp1/support/psdk/server2003R2/The idea is to keep around every version of supporting libraries I've needed in the past, and use project files to bring the right version in.  This way I can use new supporting libraries without breaking old ones.  I only use this for external libraries.  For my stuff, I just use version control.   ;Quote:Original post by ValereI put everything that is required to build the project under source control (svn).  When I release something, I can apply a tag to the repositories used, and use that tag to regenerate that build exactly at any time in the future.I'm not sure what you mean. I do have everything under version control, somewhere. Can you explain that paragraph a little more?Quote:I also tend toward super small, libraries, and now that I've largely internalized templates, I've been running into header-only-itis.  I organize these into library projects, but I'm not quite satisfied with that approach.It sounds like you run into a lot of "breaking" changes in your shared code.  In my experience, there's not much you can do if multiple projects in simultaneous development rely on and change shared code except manage the change as soon as possible.  If I need to break something, I find it works best if I _really_ break it, so that I have to change it everywhere before I can compile again.  It just makes sure that I deal with the issue while the change is still fresh in my mind.I don't run into breaking changes a lot yet, I'm just trying to head the problem off at the pass. I'm just starting to actually have code that can be shared. [headshake]Quote:Something I do, when it comes to supporting libraries in a common location, is to ape the OS X Frameworks structure a bit:support/boost/1.34.1support/boost/1.38.0support/psdk/vistasp1/support/psdk/server2003R2/The idea is to keep around every version of supporting libraries I've needed in the past, and use project files to bring the right version in.  This way I can use new supporting libraries without breaking old ones.  I only use this for external libraries.  For my stuff, I just use version control.So you explicitly save old versions of third-party libraries, and keep tags of libraries you wrote. Then you just put everything a given project needs into its SVN repo. Does that include third party libs, like Boost?;  In the places where I have worked we have a directory with lots of source/header files so we can add them to each project which requires it.Not that I like it.   