Dealing with multiple projects in visual studios - c++

I am trying to figure out how to deal with multiple projects under the banner of a single solution and how to correctly link projects in order to make things work in conjunction.
I began by making two projects in one solution - for simplicity's sake, ProjA and ProjB. ProjB is set as the StartUp project. Furthermore, ProjA is configured to be built as a .dll file which I am to link with ProjB, which in turn is configured to be built as a .exe file. So far I've linked ProjA to ProjB by adding a dependency to ProjB via referencing (RMB>Add>Reference).
With all that out of the way, I wanted to test whether the setup worked as intended. So I did the following. In ProjA, I wrote the following Test code:
Test.h
#pragma once
namespace ProjA {
_declspec(dllexport) void Print();
}
Test.cpp
#include "Test.h"
#include <stdio.h>
namespace ProjA {
void Print()
{
printf("Testing\n");
}
}
And in ProjB:
TestEntry.cpp
#include <stdio.h>
namespace ProjA {
_declspec(dllimport) void Print();
}
void main()
{
ProjA::Print(); //breakpoint1
printf("Testing (2)\n"); //breakpoint2
}
I set two breakpoints at the commented lines for debugging, built the projects and ran the program. At breakpoint1, I expected the console to print "Testing" and proceed to the next line, followed by breakpoint2 printing "Testing (2)" and proceeding to the next line before exiting. However, the console was blank at breakpoint1. It only printed the line from the main function at breakpoint2.
So what am I doing wrong here? Is there something wrong with the way I included the projects? Was there a linking procedure I skipped? Is there a specific way I need to set up Visual Studios 2017 in order for it to work? Are there other plugins/APIs I should be installing?
To test it out further, I commented out everything in ProjA. This time I expected a linking error when building the projects, but everything ran in the exact same manner. This confused me even more. It's as if I didn't even link the projects and the main function is not identifying the Test codes via the include. That's the only thing I could deduce so far.

As suggested by SoronelHaetir, I redid the whole thing using #defines and namespaces. It's working as intended now. In conclusion, the crude method was a bad idea from the getgo.

Related

How can I create a c++ header file in Visual Studio Code?

