Circular Dependencies Between Libraries

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • barias@axiscode.com

    #1

    Circular Dependencies Between Libraries

    Although circular dependencies are something developers should normally
    avoid, unfortunately they are very easy to create accidentally between
    classes in a VS project (i.e. circular compile-time dependencies). But
    then I started wondering how "easy" it would be to similarly make a
    NON-RUNTIME circular dependency between (implicitly linked) DLLs.
    Indeed authors like John Lakos, who focus on compile/link-time
    dependencies (not run-time), tell us to avoid such circular
    dependencies between "packages" (i.e. libraries). But to my surprise,
    evidently it isn't possible to create a circular library dependency
    even if you try...

    Tonight I tried to make a circular dependency by creating two Win32
    console DLLs in a new VC++ solution, and attempted to make both have a
    (implicit link) dependency on the other. But no matter how I tried, in
    the end I always got a linker error about missing symbols - because DLL
    'A' needed the type library of DLL 'B', which did not exist yet because
    DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
    if I made both projects just static libraries (instead of DLLs).

    In the end, I concluded that to make the circular dependency I would
    need to involve some kind of externalized interface descriptions - such
    as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
    would end up with something that is more akin to circular runtime
    dependency rather than a non-runtime dependency (and even then, it may
    no longer qualify as truly circular).

    Can anyone give me an example of how DLLs (or even static LIBs) can get
    involved in a circular dependency? I'm scrutinizing this topic because
    authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    how "packages" (aka libraries) should be forced away from cyclical
    dependencies. Well, why make all that effort of preaching against
    circular package/library dependencies, if its not even possible to make
    such circular dependencies in the first place?

  • Gavin Deane

    #2
    Re: Circular Dependencies Between Libraries


    bar...@axiscode .com wrote:
    Although circular dependencies are something developers should normally
    avoid, unfortunately they are very easy to create accidentally between
    classes in a VS project (i.e. circular compile-time dependencies). But
    then I started wondering how "easy" it would be to similarly make a
    NON-RUNTIME circular dependency between (implicitly linked) DLLs.
    Indeed authors like John Lakos, who focus on compile/link-time
    dependencies (not run-time), tell us to avoid such circular
    dependencies between "packages" (i.e. libraries). But to my surprise,
    evidently it isn't possible to create a circular library dependency
    even if you try...
    >
    Tonight I tried to make a circular dependency by creating two Win32
    console DLLs in a new VC++ solution, and attempted to make both have a
    (implicit link) dependency on the other. But no matter how I tried, in
    the end I always got a linker error about missing symbols - because DLL
    'A' needed the type library of DLL 'B', which did not exist yet because
    DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
    if I made both projects just static libraries (instead of DLLs).
    >
    In the end, I concluded that to make the circular dependency I would
    need to involve some kind of externalized interface descriptions - such
    as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
    would end up with something that is more akin to circular runtime
    dependency rather than a non-runtime dependency (and even then, it may
    no longer qualify as truly circular).
    >
    Can anyone give me an example of how DLLs (or even static LIBs) can get
    involved in a circular dependency? I'm scrutinizing this topic because
    authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    how "packages" (aka libraries) should be forced away from cyclical
    dependencies. Well, why make all that effort of preaching against
    circular package/library dependencies, if its not even possible to make
    such circular dependencies in the first place?
    VC++, Windows programming, IDL, DLLs are all off-topic here. However,
    if you can formulate your question as a pure C++ question


    then you should get some help. Alternatively, if your question is
    specific to Windows, try asking in one of the Windows programming
    groups suggested in FAQ 5.9.

    Gavin Deane

    Comment

    • Alf P. Steinbach

      #3
      Re: Circular Dependencies Between Libraries

      * barias@axiscode .com:
      >
      Can anyone give me an example of how DLLs (or even static LIBs) can get
      involved in a circular dependency? I'm scrutinizing this topic because
      authors like Robert Martin or John Lakos ("Large Scale C++") talk about
      how "packages" (aka libraries) should be forced away from cyclical
      dependencies. Well, why make all that effort of preaching against
      circular package/library dependencies, if its not even possible to make
      such circular dependencies in the first place?
      Circular dependencies are possible (in practice) for all kinds of
      modules created in C++.

      Start by creating two functions foo and bar that depend on each other:

      <file foo.cpp>
      void bar();
      void foo() { bar(); }
      </file foo.cpp>

      <file bar.cpp>
      void foo();
      void bar() { foo(); }
      </file bar.cpp>

      Now compile these files separately: you have circularly dependent object
      files.

      Create a static library from each: you have circularly dependent static
      libraries.

      Create a DLL from each: you have circularly dependent DLLs (of course,
      how to create such DLLs is off-topic in this group, which is about the
      C++ language, so for specific tool usage ask in appropriate group).

      --
      A: Because it messes up the order in which people normally read text.
      Q: Why is it such a bad thing?
      A: Top-posting.
      Q: What is the most annoying thing on usenet and in e-mail?

      Comment

      • Greg

        #4
        Re: Circular Dependencies Between Libraries

        barias@axiscode .com wrote:
        Can anyone give me an example of how DLLs (or even static LIBs) can get
        involved in a circular dependency? I'm scrutinizing this topic because
        authors like Robert Martin or John Lakos ("Large Scale C++") talk about
        how "packages" (aka libraries) should be forced away from cyclical
        dependencies. Well, why make all that effort of preaching against
        circular package/library dependencies, if its not even possible to make
        such circular dependencies in the first place?
        Since dynamic libraries are a subject of active interest and
        development in the C++ standard, I would say that dynamic libraries are
        not entirely off-topic. At any rate this question is easily answered:
        It is certainly possible to build mutually dependent libraries. The
        trick is simply to build one library against a stub library version of
        the other.

        Greg

        Comment

        • Noah Roberts

          #5
          Re: Circular Dependencies Between Libraries


          barias@axiscode .com wrote:
          Although circular dependencies are something developers should normally
          avoid, unfortunately they are very easy to create accidentally between
          classes in a VS project (i.e. circular compile-time dependencies). But
          then I started wondering how "easy" it would be to similarly make a
          NON-RUNTIME circular dependency between (implicitly linked) DLLs.
          Indeed authors like John Lakos, who focus on compile/link-time
          dependencies (not run-time), tell us to avoid such circular
          dependencies between "packages" (i.e. libraries). But to my surprise,
          evidently it isn't possible to create a circular library dependency
          even if you try...
          >
          Tonight I tried to make a circular dependency by creating two Win32
          console DLLs in a new VC++ solution, and attempted to make both have a
          (implicit link) dependency on the other. But no matter how I tried, in
          the end I always got a linker error about missing symbols - because DLL
          'A' needed the type library of DLL 'B', which did not exist yet because
          DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
          if I made both projects just static libraries (instead of DLLs).
          >
          In the end, I concluded that to make the circular dependency I would
          need to involve some kind of externalized interface descriptions - such
          as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
          would end up with something that is more akin to circular runtime
          dependency rather than a non-runtime dependency (and even then, it may
          no longer qualify as truly circular).
          >
          Can anyone give me an example of how DLLs (or even static LIBs) can get
          involved in a circular dependency? I'm scrutinizing this topic because
          authors like Robert Martin or John Lakos ("Large Scale C++") talk about
          how "packages" (aka libraries) should be forced away from cyclical
          dependencies. Well, why make all that effort of preaching against
          circular package/library dependencies, if its not even possible to make
          such circular dependencies in the first place?
          We had one where one lib required the header of the other and then
          there was a solid dependency the other way. I fixed that one.

          We also have some sort of funky cyclic dependency solved by compiling
          one into the exe and loading the other. I'll fix that one eventually.

          Comment

          • barias@axiscode.com

            #6
            Re: Circular Dependencies Between Libraries

            Start by creating two functions foo and bar that depend on each other:
            >
            Now compile these files separately: you have circularly dependent object
            files.
            >
            Create a static library from each: you have circularly dependent static
            libraries.
            The simplistic version you describe here, isn't possible. As soon as
            you try to link either one of these seperate object files, you will get
            a linker error. As another poster pointed out, between two libs 'A'
            and 'B', you'd have to make some kind of "3rd party" stub library -
            such as 'BStub', and have 'A' link against that.

            But using that kind of approach hearkens back to using something like
            IDL (which, when compiled, produces lib stubs - at least it does in the
            case of CORBA). As such, it is actually "difficult" to produce a
            circular dependency, people don't "accidental ly" use IDL in scenarios
            like this...

            Comment

            • Ivan Vecerina

              #7
              Re: Circular Dependencies Between Libraries

              <barias@axiscod e.comwrote in message
              news:1161278632 .591757.282510@ h48g2000cwc.goo glegroups.com.. .
              :Start by creating two functions foo and bar that depend on each
              other:
              : >
              : Now compile these files separately: you have circularly dependent
              object
              : files.
              : >
              : Create a static library from each: you have circularly dependent
              static
              : libraries.
              :
              : The simplistic version you describe here, isn't possible. As soon as
              : you try to link either one of these seperate object files, you will
              get
              : a linker error. As another poster pointed out, between two libs 'A'
              : and 'B', you'd have to make some kind of "3rd party" stub library -
              : such as 'BStub', and have 'A' link against that.
              :
              : But using that kind of approach hearkens back to using something like
              : IDL (which, when compiled, produces lib stubs - at least it does in
              the
              : case of CORBA). As such, it is actually "difficult" to produce a
              : circular dependency, people don't "accidental ly" use IDL in scenarios
              : like this...

              What you are facing is just a limitation of the tool chain you are
              using (or of your understanding of it).
              There is no need for such a thing as IDL or Corba. In your case it
              might be enough to comment-out the contents of the function body
              of either library to make a first compile. Then uncomment the code,
              rebuild that library, and you're done.

              Again, as others pointed out, the specifics of how to do this on
              the platform you are using are out of topic here.


              --
              http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

              Comment

              • Alf P. Steinbach

                #8
                Re: Circular Dependencies Between Libraries

                * barias@axiscode .com:
                >Start by creating two functions foo and bar that depend on each other:
                >>
                >Now compile these files separately: you have circularly dependent object
                >files.
                >>
                >Create a static library from each: you have circularly dependent static
                >libraries.
                >
                The simplistic version you describe here, isn't possible.
                T:\type con >foo.cpp
                void bar();
                void foo() { bar(); }
                ^Z

                T:\type con >bar.cpp
                void foo();
                void bar() { foo(); }
                ^Z

                T:\cl /GX /GR /c foo.cpp bar.cpp
                Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
                Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

                foo.cpp
                bar.cpp
                Generating Code...

                T:\lib foo.obj /out:foo.lib
                Microsoft (R) Library Manager Version 7.10.3077
                Copyright (C) Microsoft Corporation. All rights reserved.


                T:\lib bar.obj /out:bar.lib
                Microsoft (R) Library Manager Version 7.10.3077
                Copyright (C) Microsoft Corporation. All rights reserved.


                T:\dir /b *.lib
                bar.lib
                foo.lib

                T:\type con >main.cpp
                void foo();
                int main()
                {
                foo();
                }
                ^Z

                T:\cl /GX /GR main.cpp foo.lib bar.lib
                Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
                Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

                main.cpp
                Microsoft (R) Incremental Linker Version 7.10.3077
                Copyright (C) Microsoft Corporation. All rights reserved.

                /out:main.exe
                main.obj
                foo.lib
                bar.lib

                T:\dir /b *.exe
                main.exe

                T:\_


                As soon as
                you try to link either one of these seperate object files, you will get
                a linker error.
                Will I?

                As another poster pointed out, between two libs 'A'
                and 'B', you'd have to make some kind of "3rd party" stub library -
                such as 'BStub', and have 'A' link against that.
                Do I really have to?

                But using that kind of approach hearkens back to using something like
                IDL (which, when compiled, produces lib stubs - at least it does in the
                case of CORBA). As such, it is actually "difficult" to produce a
                circular dependency, people don't "accidental ly" use IDL in scenarios
                like this...
                Sorry, that's techo-babble.

                --
                A: Because it messes up the order in which people normally read text.
                Q: Why is it such a bad thing?
                A: Top-posting.
                Q: What is the most annoying thing on usenet and in e-mail?

                Comment

                Working...