Share Projects in one solution

Dear all,

I create two projects, say A and B, in one solution in VC.net 2003. They are basically 2 executable applications, A.exe and B.exe.

 < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

In project A, it uses some classes created in project B. I include the header B.h in A.h, and add Additional Include Directories to which B.h resides.

 

Compile is OK but when linking it looks like the LINKER does not know where to link obj in B project and gives the error messages like this:


ATest error LNK2019: unresolved external symbol "public: __thiscall HelloWorld::~HelloWorld(void)" ( 1HelloWorld@@QAE@XZ) referenced in function _main

I do not want to create B project to B.lib.  How can I share these classes between projects in the solution

 

Thank you.



Answer this question

Share Projects in one solution

  • DomL

    Don't use precompiled header settings.

    In general: I always place #include "stdafx.h" in every cpp file of my projects. because I always use precompiled headers. At least windows.h is included there or afx.h.


  • Todd Biggs - Windows Live

    I recommend you not to share on a OBJ file base. It is much more complicated than sharing source.

    To add files on a obj level, can be done in adding the obj file to the project (with the problem that you can't make a difference between debug and release files).
    Better is. Open the project properties. Select linker, select input. Add the files (obj or LIB) to the field Additional Dependencies.

    The CRT is the C-Runtime-Library. Thee is a static one, static-Debug, DLL-Version, DLL-Debug-Version.
    You see: Depending on the versions you have to compile a file the specific CRT version is chosen. CRT versions shouldn't never be mixed in on project.

    You ask me why to create so many projects Each target file: EXE, DLL, LIB, TSP whatever is a project!

    I may repeat myself.
    Sharing files between can be done on very different ways. (See my first post). The most common way to share source code on a OBJ level is to add them into a library.

  • Socrates Kapetaneas

    Dear Martin,

    Thank you for your reply.  Would you please tell me how to add the obj files to the linker option   I cannot find the associated options that can do this in the project properties setting.  I think I am going to try this method first to see how it works before creating other DLL or LIB solutions.

     < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    What is CRT I think I do not use any fancy compile options and all obj files should be sharable, right   Maybe I do not know yet!  How similar option is similar

     Martin Richter wrote:
    The linker knows only files you add to a project and you add to the linker options. There no knowledge beyond that.
    So it looks like I have to link all the required obj files to the LINKER manually too if I pursue this method.


     Martin Richter wrote:
    The dependencies of projects and solutions are like a tree. The leaves can not be shared between the different paths of the tree! This rule is manifest and you can only trick around like I wrote in my tips.
    Then looks like I should contain all files in one project!  Only store them into different folders to make it looks cleaner.  In this case, all files should be sharable without any efforts needed, right   Then why do I need to create so many different projects


  • Demid

    But it will cause problem when the cpps in the project are in different dir. At such circumstance, i have to add "." in my additional including path, or the compiler may complain that it cannot find "stdafx.h" (Not always, but just sometimes, I don't know why). This is especially annoying when i add some shared cpp into new project
  • Leland Gary

    You can directly share the obj file. You can include the object file from another project into your project.
    But!!!! The compiled file depends on the way it was build. So there is a debug build and a release build. In both cases the object you want to share must be compiled with similar options. Otherwise multiple version of the CRT might be loaded and memory allocation might fail in a catastrophic way.

    The linker can link the object file. The only thing is (as I wrote above) add the object file to the project or add the object file to the linker options. The later method is better because you can use different options for debug and release build.

    The linker knows only files you add to a project and you add to the linker options. There no knowledge beyond that.
    The dependencies of projects and solutions are like a tree. The leaves can not be shared between the different paths of the tree! This rule is manifest and you can only trick around like I wrote in my tips.

  • lschiedel

    Now I encounter a great difficulty in the method of copying around cpp and h files between two projects.

     < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    Project A is a MFC application.  I add the following cpp and h into this project and it works fine.

     

    Mock.h:

    #pragma once

     

    class Mock

    {

    public:

                Mock(void);

                ~Mock(void);

                int add(int x, int y);

    };

     

    Mock.cpp

    #include ".\mock.h"

     

    Mock::Mock(void)

    {

    }

     

    Mock::~Mock(void)

    {

    }

     

    int Mock::add(int x, int y) {

                return x+y;

    }

     

    Project B is a Win32 console project.  After copying these two files into B project, I have to add #include "stdafx.h" at the top of cpp file in order to compile it successfully.  Strange that Project A does not require this include!  So it turns out that I have to maintain two copies of files individually!

     

    I have tried to tune all the combinations of compile options to make them compromise but all in vain.  What the heck is going on here  


  • Fritzenhammer

    In theory possible with a custom build step.
    Never tried it.

  • FredrikRN

    The header file alone is not enough. The code that is compiled is inside the a.ob/b.obj file that is ceated form the cpp file.

    There are more solutions to this.
    1. Use a source control system (VSS) and share both files. Than there is a copy of each file in each project, but the file contents is controlled by the source control system (this is the way I prefer).
    2. Build a 3rd project with the shared part as a static LIB, include this into the other project as dependency.
    3. Just include also the cpp from the other directory (I don't like this because the projects are to tightly coupled)
    4. Create a DLL project with the shared code and include this to the other projects.

    And there a still more options you have.
    3.

  • Bryan Roth

    It looks like adding #include "stdafx.h" in each file is a good idea.  My project setting has been in not using Precompiled Headers setting all the time.  There are some files include stdafx.h; whereas others are not. The project can build to executable application without any problems in this juncture until I try to add the Mock.h/cpp mentioned above into this project to test some functions.  Definitely, without including stdafx.h, it can compile; however, with stdafx.h included, it gives me error message: fatal error C1189: #error :  Please use the /MD switch for _AFXDLL builds.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    After switching from /MTd to /MD, it acts like the chain-effects and turns out more errors when linking.

     

    Googling around it looks like this is a very common question, but so far I still cannot get a clear idea on what the concept behind to avoid my try-and-error to each options in project properties.


  • Ed Graham

    I agree, but it can be solved with a project setting.
    So its not really a problem.

    The major idea is that each of my cpp files should be sharable between projects. In this case I make sure that a stdafx.h is used.

    Another solution is a per file setting in the project. You can remove the usage of precompiled headers on this specific cpp file, but this causes much longer compile times. So I prefer using a stdafx.h file always!

  • Guns

    You added just the name documents.obj. In this case you have to add the complete path name. As I said, this is not practical. Use on of the techniques I mentioned before.

  • pellis

     Martin Richter wrote:

    Better is. Open the project properties. Select linker, select input. Add the files (obj or LIB) to the field Additional Dependencies.


    I have done this already but the linker gave me the error:

     < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    fatal error LNK1104: cannot open file 'C:\Documents.obj'

     

    Where can I find this mysterious obj

  • Christophe Lauer

    Thank you, Martin.

    That is why I do not understand.  Compiler can generate both a.obj and b.obj in A project.  But b.obj is not good enought for A project LINKER   Then how come the LINKER cannot link a.obj in A project and b.obj in B project, instead of in A project

     < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    Though A and B physically resides in different folder, that does not mean the LINKER cannot link a.obj in A and B.obj in B, right   Do you think this method might work   Because by using this way, I hope the LINKER can pick up the required obj in B project automatically.

     

    By the way, since b.obj has been created by B project, why does A project need to compile another b.obj in its Debug folder   The compiler should know b.obj exist and skip compile it.  The LINKER then should know where to pick up the needed obj files, shouldn't it

     

    I think 2 and 4 are the same.  The difference is one is a static LIB and the other is DLL; however, both of them require me to create another project and include all files (cpp and h) needed by B project from A project manually and laboriously.  Besides, one piece of same code will be compiled 3 times.  To deploy B project, compile once.  To deploy A project, it will compile B project again but it is not good enough for the LINKER.  Then, create C project as LIB or DLL, definitely it needs to compile the same codes again!


    Same thing with solution 1, it creates an additional copy. 

     


  • Ben Strauss

    Yah, I add the full path of MY obj files.  'C:\Documents.obj' is not mime.  I do not know what and where this mysterious obj come from!

     < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    Actually I have used your method 1 already.  I add the needed files by using Add Existing Item…and yes, it works fine.  Also if I edit the files added from other projects, it actually edits the original files reside in their original projects individually, which is good.

     

    However, as I mentioned previous, it is a little bit time consuming because the added file will be compiled at least twice.  One is in its own projects; the other is in the project that adds these files to.

     

    So my idea is since B project is deployed, there are definitely some generated obj files we can reuse without compiling again.

     

    Well, unless there is a way to build a project into exe application and LIB at the same time and only compile once.  Can I do that

     

    Thank you.


  • Share Projects in one solution