I have a program with 3 files, and when IrRun the program via Code Runner it keeps printing errors.The icon for the "Log.hpp" file is C, not C++. It doesnt matter if I rename it to Log.h or anything, it seems that I cant create a c++ header file in vscode.
The 3 files are:
main.cpp
#include <iostream>
#include "log.hpp"
using namespace std;
int main() {
InitLog();
Log("Hello World");
return 0;
}
log.cpp
#include "log.hpp"
#include <iostream>
void InitLog() {
Log("Initializing Log");
}
void Log(const char *message) {
std::cout << message << std::endl;
}
log.hpp
#pragma once
void InitLog();
void Log(const char *message);
The error mesages are:
main.cpp: In function 'int main()':
main.cpp:5:5: error: 'InitLog' was not declared in this scope
InitLog();
^~~~~~~
main.cpp:6:5: error: 'Log' was not declared in this scope
Log("Hello World");
Need help.
Are you using Windows? Which compiler? Do you have Microsoft Build Tools installed or even Visual Studio? Are you using gcc or clang?
You must start VS Code from a developer prompt: Open a developer prompt console, navigate to the folder where you code is. Then enter
code .
Visual Studo Code will then open with the environment set up. Then open a terminal inside VSCode using Control-` and try
cl /EHsc main.cpp log.cpp
And it will create main.exe. You can run it in the terminal and it will not close... Next time you open the project you can just open the folder in VS Code, since it would then already have the json config files created
VS Code is just an IDE. So compilers must be installed and also extensions. And some JSON files and tasks must be set up. It is sometimes simple, sometimes not so simple, I believe. But doing that you will then have a powerful editor and an unbelievably flexible environment, since you can for instance run and debug code in nodejs or C or C++ or anything and even in Linux without leaving the session on your casual Windows machine.
Your question is about a specific vscode plugin called Code Runner. It's not really related to vscode. The way how Code Runner is designed will never work for multiple C++ source files. It's not the right tool for the job.
Perhaps you'd better off with Microsofts CMake Tools package for vscode. It does require you to create your own CMakeLists.txt file though. In your case you'd need nothing more than:
add_executable(log
main.cpp
log.cpp
)

Where to put implementation when using Doctest alongside code

I'm using doctest for the tests in my C++ project.
I would like to put the test code alongside my implementations, as the library says is possible, but I can't seem to figure out what to do with the doctest implementation code.
I have a doctest.cpp file that looks like this:
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
A main.cpp that looks like this:
#include "thing.h"
int main(int argc, const char *argv[]) {
do_thing();
}
thing.h is self-explanatory, but thing.cpp looks like this:
do_thing() {}
TEST_CASE("Test thing") {
CHECK(1 == 1);
}
CMake is used to create two executables, a Tests executable and a Main executable.
If I don't include doctest.cpp in my project sources for Main, I get undefined reference errors because it can't find a definition for all the testing stuff in doctest.
However, if I do include it I get errors because there are multiple main() functions in one target.
I can't find any info on this in the doctest documentation.
How are you meant to get around this?
The author of the library gave a good response in this issue:
DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN implements the test runner and also defines a main() function.
DOCTEST_CONFIG_IMPLEMENT implements ONLY the test runner.
If you define your own main() then you should use DOCTEST_CONFIG_IMPLEMENT - have a look at the relevant docs.
You will need the test runner implemented in your main executable (that means doctest.cpp) since you are writing your tests alongside your production code.
You can also define DOCTEST_CONFIG_DISABLE when building the main executable so tests are written in the production code but aren't compiled (you will still need doctest.cpp so it all links). This way you won't need to #ifdef the tests.
You could also entirely remove the test executable and use the main executable for running the tests - docs.
I went with the first option of writing my own main() function.
I encountered the same problem and one workaround is to add -DDOCTEST_CONFIG_DISABLE to the compiler flags when you compile Main.

Eclipse CDT Including Unreferenced Files in Automatically Generated Build

I'm new to cpp in eclipse and trying to mess with simple builds. I have made a basic project which automatically generates build info (no user-defined makefile).
Simple (Working) Case
I made a "Hello World" project called Test (not an empty project). It has one file - Test.cpp with a main() in => builds and runs fine.
Test.cpp
int main() {
// output some stuff
}
Slightly More Complex (Working) Case
I make a new file called Main.cpp. Move the main() function into Main.cpp and make a decleration of a function in main too - void test();
The test() function lives in Test.cpp, which is where I provide the function definition.
Main.cpp
#include <iostream>
void test();
int main() {
// Use test()
}
Test.cpp
#include <iostream>
void test() {
// output some stuff
}
Build it, there are now two .o files in the Debug directory - Test.o and Main.o. This runs fine.
The Problem
Now I try to introduce a third file - Limits.cpp.
Limits.cpp
#include <iostream>
void printLimits() {
// Print out limits for different integer sizes
}
Again I provide a deceleration of this function in Main.cpp.
Main.cpp
#include <iostream>
void test();
void printLimits();
int main() {
// Use printLimits()
}
This time there is no object file created for Limits in the Debug folder => the build fails.
Main.cpp:*line* undefined reference to `getLimits()'
It just looks like the autogenerated build config for the project is duff. I've tried looking around the project properties but I have had no luck. I've tried including the path/file in Include Paths/Include files, other objects, and I've checked just about every other property I can see. This has been frustrating me for two days.
The strange thing about this is case 2. It looks like because Test.cpp was the first file made it always includes this in the build? (even if it is not imported). Where as because Limits.cpp is new and not imported it doesn't generate an object file so it can't link the function.
I could me making an error by needing to include the files but my understanding is if all the object files make it to the linker then all will be well (ie I just need the function declarations when making the object files which is what I have here).
With a "Blank project" it seems to compile all the cpp files even if they are never used so my case above works. (Although, it doesn't work for files in subfolders of src). Looks like its a "feature" of the "Hello world" project type but it's going to drive me crazy knowing there must be a way to get it to do this.
If anyone knows if it is possible to include this file without writing my own makefile (I'm not a makefile guru (yet!)), or let me know if this is not possible with autogen CDT that would be great.
Using MinGW GCC toolchain.
Thanks

Code coverage error (No binaries were instrumented)

Problem:
Microsoft Visual Studio Enterprise 2015
Version 14.0.25431.01 Update 3
I'm attempting to use the code coverage function but it returns this error:
Empty results generated: No binaries were instrumented. Make sure the
tests ran, required binaries were loaded, had matching symbol files,
and were not excluded through custom settings. For more information
see http://go.microsoft.com/fwlink/?LinkID=253731
My .coverage file is full of non-sense, starting with "PCHÿ". I thought my problem looked similar to this one: Issue with Code Coverage in VS 2012, but deleting the .suo file and running Visual Studio in admnistrator didn't solve anything.
How to replicate:
1) Create new empty project "MyProject"
2) Add new file "Calculator.hpp"
#pragma once
class Calculator
{
public:
int add(int a, int b);
int sub(int a, int b);
};
3) Add new file "Calculator.cpp"
#include "Calculator.hpp"
int Calculator::add(int a, int b)
{
return a + b;
}
int Calculator::sub(int a, int b)
{
return a - b;
}
4) Add new file main.cpp
#include "Calculator.hpp"
#include <iostream>
using std::cout;
int main()
{
Calculator calc;
std::cout << calc.add(5, 11) << std::endl;
std::cout << calc.add(11, 1) << std::endl;
return 1;
}
5) Build solution. (0 errors)
6) Add new test project to solution as explained here: https://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef:
Add new Native Unit Test Project to solution "CalculatorUnitTest"
Add "main.obj" and "Calculator.obj" to Linker/Input/Additional Dependencies of "CalculatorUnitTest"
Add path to obj files to Linker/General/Additional Library Directories of "CalculatorUnitTest". (In my case: D:\JF\Programming\Tests\MyProject\MyProject\Debug)
Add the header directory of "MyProject" to VC++ Directories/Include Directories. (In my case: D:\JF\Programming\Tests\MyProject\MyProject).
7) Replace code in "unittest1.cpp" with:
#include "stdafx.h"
#include "CppUnitTest.h"
#include <Calculator.hpp>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorUnitTest
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
Calculator calc;
Assert::AreEqual(5, calc.add(2, 3));
}
};
}
8) Build solution (0 errors, TestMethod1 appear in Test Explorer)
9) Right-click TestMethod1, "Run Selected Tests" (Test successfully passes)
10) Right-click TestMethod1, "Analyze Code Coverage for Selected Tests" (Code coverage fails).
At D:\JF\Programming\Tests\MyProject\Debug, I have both my MyProject.exe and MyProject.pdb with the CalculatorUnitTest.dll.
First of all, I am not sure if Visual Studio 2015 (C++) supports ".exe" type project for the unit test. But you are using ".obj" directly from your project. You need to place ".pdb" file in the same folder.
I created a static library project and added the unit test. Same problem on my environment.
Future here. Same problem, except my test target is a Static Library project in the same Solution.
MyLib - Code that will be tested.
MyLibTests - Project containing the tests.
Solution contains both projects.
MyLibTests has project Reference to MyLib.
<OutDir> (in .vcxproj) aka Output Directory aka $(OutDir) identical in both projects. (My value <OutDir>$(SolutionDir)$(Configuration)_$(Platform)\</OutDir>)
On your test project (MyLibTests), go
Properties
Select [Debug|platform]
Linker
Debugging
Generate Debug Info = Optimize for debugging /DEBUG
Mine was initially set for /DEBUG:FASTLINK.
Via this social MSDN post I figured it had something to do with the PDB, because MSDN (aka now "learn.microsoft.com") said this is an important step in several places, and I assume PDB are used trace calls, I assume using DbgHelp.dll.
And this sort of checklist modified from another social MSDN post:
Test project References properly set (MyLib.lib is in the same Solution as MyLibTests.dll)
Build order/dependency set/verified.
I also have Autorun on Build.
Rebuild (this should rebuild dependencies).
made sure all test were run(all test run successful)
not using optimisation (Profile Guided/Instrumentation etc).
<OutDir> aka Ouput directory should be the same, where both MyLibrary.lib/dll/exe ends up with their MyLibrary.pdb since PDB paths are linked in the exe/dll.
not using a runsettings file
Unload all other projects other than affected ones

