I'm working on a solution file (VS 2005) which contains multiple projects.
There are two projects of my concern right now - one called core and another called log.
The core project is the startup project and the log project has core ticked in its project dependencies.
I have two files in core project - AB.h(declarations) and AB.cpp(definitions)
Many other cpp files from the core project refer to AB.h and has no issues finding the definitions in AB.cpp.
Now comes the issue. I have a cpp file called CD.cpp in the log project which requires referring to AB.h. I have added the include directory of AB.h to both the core and log projects (AB.cpp also resides in same folder)
In addition the log project has $(OutDir) in its "Additional Library Directories" parameter in the Linker part of project settings. Also have added "core.lib" to the Additional Dependencies field in Properties->Linker->Input
The core project compiles into a dll but there is also a core.lib in the same folder amongst other junk. Solution compiled as the Release version.
In CD.cpp, when I right click the #include "AB.h" line, it takes me to .h file in the core folder. So far everything is fine. However when I try to compile the solution, the log project does not build properly, showing these two linker errors.
log.obj : error LNK2001: unresolved external symbol "class myNamespace::myClass myInstance" (?myInstance##3VmyClass#myNamespace##A)
log.obj : error LNK2001: unresolved external symbol "bool infFlag" (?infFlag##3_NA)
The class is part of an h file included in AB.h (instance declared in AB.cpp and included as extern in CD.cpp. infFlag is declared in AB.cpp and declared in CD.cpp as extern.
What do I do to let log build properly? Thanks
OK. You guys need more details. Sure.
One Solution file. Multiple Projects.
[Core]
includes AB.h and AB.cpp
-AB.h
--includes EF.h from external lib (functions from this lib is working properly for files within the same core project).
--declares some functions
-AB.cpp
--defines those functions which was declared in AB.h
-some other cpp files which can use those functions from AB.h without issues
[/Core]
[Log -> Project Dependencies -> Core]
-No h files
-CD.cpp
--requires AB.h to work. Is included with a #include command and its linked properly (I can right click and click "open file" to open the real .h file)
--uses functions from AB.h
[/Log]
Hopefully this will better let you guys understand the project structure in my solution.
Issue comes when compiling Log project. It always comes up with a link error for any references to functions in AB.h saying "unresolved external symbol". I guess this comes because it cannot find the definitions for the functions declared in AB.h (probably because it is a different project). Since log is dependent on core, and core will have compiled as of then, I added in $(OutputDir) to Library directories (both core and log build into the same directory) so that it can find core.lib and also added "core.lib" to "Additional Dependencies" under Input tab under Linker (in project properties).
So there you go. Any ideas?
In addition the log project has $(OutDir) in its "Additional Library Directories" parameter in the Linker part of project settings.
Probably wrong. It should be that dir where "core.lib" resides, the $(OutDir) is where the log will be put.
The class is part of an h file included in AB.h (instance declared in AB.cpp and included as extern in CD.cpp. infFlag is declared in AB.cpp and declared in CD.cpp as extern.
So where are definitions?
Related
I have a C++ .h and .cpp file from another project that I want to include into my project.
I don't want to copy the files over into my project since I want any changes to those files be applied to both projects.
I've included the directory of the file's folder in the
Properties->VC++ Directories->Include Directories
I've also included the folder in the
Properties->C/C++ -> General -> Additional Include Directories
The .h files seem to work. If I rename the include to anything other than
#include "myfile.h"
The cpp file gets unknown definitions.
When I compile. The error is
fatal error C1083: Cannot open source file: '..\..\..\..\..\..\my project\myfile.cpp': No such file or directory
If I remove the cpp file from the project. Then I get a long list of unresolved functions.
error LNK2019: unresolved external symbol "public: unsigned long __thiscall myclass::myfunction"
How can I include both the .h and .cpp file into my second project?
For cpp files you can just use right mouse click on project, select "add"->existing item.
Then they should compile with others, when a build initiated.
Slightly more complicated with headers. There is two ways to use #include directive:
with < > and " " braces
When " " braces used, compiler treats path as relative (if not absolute used) to location of cpp file.
When < > braces used, compiler looks for file in something like system include folders. For example - stdlib headers folder and windows.h location folder. Properties entry Additional Include Directories also goes there.
I suggest you to change projects structure and extract shared features from both projects to compile it as static library. Place shared headers in some subfolder inside library project and refer then as
#include "mylibHeaderDir/someheader.h"
In dependent projects, after setting Additional Include Directories you can refer theese includes as
#include <myLibHeaderDir/someheader.h>
This approach will help you in future, as you can reuse that shared module in every project you want.
About how to create and link static library you can read this article http://msdn.microsoft.com/en-us/library/vstudio/ms235627(v=vs.110).aspx Version of visual studio may be differ, but basics are the same.
You can't just pick files like that. There are two reasonable ways to solve it. 1, shared the file by means of a Code Versioning System (e.g. svn/git). 2, compile the the .cpp into a library and link to that library.
If the cpp can be used by multiple projects, it must mean that the code is something common. That means you should compile that code by itself into a library and then share that library. Compiling the same cpp into multiple libraries is likely to result in conflicts later if two such libraries are ever needed to work together.
Try to drag them into your solution?
You can create a new folder in your solution, and drag them all into this folder!
I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).
The compilation gave the following output:
1 Debug\is.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\make.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\view.obj : warning LNK4042: object specified more than once; extras ignored
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl
test::identity::view(void) (?view#identity#test##YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity#0test##YAXXZ)
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl test::identity::make(void) (?make#identity#test##YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity#0test##YAXXZ)
1 range.obj : error LNK2019: unresolved external symbol void __cdecl test::range::is(void) (?is#range#test##YAXXZ) referenced in function void __cdecl test::range::range(void) (?range#0test##YAXXZ)
Linker errors are always a pain to debug... but there were unresolved references, and so I checked... but the source is well-formed... and finally it hit me:
My folder hierarchy looks like so:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
and so does the hierarchy in the Solution (I always set it up so that it mimicks the "real" folder structure).
And the diagnostic outputs:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Along with a warning which says that the .obj has been passed twice to the linker and that one will be ignored.
Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.
At the moment, I am simply thinking of renaming the files, that should cover the issue...
... but is there a way to have Visual Studio NOT flatten the file hierarchy ?
I had a similar problem with linker warning LNK4042: object specified more than once; extras ignored. In my case Visual Studio was trying to compile both header and source files with the same name - MyClass.h and MyClass.cpp. It happened because I renamed .cpp file to .h and Visual Studio got confused. I noticed the problem by looking at the compiler logs in the Debug directory. To resolve just remove .h file from the project then add it again.
Just wanted to cross post what I believe to be the answer, if you open the properties for the entire project, and the change the value under C/C++ -> Output Files -> "Object File Name" to be the following:
$(IntDir)/%(RelativeDir)/
Under VS 2010, I believe this will disambiguate all of the object files (as I believe windows won't let you under any crazy circumstances have two files with the same names in the same directory). Please also check out the details here.
Right-click the .cpp file in the Solution Explorer window, Properties, C/C++, Output Files, Object File Name setting. The default is $(IntDir)\, that's what is doing the flattening. All the .obj file will go into $(IntDir), the "Debug" directory in the debug configuration.
You can change the setting, say $(IntDir)\is2.obj. Or select all the files from one group (use Shift+Click) and change the setting to, say, $(IntDir)\identity\
Or you can change the .cpp filename so that .obj files don't overwrite each other. Having files with the exact same name in two directories is a bit odd.
Or you can create multiple projects, creating, say, .lib projects for the files in identity and range. Commonly done in makefile projects for example. That does however make managing the compile and link settings more of a hassle unless you use project property sheets.
Right click on header file -> Property -> ItemType (select C/C++ Header). Do the same with Cpp file but select C/C++ Compiler (it's work for me)
Alternatively to deleting and making a new file you can change the compile/include settings.
Go to your project.vcxproj file, open it with an editor, find the html like line <ItemGroup>.
It should look something like:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
and
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
Assuming your implementation files are .cpp and your declarations are .hpp. Make sure your all your implementation files are listed between the first section if you have more then one and likewise for the second section for multiple declaration files.
I had this problem with stdafx.cpp. Somehow stdafx.cpp got duplicated, so there was a second StdAfx.cpp (mind the different case).
After I removed the StdAfx.cpp everything worked fine!
Using VS 2010.
I use $(IntDir)\%(Directory)\ under C/C++ -> Output Files -> "Object File Name".
I used to have in the same project .c and .cpp files with the same filenames. The files were in folders all over the place and the solutions provided by others created a mess, and folder hell (in my case). Even Release builds would overwrite Debug builds!
A good (not perfect) solution would be to use $(ParentName), but for some reason beyond anyone's grasp it has been removed from later versions of Visual Studio (2015+).
What I use succesfully now is:
$(IntDir)%(Filename)%(Extension).obj
which at least separates .c built object files from .cpp.
I'd like to point out one possible reason for why the ItemType of a .h file would change from C/C++ header to C/C++ compiler:
In the Solution Explorer window of VS (2019 here), right click the project name, choose Add -> New Item;
Select the C++ File (.cpp) template, but type something.h in the name input area, then click OK to add it;
Then you'll encounter the LNK4042 warning if the something.h file be included within more than one .cpp files.
I just overcame a similar error message, and lots more with the procedure below. Symptom: one linker error for every invocation of every function defined in a particular header, plus one at the end of output for every function defined in the header.
Then I remembered that when I had originally created this header, I accidentally had selected "add->new item->c++ file" and though I named it 'whatever.h', it seems Visual Studio considered them both the same kinds of files because of the incorrect action I used to add one. Examining the build output logs made this obvious.
SOLUTION (Using VS Community 2019)
Back up project first (just to be safe).
Right-click the offending header file and select "Exclude from project" (this will not delete them; the VS project will just ignore them).
Do same for the matching .c or .cpp file.
Do Build->Clean on project
Do Build->Rebuild on project
-- there of course will be errors---
Right-click Header Files->Add->Existing Item, then select the .h file
Right-click Source Files->Add->Existing Item, the select the .c or .cpp file
Do Build->Rebuild on project.
This completely cleaned it up for me, relieving me of many irritating linker errors including LNK4042 from the title of this question.
I resolved it changing filenames in my project. There was two files named main.c and main.cpp. I changed one of them and worked.
I have been able to work in the same project for sometime now, writing and successfully running c++ code. However, I discovered that I am still missing some essentials on how to export my .h files to another project and successfully use them in there.
I created a second project, project B to test the classes I have in project A.
visual c++: #include files from other projects in the same solution
I added the path of the header file in Project A into the Additional Include Directories(C\C++>general and Linker>general) section in the project configuration of Project B. I tried following the tutorials on this page http://msdn.microsoft.com/en-us/library/ms235636.aspx but I still end up with the error below
** LINK : fatal error LNK1104: cannot open file 'C:\Users\LaC\Projects\OSGB\Debug\OSGB.lib**
I would appreciate any help in understanding exactly how this is done so that in future, when I encounter this problem, I can know how to troubleshoot.
The code below is all I am working with.
IN PROJECT A
=============
//Utility.h
class Utility
{
private:
protected:
public:
Utility(void);
~Utility(void);
double square_root (const double);
};
//Utility.cpp
#include "StdAfx.h"
#include "Utility.h"
Utility::Utility(void)
{
//do nothing for now
}
Utility::~Utility(void)
{
//do nothing for now
}
double Utility::square_root (const double)
{
return 0;
}
IN PROJECT B
===============
#include "gtest/gtest.h"
#include "Utility.h"
TEST (SquareRootTest, PositiveNos) {
Utility u;
EXPECT_EQ (50.3321, u.square_root (2533.310224));
}
There are two (general) ways to include files into your project:
Make them a part of your project (adding them from the solution explorer) OR
Import them as a library (static or dynamic linking)
If you make them part of your project, then you have to add the header and the source files in order for the project to compile correctly. However, that's usually not what you want to do, as it defeats the purpose of having external libraries.
The second case is to use the external libraries, which requires that you:
Include the header files which are exported by the library in your C++ properties.
For static linking: you also have to include the *.lib file (the output of building the library) in the Linker properties.
OR
For dynamic linking: see tutorial.
So remember: there are two parts to building a C++ project- compiling and linking.
Compiler Errors:
If you get an error whose code starts with C* (e.g. C1083) and is related to problems header with the files, then check the Properties-> C/C++ -> General -> Additional Include Directories.
Linker Errors:
If you get an error whose code starts with LNK*, then check
Properties -> Linker -> General -> Additional Library Directories (make sure that this points to where the *.lib file is located)
AND
Properties -> Linker -> Input -> Additional Dependencies (make sure that the *.lib file is added here).
If you're dynamically linking, then check that you're correctly referencing the DLL.
So in your case, you have to determine if you're linking statically or dynamically and then make the appropriate references. So ware you getting those header files from a dynamically library or a static library?
When the linker emits unresolved external symbol for a symbol that lives in another library (DLL or shared library), this indicates that you need to link your app to that other library's .lib file. That is most likely what's happening here.
For more information see:
(MSDN) Walkthrough: Creating and Using a Dynamic Link Library (C++)
I have inherited a VC++ solution and from one project (named "IntersonWinDriver") I'm trying to link to a .lib file that is generated by a different project (named "Utility"). I noticed that in a different project, named "MasterVu", I found "Utility.lib" included among the linker command line options.
In order to duplicate this for the IntersonWinDriver project, under the properties window I selected Configuration Properties->C/C++->General. I added the folder containing the code for the Utility project under the "Additional Include Directories" option. I then added the Utility project as one of the project dependencies for IntersonWinDriver.
The problem is that when I look at the linker command line options, I don't see any reference to Utility.lib as with the MasterVu project. I could manually add a reference to Utility.lib under Configuration Properties->Linker->Input, but I would rather not. What am I missing here?
As you may guess, I'm getting an unresolved external symbol error due to any reference in IntersonWinDriver to code written under the Utility project.
Hmm...I see that under Common Properties->Framework and References I can add the Utility project. Now I feel silly for asking this question too soon...
I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).
The compilation gave the following output:
1 Debug\is.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\make.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\view.obj : warning LNK4042: object specified more than once; extras ignored
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl
test::identity::view(void) (?view#identity#test##YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity#0test##YAXXZ)
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl test::identity::make(void) (?make#identity#test##YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity#0test##YAXXZ)
1 range.obj : error LNK2019: unresolved external symbol void __cdecl test::range::is(void) (?is#range#test##YAXXZ) referenced in function void __cdecl test::range::range(void) (?range#0test##YAXXZ)
Linker errors are always a pain to debug... but there were unresolved references, and so I checked... but the source is well-formed... and finally it hit me:
My folder hierarchy looks like so:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
and so does the hierarchy in the Solution (I always set it up so that it mimicks the "real" folder structure).
And the diagnostic outputs:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Along with a warning which says that the .obj has been passed twice to the linker and that one will be ignored.
Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.
At the moment, I am simply thinking of renaming the files, that should cover the issue...
... but is there a way to have Visual Studio NOT flatten the file hierarchy ?
I had a similar problem with linker warning LNK4042: object specified more than once; extras ignored. In my case Visual Studio was trying to compile both header and source files with the same name - MyClass.h and MyClass.cpp. It happened because I renamed .cpp file to .h and Visual Studio got confused. I noticed the problem by looking at the compiler logs in the Debug directory. To resolve just remove .h file from the project then add it again.
Just wanted to cross post what I believe to be the answer, if you open the properties for the entire project, and the change the value under C/C++ -> Output Files -> "Object File Name" to be the following:
$(IntDir)/%(RelativeDir)/
Under VS 2010, I believe this will disambiguate all of the object files (as I believe windows won't let you under any crazy circumstances have two files with the same names in the same directory). Please also check out the details here.
Right-click the .cpp file in the Solution Explorer window, Properties, C/C++, Output Files, Object File Name setting. The default is $(IntDir)\, that's what is doing the flattening. All the .obj file will go into $(IntDir), the "Debug" directory in the debug configuration.
You can change the setting, say $(IntDir)\is2.obj. Or select all the files from one group (use Shift+Click) and change the setting to, say, $(IntDir)\identity\
Or you can change the .cpp filename so that .obj files don't overwrite each other. Having files with the exact same name in two directories is a bit odd.
Or you can create multiple projects, creating, say, .lib projects for the files in identity and range. Commonly done in makefile projects for example. That does however make managing the compile and link settings more of a hassle unless you use project property sheets.
Right click on header file -> Property -> ItemType (select C/C++ Header). Do the same with Cpp file but select C/C++ Compiler (it's work for me)
Alternatively to deleting and making a new file you can change the compile/include settings.
Go to your project.vcxproj file, open it with an editor, find the html like line <ItemGroup>.
It should look something like:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
and
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
Assuming your implementation files are .cpp and your declarations are .hpp. Make sure your all your implementation files are listed between the first section if you have more then one and likewise for the second section for multiple declaration files.
I had this problem with stdafx.cpp. Somehow stdafx.cpp got duplicated, so there was a second StdAfx.cpp (mind the different case).
After I removed the StdAfx.cpp everything worked fine!
Using VS 2010.
I use $(IntDir)\%(Directory)\ under C/C++ -> Output Files -> "Object File Name".
I used to have in the same project .c and .cpp files with the same filenames. The files were in folders all over the place and the solutions provided by others created a mess, and folder hell (in my case). Even Release builds would overwrite Debug builds!
A good (not perfect) solution would be to use $(ParentName), but for some reason beyond anyone's grasp it has been removed from later versions of Visual Studio (2015+).
What I use succesfully now is:
$(IntDir)%(Filename)%(Extension).obj
which at least separates .c built object files from .cpp.
I'd like to point out one possible reason for why the ItemType of a .h file would change from C/C++ header to C/C++ compiler:
In the Solution Explorer window of VS (2019 here), right click the project name, choose Add -> New Item;
Select the C++ File (.cpp) template, but type something.h in the name input area, then click OK to add it;
Then you'll encounter the LNK4042 warning if the something.h file be included within more than one .cpp files.
I just overcame a similar error message, and lots more with the procedure below. Symptom: one linker error for every invocation of every function defined in a particular header, plus one at the end of output for every function defined in the header.
Then I remembered that when I had originally created this header, I accidentally had selected "add->new item->c++ file" and though I named it 'whatever.h', it seems Visual Studio considered them both the same kinds of files because of the incorrect action I used to add one. Examining the build output logs made this obvious.
SOLUTION (Using VS Community 2019)
Back up project first (just to be safe).
Right-click the offending header file and select "Exclude from project" (this will not delete them; the VS project will just ignore them).
Do same for the matching .c or .cpp file.
Do Build->Clean on project
Do Build->Rebuild on project
-- there of course will be errors---
Right-click Header Files->Add->Existing Item, then select the .h file
Right-click Source Files->Add->Existing Item, the select the .c or .cpp file
Do Build->Rebuild on project.
This completely cleaned it up for me, relieving me of many irritating linker errors including LNK4042 from the title of this question.
I resolved it changing filenames in my project. There was two files named main.c and main.cpp. I changed one of them and worked.