I've been working on a development environment architecture. I am targeting a posix-style environment, but want it to work on Windows as well. I am having troubles with part of my makefile which builds all dependencies.
On linux I'm using g++ and make, on Windows I am targeting MinGW and make. I'm not against using Cmake or Qmake, but I haven't found a good resource which describes what I'm doing. They are all either way too basic, or way too specific. Any advice you could give would be great.
My repository structure looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
File structure
bin - Output directory for resulting app and test-app
build - Directory containing build and packing files (makefiles, CMakelists.txt, etc)
dat/<proj> - Runtime data needed by the project, may also contain runtime data needed by dependants
dat/<dep> - Each dep also has a dedicated folder here.
dbin - Output directory for resulting app built in debug mode (-g)
doc/src - Contains doc/src for a doxy file, and doc/bin for generated documentation
etc/<proj> - Configuration data (may be over-riden by dependenants)
etc/<dep> - Each dep also has a dedicated folder here.
ext/<dep> - Contains svn:externals for dependencies
<proj> will build these, and install here before building itself.
Each <dep> is garunteed to also have this file structure.
inc/<proj> - Contains include files from dependencies, and public include files from this project.
inc/<dep> - Each <dep> has it's include files available here.
int/ - Contains garbage intermediate files
lib - Contains static libraries (may be the primary output of this project depending on type)
src - Contains all source files and headers, may include subdirs.
test - Contains sources needed to build the test-app.
var - Contains log files. Used during runtime only. Not needed in repo
Config
<proj> = ProjectName
<rootdir> = ..
<dependencies> = dep1 dep2 dep3
<Config> = Release|Debug
<Template> = app|so|lib
Build Dependencies
for each <dep> in <dependencies>
if (<rootdir>/ext/<dep> exists) # Search for deps in ext/
<depdir> = <rootdir>/ext/<dep>
make -C <depdir>/build
elseif (<rootdir>/../<dep> exists) # Maybe we are already a
<depdir> = <rootdir>/../<dep> # dep, check if our deps
else # are siblings
throw error: "Dependency not found"
endif
cp <depdir>/bin/* <rootdir>/bin/ # Only for app dep
cp <depdir>/lib/*.a <rootdir>/lib/ # Only for static dep
cp <depdir>/lib/*.so <rootdir>/lib/ # Only for dynamic dep
cp <depdir>/inc/<dep>/* <rootdir>/inc/<dep>/
cp <depdir>/dat/<dep>/* <rootdir>/dat/<dep>/
cp <depdir>/etc/<dep>/* <rootdir>/etc/<dep>/ -n
endfor
Build my stuff
Build my binaries
compile ../src/*.cpp + subdirs to ../int/*.o
link ../int/*.o ../lib/*.a and ../lib/*.so into */int/<proj>.a
if <template>=so
compile ../src/LibInterface.cpp and link ./lib/<proj>.a into ../lib/lib<proj>.so
elseif <template>=app
compile ./lib/<proj.a> into ../bin/<proj>
Copy my public API
cp ../src/*.h ../inc/<proj> (probably want to define a subset)
Build test
compile ../test/*.cpp and link ../lib/<proj>.a into ../bin/<proj>-test
Build documentation
( cat <rootdir>/doc/src/doxy ; echo "OUTPUT_DIRECTORY=<rootdir>/doc/bin" ) | doxygen - */
I've got most sections working except for the "Build Dependencies" section because I can't figure out how to do the text-replacement in make for a procedure like this.
Would appreciate some help with how to template that!
I'm starting to think that the giant "cp" block could be handled inside of the dependencies makefile. In addition, the if/elseif/else section could be omitted, with the consequence of building super-generic libraries over and over and over for each dependency. It'd be an optimization I could figure out later.
Config
<proj> = ProjectName
<rootdir> = ..
<dependencies> = dep1 dep2 dep3
<Template> = app|so|lib
Build Dependencies
for each <dep> in <dependencies>
make -C <rootdir>/ext/<dep>
endfor
Build my stuff
Build my binaries
compile ../src/*.cpp + subdirs to ../int/*.o
link ../int/*.o ../lib/*.a and ../lib/*.so into */int/<proj>.a
if <template>=so
compile ../src/LibInterface.cpp and link ./lib/<proj>.a into ../lib/lib<proj>.so
elseif <template>=app
compile ./lib/<proj.a> into ../bin/<proj>
Copy my public API
cp ../src/*.h ../inc/<proj> (probably want to define a subset)
Build test
compile ../test/*.cpp and link ../lib/<proj>.a into ../bin/<proj>-test
Build documentation
( cat <rootdir>/doc/src/doxy ; echo "OUTPUT_DIRECTORY=<rootdir>/doc/bin" ) | doxygen - */
Install
cp <rootdir>/bin/* <installdir>/bin/ # Only for app dep
cp <rootdir>/lib/*.a <installdir>/lib/ # Only for static dep
cp <rootdir>/lib/*.so <installdir>/lib/ # Only for dynamic dep
cp <rootdir>/inc/<dep>/* <installdir>/inc/<dep>/
cp <rootdir>/dat/<dep>/* <installdir>/dat/<dep>/
cp <rootdir>/etc/<dep>/* <installdir>/etc/<dep>/ -n */
That means the problem I need to solve is how to do this in make:
1 2
for each <dep> in <dependencies>
make -C <rootdir>/ext/<dep>