undefined reference to function code blocks

main.cpp
#include <iostream>
#include <string>
using namespace std;
void echo(string);
int main()
{
echo("hello");
cout << "Hello world!" << endl;
return 0;
}
print.cpp
#include <iostream>
#include <string>
void echo(string code){
cout << code;
}
After compiling the code in code blocks 12.11, it gives me that error:
undefined reference to `echo(std::string)
I use windows 7 x64.
I have added the directory; Project>build options > search directories and added the current working directory.
All the files are in one console project in code blocks
I believe you should read up a bit more on namespaces usage. You are missing std in print.cpp.
Generally, while starting to learn cpp or getting a grip of the language you should always try writing full names of the classes along with the namespaces. Eventually with practice and some oversights (like now) you will learn why you really need them. In a nutshell namespaces are great:
When you are writing code over multiple files
Compartmentalize your code into separate blocks.
Also, using namespace std; should be used within cpp files mostly (otherwise headers get mangled up.
Anyways, try changing your code to this:
#include <iostream>
#include <string>
void echo(std::string code){
std::cout << code;
}
Then your results will look like this:
> g++ main.cpp print.cpp -o a.out
> ./a.out
helloHello world!
You should get more than that linker error, since you use string without any namespace in your print.cpp file. And if that source file doesn't compile it can't be linked with, and you will get the linker error you have.
Change to e.g.
void echo(std::string code) { ... }
And you do try to link with the object file created from print.cpp ?
I know this is old, but for anyone looking to solve this issue, the following may be a solution for you. If you have g++ follow c++ 11 under project->build options (check your options anyway) then you must check that box for all files you make in the project for the error to be cleared up. I had that annoying undefined reference thing too but now it is gone!
Try "Project/Properties/Build Targets tab". There you should find "Build target files" field. In that filed find "print.cpp" and click the checkbox (now the compiler will build print.cpp).
Some usefull information on Project management in CB
http://www.codeblocks.org/docs/main_codeblocks_en.html
When dealing with strings in C++ its best to sue std::string and your code seems to be wrong with a changes like using std::cout instead of plain cout another thing you need to be careful is linking your files especially files in different directories you need to tell code blocks were to find this print.cpp by going to build option and go for the search tab directory and point to where print.cpp is other wise the other approach is to just build a project which will have the main.cpp and and then add print.cpp class to current project I hope this will be of some help