buildr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ittay Dror <>
Subject Re: request for enhancement: compile, package and artifacts support for C++
Date Mon, 28 Jul 2008 12:18:07 GMT
another issue, inline

Ittay Dror wrote:
> Hi,
> I'm working on adding C++ support to buildr. I already have a 
> prototype that builds libraries and executables in Linux. I'd like to 
> share some of the difficulties I had and request changes to buildr to 
> accommodate C++ more easily. (Right now, I've created parallel route 
> to that of building Java-like code)
> compile
> ========
> overview
> --------------------
> the compile method in project returns a CompileTask that is generic 
> and uses a Compiler instance to do the actual compilation. In C++, 
> compilation is also dependency based (.o => .cpp, sometimes 
> precompiling headers). Also, the same code can produce several results 
> (static and shared libraries, oj files with debug, profiling, 
> preprocessor defines turned on and off). [1]
> there is the 'build' task, which is used as a stub to attach 
> dependencies to.
> suggestion
> ---------------------
> * there should be an array of compile tasks (as in packages)
> * #compile should delegate the call to a factory method which returns 
> a task (again, as in packages)
> * generic pre-requisites (like 'resources') should either be tacked on 
> 'build' (relying on order of prerequisites), or the compile task can 
> be defined to be a composite (that is, from the outside it is a single 
> task, but it can use other tasks to accomplish its job).
> package & artifacts
> =========
> overview
> ---------------
> buildr has a cool concept that all dependencies (in 'compile.with') 
> are converted to tasks that are then simple rake dependencies. 
> However, the conversion is not generic enough. to compile C++ code 
> against a dependency one needs 2 paths: a folder containing headers 
> and another containing libraries. To put this in a repository, these 
> need to be packaged into one file. To use after pulling from the 
> repository, one needs to unpack. So a task representing a repository 
> artifact is in fact an unzip task, that depends on the 'Artifact' task 
> to pull the package from a remote repository.
> furthermore, when building against another project, there is no need 
> to pack and unpack in the repository. one can simply use the artifacts 
> produced in the 'build' phase of the other project.
> finally, in C++ in many cases you rely on a system library.
> in all cases the resulting dependency is two-fold: on a include dir 
> paths and on a library paths. note that these do not necessarily 
> reside under a shared folder. for example, a dependency on another 
> project may depend on two include folders: one just a folder in the 
> source tree, the other of generated files in the target directory
> suggestion
> -------------------
> While usage of Buildr.artifacts is only as a utility method, so one 
> can easily write his own implementation and use that, I think it will 
> be nice to be able to get some reuse.
> * when given a project, use it as is (not 'spec.packages'), or allow 
> it to return its artifacts ('spec.artifacts').
> * if a symbol, recursively call on the spec from the namespace
> * if a struct, recursively call
> * otherwise, classify the artifact and call a factory method to create 
> it. classification can be by packaging (e.g. jar). but actually, i 
> don't have a very good idea here. note that for c++, there need to be 
> a way of defining an artifact to look in the system for include files 
> and libraries  (maybe something like 'openssl:system'? - version and 
> group ids are meaningless).
>  * the factory method can create different artifacts. for c++ there 
> would be RepositoryArtifact (downloads and unpacks), ProjectArtifact 
> (short circuit to the project's target and source directories) and 
> SystemArtifact.
> I think that the use of artifact namespaces can help here as it allows 
> to create a more verbose syntax for declaring artifacts, while still 
> allowing the user to create shorter names for them. (as an example in 
> C++ it will allow me to add to the artifact the list of flags to use 
> when compiling/linking with it, assuming they're not inherent to the 
> artifact, e.g. turn debug on). The factory method receives the 
> artifact definition (which can actually be defined by each plugin) and 
> decides what to do with it.
to support jni, one needs to first compile java classes, then run javah 
to generate headers and then compile c code that implements these 
headers. so the javah task should be able to specify it depends on the 
java compile task. this can't be by depending on all compile tasks of 
course or on 'build'.

when creating a compile task (whose name can be, as in the case of c++, 
the result library name - to allow for dependency checking), also create 
a "for ordering only" task with a symbolic name (e.g., 'java:compile') 
which depends on the actual task. then other tasks can depend on that task

> I hope all this makes sense, and I'm looking forward to comments. I 
> intend to share the code once I'm finished.
> Thank you,
> Ittay
> Notes:
> [1] I don't consider linking a library as packaging. First, the obj 
> files are not used by themselves as in other languages. Second, 
> packaging is required to manage dependencies, because in order for 
> project P to be built against dependency D, D needs to contain both 
> headers and libraries - this is the package.

Ittay Dror <>

View raw message