Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Implied Linker defaults to gcc, sometimes

Help
2005-01-31
2013-04-24
  • I'm pretty sure I've uncovered a bug, but can someone please confirm.

    It appears that if you define a compiler within a project using <compiler> (not in cc task), and reference that compiler using a <compiler refid="blah"> in a cc task, the correct linker is not implied.  It results in trying to use gcc. 

    If I specify the classname in the <cc> task, it always works correctly (I've only tested "classname" for custom adapters).  Another peculiar part is that it seems to work correctly for statically linked libraries, but not executables.

    Here are the excerpts from my code:
    build.xml:
    ...
    <compiler id="myCompiler" classname="${ForteCCompiler.classname}">
        <includepath>
              <filelist dir="/./" files="${APP_INC}" />
                <filelist dir="/./" files="${distBaseDir}/include" />
        </includepath>
    </compiler>

    <linker id="myLinker" classname="myPath.common.util.ForteCLibrarian"/>
    ...

    <target name="compileTest" >
        <cc    objdir="${testDir}"
              outtype="executable"
                outfile="${testDir}/${test.name}"
          >

            <compiler refid="myCompiler" />
              <linker classnamevi ="myPath.common.util.ForteCLibrarian" />
              <fileset dir="${testDir}" includes="${test.name}.c" />
            ... linker args ...
            ... libraries ...
        </cc>
    </target>

    Although this shouldn't make a difference since it works otherwise...
    ForteCLinker.java (adapter from ForteCC):

    (Beginning Declarations)
        private static final ForteCLibrarian arLinker = ForteCLibrarian.getInstance();

        private static final ForteCLinker dllLinker = new ForteCLinker("cc",
                objFiles, discardFiles, "lib", ".so");

        private static final ForteCLinker instance = new ForteCLinker("cc",
                objFiles, discardFiles, "", "");

        public Linker getLinker(LinkType type) {
            if (type.isStaticLibrary()) {
                return arLinker;
            }
            if (type.isSharedLibrary()) {
                return dllLinker;
            }
            return instance;
        }

    Thanks,
    Athas

     
    • Sorry, please ignore the linker element in the <cc> task.  It's wrong (should be Linker not Librarian) but if it is correctly set, it is a work around.

      ~ Athas

       
      • Curt Arnold
        Curt Arnold
        2005-01-31

        I think you are seeing the intended behavior, but it is not what you expect.  Adding a <compiler> element to the <cc> element (potentially) affects the compiler that files are dispatched to, but does not affect the selected linker. 

        There can be multiple compilers involved in a cc task, but only one linker.  The linker is the first active (that is if and unless conditions satisified) linker element.  If there is not a linker element, then it is the linker associated with the compiler specified on the cc element which is gcc if name or classname is not specified.

        For example, if I did this

        <cc name="bcc"...>
             <compiler name="msidl"/>
             <fileset dir="*.cpp *.idl"/>
        </cc>

        All the files in the fileset would be auctioned off with the Microsoft IDL bidding first then the Borland C++ compiler.  The IDL compiler would only bid on *.idl files and the Borland compiler would win the bidding on everything else.  Placing a Microsoft compiler in the bidding queue doesn't affect the linker in use which in this case would be the Borland linker.

        In your usage, you have placed a C++ compiler in front of the default compiler (which if not specified is gcc).  However the fact that your compiler wins all the bidding (since it precedes the default compilers bid) doesn't affect the choice of linker.