Best way to include platform specific sources?

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Best way to include platform specific sources?

Daniel Einspanjer
I was looking at this piece of Jamfile again:

========== Example 1 ==========
alias linux ;
obj linux
    : # sources
        linux.cpp
    : # requirements
        <os>LINUX
    ;

alias osxppc ;
obj osxppc
    : # sources
        osxppc.cpp
    : # requirements
        <os>OSXPPC
    ;

exe example1 : linux osxppc ;
========== End Example 1 ==========

And wondering if there wasn't a different/better way.
I thought about using a rule like this:

========== Example 2 ==========
rule platform-specific-source ( )
{
    import os ;
    local files ;
    switch [ os.name ]
    {
        case NT : ;
        case LINUX :
            files += linux.cpp
            ;
        case OSXPPC :
            files += osxppc.cpp
            ;
    }
    return $(files) ;
}

exe example2 : [ platform-specific-source ] ;
========== End Example 2 ==========

and it almost works, but since we don't have any NT specific files, the rule
bombs out.

Is the rule better? If so, how can I work around the empty case?


Daniel


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Vladimir Prus
Hi Daniel,

> I was looking at this piece of Jamfile again:

> alias linux ;
> obj linux
>
>     : # sources
>
>         linux.cpp
>
>     : # requirements
>
>         <os>LINUX
>     ;
.......

> ========== Example 2 ==========
> rule platform-specific-source ( )
> {
>     import os ;
>     local files ;
>     switch [ os.name ]
>     {
>         case NT : ;
>         case LINUX :
>             files += linux.cpp
>             ;
>         case OSXPPC :
>             files += osxppc.cpp
>             ;
>     }
>     return $(files) ;
> }
>
> exe example2 : [ platform-specific-source ] ;

That's just fine, if the build platform and the target platforms is the same
-- which is the case now since we don't, at least officially, support
cross-compiling.

> and it almost works, but since we don't have any NT specific files, the
> rule bombs out.

Ah, true, but what do you want in that case? Skip building of 'example2'
completely? Then, you can either wrap it in "if [ os.name ] = NT", or you can
use newly introduced <build>no properties:


   exe example2 : [ platform-specific-source ] : <os>NT:<build>no ;

or you can combine indirect conditional requirements with <build>on and the
<source> feature like this:

        rule sources ( properties * )
        {
     if <variant>debug in $(properties)
       {
        return <source>a_d.cpp ;
         }
        else if <variant>release in $(properties)
         {
                     return <source>a_r.cpp ;
        }
      else
        {
                     return <build>no ;
      }
        }
       
        exe main : : <conditional>@sources ;

I've used <varint> for testing, you'll use <os> feature. Here's what I get:

    ghost@zigzag$ bjam debug
    [...]
    gcc.compile.c++ bin/gcc/debug/a_d.o
    [...]
    ghost@zigzags$ bjam release
    [...]
    gcc.compile.c++ bin/gcc/release/a_r.o
    [...]
    ghost@zigzag:/space/p2/ghost/build/boost.build/sources$ bjam profile
    Skipping build of ./main -- <build>no in properties.

HTH,
Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Daniel Einspanjer
Wow.  Thanks for the detailed reply!

"Vladimir Prus" <[hidden email]> wrote in message
news:[hidden email]...

> That's just fine, if the build platform and the target platforms is the
> same
> -- which is the case now since we don't, at least officially, support
> cross-compiling.

Would the right way to support a cross-compilation-aware BB be the first
method of using empty aliases and alternatives?

>> and it almost works, but since we don't have any NT specific files, the
>> rule bombs out.
>
> Ah, true, but what do you want in that case? Skip building of 'example2'
> completely? Then, you can either wrap it in "if [ os.name ] = NT", or you
> can
> use newly introduced <build>no properties:
>

My example was a bit contrived here.  In reality, these source files get
compiled into a lib that has other source files that are always part of it.
I trimmed a bit too much away to give a clear representation.

> or you can combine indirect conditional requirements with <build>on and
> the
> <source> feature like this:

I tried implementing this method with the following code.  I used an
intermediate obj target so I could have the <build>no stop it but not the
parent.  It works, but I did notice something a bit strange.  The Skipping
message appears *very* early in the build progress..  While it is very clear
in its statement, I think it might be just a bit disconcerting when one of
my developers sees it at the top of a Windows build.

rule select_platform_specific_sources ( properties * )
{
    if <os>NT in $(properties)
    {
        return <build>no ;
    }
    else if <os>LINUX in $(properties)
    {
        return <source>linux.cpp ;
    }
    else if <os>OSXPPC in $(properties)
    {
        return <source>osxppc.cpp ;
    }
}
obj platform_specific_sources
    : # sources
    : # requirements
        <conditional>@select_platform_specific_sources
    ;
lib util
    : # sources
        #... normal sources here
        platform_specific_sources
    : # requirements
    ;
[C:\src\testproj\engine\cpp\util\common]bjam util
Skipping build of
../../../../engine/cpp/util/common/platform_specific_sources -- <build>no in
properties.
...patience...
...found 468 targets...
...updating 91 targets...
MkDir1 ..\..\..\..\product\build


Does it seem right to you that the Skipping message appears so early?

Daniel


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Daniel Einspanjer
In reply to this post by Daniel Einspanjer
I noticed one other oddity that I think might be a bug.  Please see the
bottom of this e-mail...

"Daniel Einspanjer" <[hidden email]> wrote in message news:...

> rule select_platform_specific_sources ( properties * )
> {
>    if <os>NT in $(properties)
>    {
>        return <build>no ;
>    }
>      ...
> }
> obj platform_specific_sources
>    : # sources
>    : # requirements
>        <conditional>@select_platform_specific_sources
>    ;
> lib util
>    : # sources
>        #... normal sources here
>        platform_specific_sources
>    : # requirements
>    ;
> [C:\src\testproj\engine\cpp\util\common]bjam util
> Skipping build of
> ../../../../engine/cpp/util/common/platform_specific_sources -- <build>no
> in properties.
> ...patience...
> ...found 468 targets...
> ...updating 91 targets...
> MkDir1 ..\..\..\..\product\build

MkDir1
..\..\..\..\product\build\engine\cpp\util\common\internal\msvc\debug\build-no
MkDir1
..\..\..\..\product\build\engine\cpp\util\common\internal\msvc\debug\build-no\runtime-debugging-off

I just noticed that on NT, my util lib gets built into a build-dir
containing build-no.  At the most, I would expect to see the
platform_specific_sources rsp files in a build-no directory, certainly not
the files that actually did get built.

Daniel


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Foster Brereton
In reply to this post by Vladimir Prus
Are the features you describe here available in Boost 1.33.1? If not, are the kludges one can implement to achieve similar functionality?

Blessings,
Foster

On 2/10/06, Vladimir Prus <[hidden email]> wrote:

[snip]

Ah, true, but what do you want in that case? Skip building of 'example2'
completely? Then, you can either wrap it in "if [ os.name ] = NT", or you can
use newly introduced <build>no properties:


   exe example2 : [ platform-specific-source ] : <os>NT:<build>no ;

--
Foster T. Brereton - Computer Scientist
Software Technology Lab, Adobe Systems Incorporated
[hidden email]   --   http://opensource.adobe.com
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Jaroslav Gresula
In reply to this post by Vladimir Prus
Vladimir Prus wrote:

 > or you can combine indirect conditional requirements with <build>on
and the <source> feature like this:
 >
 >     rule sources ( properties * )
 >     {
 >           if <variant>debug in $(properties)
 >            {
 >                 return <source>a_d.cpp ;
 >          }
 >              else if <variant>release in $(properties)
 >          {
 >              return <source>a_r.cpp ;
 >            }
 >           else
 >            {
 >              return <build>no ;
 >           }
 >     }
 >
 >     exe main : : <conditional>@sources ;
 >
It seems to me that the <source> feature does not work for lib targets.
For instance, consider the following Jamfile:

lib mylib : : <source>main.cpp ;
exe myexe : : <source>main.cpp ;

Invoking 'bjam' on this file builds only the myexe target. Invoking
'bjam mylib' just prints '...found 3 targets...', but nothing actually
happens. Is this behavior intended or it is a bug?

Thanks,
Jarda.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Mark Evans-2
I confirmed this problem on my system.

lib : : <conditional>@sources ;

when "bjamed" does nothing other than indicate nnn targets found.  Change this to:

exe : : <conditional>@sources ;

causes the sources returned by [ sources ] to be compiled.

Anyone have a fix?   I was hoping to exploit this feature.

Regards,
Mark

Jaroslav Gresula <[hidden email]> wrote:
It seems to me that the feature does not work for lib targets.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Mark Evans-2
In reply to this post by Daniel Einspanjer
Attached is a proposed patch to enable the builtin lib rule to correctly handle

lib foo : : <conditional>@source-list-generator ;

It's a simple one-liner in tools/builtin.jam.

Cheers,
Mark


cvs diff -u -- builtin.jam (in directory C:\CVSROOT\boost\tools\build\v2\tools\)
Index: builtin.jam
===================================================================
RCS file: /cvsroot/boost/boost/tools/build/v2/tools/builtin.jam,v
retrieving revision 1.185
diff -u -r1.185 builtin.jam
--- builtin.jam 10 Feb 2006 15:00:51 -0000 1.185
+++ builtin.jam 11 Feb 2006 18:51:22 -0000
@@ -404,7 +404,10 @@
             local properties = [ $(property-set).raw ] ;
             # Determine the needed target type
             local actual-type ;
-            if <search> in $(properties:G) || <name> in $(properties:G)
+    # <source>files can be generated by <conditional>@rule feature
+    # in which case we don't consider it a SEARCHED_LIB type.
+            if ! <source> in $(properties:G) &&
+               ( <search> in $(properties:G) || <name> in $(properties:G) )
             {
                 actual-type = SEARCHED_LIB ;
             }


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

patch.log (542 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Vladimir Prus
In reply to this post by Daniel Einspanjer
On Friday 10 February 2006 17:47, Daniel Einspanjer wrote:

> "Vladimir Prus" <[hidden email]> wrote in message
> news:[hidden email]...
>
> > That's just fine, if the build platform and the target platforms is the
> > same
> > -- which is the case now since we don't, at least officially, support
> > cross-compiling.
>
> Would the right way to support a cross-compilation-aware BB be the first
> method of using empty aliases and alternatives?

Yes, or using conditional requirements, or indirect conditional requirements.
In fact, any method that only looks on build properties, but not on the value
of [ os.name ] -- which is the host OS, and not a target OS in any case.

> >> and it almost works, but since we don't have any NT specific files, the
> >> rule bombs out.
> >
> > Ah, true, but what do you want in that case? Skip building of 'example2'
> > completely? Then, you can either wrap it in "if [ os.name ] = NT", or you
> > can
> > use newly introduced <build>no properties:
>
> My example was a bit contrived here.  In reality, these source files get
> compiled into a lib that has other source files that are always part of it.
> I trimmed a bit too much away to give a clear representation.

I see.

> > or you can combine indirect conditional requirements with <build>on and
> > the
> > <source> feature like this:
>
> I tried implementing this method with the following code.  I used an
> intermediate obj target so I could have the <build>no stop it but not the
> parent.  It works, but I did notice something a bit strange.  The Skipping
> message appears *very* early in the build progress..  While it is very
> clear in its statement, I think it might be just a bit disconcerting when
> one of my developers sees it at the top of a Windows build.
......

> [C:\src\testproj\engine\cpp\util\common]bjam util
> Skipping build of
> ../../../../engine/cpp/util/common/platform_specific_sources -- <build>no
> in properties.
> ...patience...
> ...found 468 targets...
> ...updating 91 targets...
> MkDir1 ..\..\..\..\product\build
>
>
> Does it seem right to you that the Skipping message appears so early?

Technically, that's right. The message is printed when Boost.Build converts
"main targets", defined in Jamfiles, into real Jam targets that correspond to
files with specific names, in specific directories and with specific updating
actions.

All those "MkDir1" messages are printed when those actual targets are built,
so they come *after* the "Skipping" message. But note that as long as your
'util' target always have regular target, you don't need '<build>no' at all.

You can just add:

   <conditional>@select_platform_specific_sources

to requirements of 'util', and instead of returning <build>no, return nothing,
that is:

  rule select_platform_specific_sources ( properties * )
  {
    if <os>NT in $(properties)
    {
        # No NT-specific sources.
    }
    ......
  }

That '<build>no' is only necessary if you have a target that must be skipped
for certain platform, completely. This sounded necessary from your previous
example, but as we've settled above, that was just over-simplified
example ;-)


- Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Vladimir Prus
In reply to this post by Foster Brereton
On Friday 10 February 2006 20:56, Foster Brereton wrote:
> Are the features you describe here available in Boost 1.33.1?

No. You're advised to use either CVS state, or nightly build from

   http://boost.org/boost-build2

Since we have automatic regression tests for Boost.Build, serious regresions
are not very likely, so using CVS/nightly is relatively safe.

> If not, are
> the kludges one can implement to achieve similar functionality?

You can use either conditional requirements or target alternatives:

  http://boost.org/boost-build2/doc/html/bbv2/advanced/targets.html#id2572339
  http://boost.org/boost-build2/doc/html/bbv2/advanced/targets.html#id2572501

(That's CVS docs, and "indirect conditional requirements" mentioned there is
that new feature not available in 1.33.1. Ordinary conditional requirements
were available for a long time now)

HTH,
Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Vladimir Prus
In reply to this post by Mark Evans-2
Hi Mark,

> Attached is a proposed patch to enable the builtin lib rule to correctly
> handle
>
>   lib foo : : <conditional>@source-list-generator ;
>
>   It's a simple one-liner in tools/builtin.jam.

That indeed fixes the problem! I've run the testsuite and there are no
regressions, so the patch was just comitted:

  http://sourceforge.net/mailarchive/forum.php?thread_id=9709627&forum_id=9097

Thanks for such quick fix, and for providing a clear log message!

I've also wrote a small test for this problem, which is CVS now:

  http://sourceforge.net/mailarchive/forum.php?thread_id=9710039&forum_id=9097

Thanks,
Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
Reply | Threaded
Open this post in threaded view
|

Re: Best way to include platform specific sources?

Mark Evans-2
Vladimir - happy to contribute.  Thanks for illustrating how to construct a test case.

Regards,
Mark

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build