VSCode dynamic linking - C++ Boost Test - c++

I'm trying to get a Boost Unit Test program to run in VSCode, but I'm having trouble linking the library.
I've written a simple unit test setup with two classes, Boost Test, and FakeIt mocking framework, and easily verified that it works in VS2017. The motivation was to make it work in VSCode eventually though.
When I build the project, it fails to find the boost test files. I tried a few different include options; absolutely path, relative path, and with environment variables (as seen in c_cpp_properties.json below).
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "g++ -g -Wall main.cpp -L/c:/boost/lib64-msvc-14.1 -llibboost_unit_test_framework-vc141-mt-gd-x64-1_69",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "C:/MinGW/bin/gdb.exe",
"preLaunchTask": "echo",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
c_cpp_properties.json
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"${env:BOOST_ROOT}",
"${env:FAKEIT}"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "C:/MinGW/bin/gcc.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64",
"browse": {
"path": [
"${C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++}"
]
}
}
],
"version": 4
}
What I get is
Executing task: g++ -g main.cpp <
main.cpp:3:10: fatal error: boost/test/unit_test.hpp: No such file or directory
#include <boost/test/unit_test.hpp>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
The terminal process terminated with exit code: 1
Have I set up my build files incorrectly? Being used to VS2017, I'm fairly new to manually writing the build files, but I did make a working Hello World program in VSCode Cpp, so it's not like the compiler isn't working. Hope someone can help, I can provide the cpp/h files if requested, but it seems unnecessary given that I know it works in VS2017.
Edit1: I can even right click the Boost and FakeIt includes and "Go to Definition", and it opens the files, but when I try to build it says it can't...?!
Edit2: After some searching for makefile compiler commands, I updated the command to
g++ -g -Wall main.cpp -L/c:/boost/lib64-msvc-14.1
-llibboost_unit_test_framework-vc141-mt-gd-x64-1_69
, trying to tell the compiler to link the library (both .lib and .dll files are present in that folder) but it didn't change anything.
Cheers,
Tachyon

I'm not sure why you think this is a link problem, the error message is definitely telling you this is a compilation problem. The part of the message that lets you know this is for sure is:
compilation terminated.
The gcc linker would say something about "link failed" if this was a linking issue.
Another clue this is a compilation problem is:
main.cpp:3:10: fatal error: boost/test/unit_test.hpp: No such file or directory
This is the c preprocessor telling you it can't find a file you source code has asked for. Includes happen at compilation time not link time.
Your problem is just that you forgot to tell the compiler where the boost headers are in tasks.json on this line:
"command": "g++ -g -Wall main.cpp -L/c:/boost/lib64-msvc-14.1 -llibboost_unit_test_framework-vc141-mt-gd-x64-1_69",
The -L option tells the linker where to find files (not the compiler). It needs to read:
"command": "g++ -g -Wall main.cpp -Ic:/boost -L/c:/boost/lib64-msvc-14.1 -llibboost_unit_test_framework-vc141-mt-gd-x64-1_69",

Related

clang++ library not found even when providing library path

I was trying to create a new OpenGL project with glfw and glad using vs code on an m1 Mac, and setup the files such that I have the include folder and lib folder which contains the necessary headers and library (libglfw3.a) files and the src folder that contains the glad.c and main.cpp, all in my workspace folder.
I have modified the tasks.json file like such:
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-fdiagnostics-color=always",
"-g",
"-std=c++17",
"-I${workspaceFolder}/include",
"-L${workspaceFolder}/lib",
"${workspaceFolder}/src/*.cpp",
"${workspaceFolder}/src/glad.c",
"-llibglfw3",
"-o",
"${workspaceFolder}/game"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: /usr/bin/clang++"
}
]
}
However, I get the following error:
ld: library not found for -llibglfw3
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I thought that I had properly included the path to the glfw library, but it says that it could not find the library. What am I doing wrong?
As a side-note, I have followed this tutorial to setup the program, but this post assumes that you have a windows machine, so I had downloaded/changed some things to my knowledge of what would work with the m1 mac.
Normally when you give libraries to link with the -l flag, you omit the lib prefix. For example: "-lglfw3" links the file "libglfw3.a". It looks like you should change your -llibglfw3 option.

VSCode C++ Debugger Mac not Linking CPP files

I am trying to run the debugger for a simple "hello world" like program but am running into linking errors.
I only have 3 files, Log.h, Log.cpp, Main.cpp:
Log.h
#pragma once
void InitLog();
void Log(const char *);
Log.cpp
#include "Log.h"
#include <iostream>
void InitLog()
{
Log("Initializing Log");
}
void Log(const char *message)
{
std::cout << message << std::endl;
}
Main.cpp
#include "Log.h"
// #include "Log.cpp"
int main()
{
int var = 9;
char x = 'a';
Log("hello world!");
}
I changed my code-runner settings because I was getting a linker error that indicated the two functions Log() and InitLog() were declared but not defined.
Undefined symbols for architecture x86_64:
"Log(char const*)", referenced from:
_main in main-f30cc3.o
"InitLog()", referenced from:
_main in main-f30cc3.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Switching code-runner settings to compile every file in the directory worked:
"cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"cpp": "cd $dir && g++ *.cpp -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
I mention this because potentially I have wired something incorrectly that I am unaware of (should I have even needed to update code runners functionality?)
While this works for compiling and linking the code, I am unable to debug the code because of the same linking error. My CPP/.vscode/launch.json is as follows:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "g++ - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: g++ build active file"
}
]
}
I can see that the same linking error occurs, and playing around with the program and args values did not work for me. My error is:
Terminal Error:
> Executing task: C/C++: g++ build active file <
Cannot build and debug because the active file is not a C or C++ source file.
The terminal process failed to launch (exit code: -1).
Terminal will be reused by tasks, press any key to close it.
There is a simple solution to this, I can just #include "Log.cpp" (the part I have commented) and the debugger works!
> Executing task: C/C++: g++ build active file <
Starting build...
/usr/bin/g++ -fdiagnostics-color=always -g CPP/07Debugging/Main.cpp -o CPP/07Debugging/Main
Build finished successfully.
Terminal will be reused by tasks, press any key to close it.
However, I do not want to import the .cpp files into my Main.cpp everytime I need to debug - am I missing something here? Is there a way to compile and link all cpp files in my current directory in a way that I am unaware of? Searches for people running into the same debugger linker errors has proven fruitless, so I assume I am missing something obvious. I am running VSCode on Mac and compiling the c++ with g++
Here is a solution I found for not needing to `#include "Log.cpp"
In CPP/.vscode/ there needs to be a task.json file, and it was in this file that I could alter the g++ command in the same way that I did to update the code-runner.
Old
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
New
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"*.cpp", //this is what changed
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
I guess there is no need to touch the launch.json which I incorrectly assumed I had to initially. I would still like to know if anyone has other approaches because once a project is including headers from different directories I would not be surprised if all of the .cpp files failed to be compiled and linked.

Error linking Howard Hinnant's date/time zone library

I am trying to install Howard Hinnant's date/time zone library so that I can make a program that displays the time in different time zones. I am using Howard's installation guide for the time zone parser, but given that I am still new to C++ and to programming in general, I recognize I may be doing some things incorrectly.
So far, I have downloaded the source material from GitHub, and I believe I successfully compiled tz.cpp within Visual Studio Code (while linking to the header files provided within the source material). I did not opt to customize the build.
I then tried to run the following sample program (provided in the installation guide):
#include "date/tz.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
auto t = make_zoned(current_zone(), system_clock::now());
std::cout << t << '\n';
}
No errors show up under the "problems" window on my console; however, the following text appears on the terminal:
C:\Users\kburc\AppData\Local\Temp\ccqDCN6j.o: In function `main':
c:/Users/kburc/Vol 7/Documents/!Dell64docs/Programming/CPP/KJB3programs/CLClockv2/CLClockv2.cpp:26: undefined reference to `date::current_zone()'
C:\Users\kburc\AppData\Local\Temp\ccqDCN6j.o: In function `date::sys_info date::time_zone::get_info<std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > >(std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > >) const':
c:/Users/kburc/Vol 7/Documents/!Dell64docs/Programming/CPP/KJB3programs/CLClockv2/date/tz.h:896: undefined reference to `date::time_zone::get_info_impl(std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long long, std::ratio<1ll, 1ll> > >) const'
collect2.exe: error: ld returned 1 exit status
The terminal process "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -Command & 'C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\g++.exe' -g 'c:\Users\kburc\Vol 7\Documents\!Dell64docs\Programming\CPP\KJB3programs\CLClockv2\CLClockv2.cpp' -o 'c:\Users\kburc\Vol 7\Documents\!Dell64docs\Programming\CPP\KJB3programs\CLClockv2\CLClockv2.exe'" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
[Apologies for the formatting]
Any pointers on what I might have done incorrectly or failed to do would be greatly appreciated. Happy to provide more information if necessary. Thank you!
Edit: here is my launch.json file:
"version": "0.2.0",
"configurations": [
{
"name": "g++.exe - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++.exe build active file"
}
]
}
And here is my tasks.json file:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "g++.exe - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [
"-g",
"${workspaceFolder}\\*.cpp",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++.exe build active file"
}
]
}
The program compiled correctly, but it didn't link:
In function `main':
undefined reference to `date::current_zone()'
In function `date::sys_info date::time_zone::get_info<...>(...) const':
undefined reference to `date::time_zone::get_info_impl(...) const'
error: ld returned 1 exit status
Therefore, the problem is not related to running the program, since the program does not exist yet.
The command line was:
g++.exe -g CLClockv2.cpp -o CLClockv2.exe
Which does not contain any linking flag (-l), which means GCC won't link the library and produce the error you see above when it does not find the symbols it needs. Usually, you also need a search path flag (-L), too.
I suggest you learn to compile from the command line before trying to manually configure an IDE like VS Code. Another option is Visual Studio which comes preconfigured with MSVC.
Update: I was able to get the program to run as desired, thanks in part to Acorn's feedback. It turned out that there were a couple of changes I needed to make.
First, I needed to include tz.cpp within the program.
Second, I needed to edit my build command to add in not just tz.cpp but -lole32 as well (credit to denchat at https://github.com/HowardHinnant/date/issues/272 for pointing this out). This could be done either within the command prompt as
g++ CLClockv2.cpp tz.cpp -lole32 -o CLClockv2.exe
or within Visual Studio Code using the following tasks.json file:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${workspaceFolder}\\*.cpp",
"-lole32",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
However, I then found that I needed to download a copy of the time zone database (the "Data only" version worked for me) from https://www.iana.org/time-zones and then unzip it into a downloads folder named tzdata.
Finally, I then needed to create a file called windowsZones.xml (available at https://github.com/unicode-org/cldr/blob/master/common/supplemental/windowsZones.xml ) and include it into the downloads folder.
Once I took all these steps, I was able to get the program to work.
Thanks again for your help!
Ken

Visual Studio Code: how to add arguments for g++ compiler?

I want to use some C++17 features that Mac's clang doesn't currently support, so I use
brew install gcc --HEAD
to install the g++ 10.0.1 version. Codes run well in terminal by directly calling
g++-HEAD -std=c++17 test.cpp
I also created a link ln -s g++-HEAD g++ in bash, and added an alias alias g++='g++ -std=c++17' in .bash_profile, so that
g++ test.cpp
will do the same job.
I want to run C++ code in Visual Studio Code - Mac version. After installing its C/C++ Extension by Microsoft, and Code Runner Extension, I set up the settings.json file in VSCode to include compiler argument:
{
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.compilerPath": "/usr/bin/g++",
"C_Cpp.default.intelliSenseMode": "gcc-x64",
"C_Cpp.default.compilerArgs": [
"-std=c++17"
]
}
Then I tried to run the same code. However, I got warning:
[Running] cd "/some directory/" && g++ test.cpp -o test && "/some directory/"test
warning: fold-expressions only available with '-std=c++17' or '-std=gnu++17'
Clearly, it means the g++ compiler ran in VSCode is not the one I manually set with alias. More interestingly, if I run directly in VSCode TERMINAL, my previous code
g++ test.cpp -o test
works.
I'm confused by the setup in VSCode: why doesn't the runner use the same g++ compiler argument as used in VSCode's own terminal? Also, how should I modify the settings.json file or some other files in VSCode so that I can correctly add the -std=c++17 argument?
Assuming you use the C/C++ extension, create a task.json file, which will allow you to change settings such as the path to the compiler, include paths, C++ standard, optimization (default is C++17), and more.
From the code tutorial:
From the main menu, choose Terminal > Configure Default Build Task. A dropdown appears showing various predefined build tasks for C++ compilers. Choose C/C++: g++ build active file.
This will create a tasks.json file in a .vscode folder and open it in the editor.
Your new tasks.json file should look similar to the JSON below
My file looks like
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-std=c++17",
"-ggdb",
"-Og",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: /usr/bin/g++"
}
]
}
Here is my solution to this predicament. I link it with my projects Makefile.
First, you'll need to build a Makefile, if your using GCC using a Makefile on its own is... controversial to say the least. But I think it serves the purposes of this example. As you may know, running "make" instead of g++ in the current directory will parse the Makefile and run the corresponding commands. But in your case, your Makefile may look similar to:
#You're gonna wanna make it think that your executable doesnt exist, otherwise,
#because the executable exists, make will assume its the most recent build.
.PHONY: debug
#using g++ and the flags inline like this, is generally seen as bad practice, it might be worth
#looking into using Makefiles to make this more acceptable, but this will get you started.
debug:
g++ -g -o debug main.cpp -std=c++17
clean:
rm debug
#if you copy this exactly, make you you replace the spaces with proper tab
#characters otherwise it will error out.
The Juicy part is in VS code; It has a very power feature known as tasks. Tasks are their very own special rabbit hole, but to put it bluntly, you add a task to the "tasks" array in a generated tasks.json file in your workspace, if you're not familar with how that might look, here is the syntax for a task:
{
"label": "[name of task]",
"type": "[type of task, usually its a shell command]",
"command": "[the actual command to call]"
}
There are many more features that tasks can offer, but for making a build tool this will be all you need, for me, this resulted in a file that looked like this:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build_debug",
"type": "shell",
"command": "make"
},
{
"label": "clean",
"type": "shell",
"command": "make clean"
},
{
"label": "build",
"dependsOn": [
"clean",
"build_debug"
],
"problemMatcher": [
"$gcc"
]
}
]
}
Why do we need to have a final build call? because your launch.json object can take a "preLaunchTask" that will automatically call prior to debug. You can slap in that final build call, and it will compile, debugger, and then run your app. it will even integrate GDB breakpoints and memory tracking into the workspace. My launch.json looks like this:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/runnable",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "build",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": false
}
]
}
]
}
Sorry for the long replay, i hope it helps :)

G++ Compiling Visual Studio Code

I have installed Visual Studio Code on Ubuntu, but I can't seem to get it to compile. I have looked at https://code.visualstudio.com/docs/languages/cpp and https://code.visualstudio.com/Docs/editor/tasks and have tried all the examples but I keep getting the error "No build task defined. Mark a task with 'isBuildCommand' in the tasks.json file." The command I would like to run is g++ Main.cpp Classes.cpp -o Planets -lGL -lglut
I once encountered this problem. What I learned from that are these:
Make sure your Main.cpp, Classes.cpp are at the $workspaceRoot or use relative path.
Make sure your tasks.json file does not contain any error.
Make sure the tasks.json has a version number at the top of the code.
Make sure the type of the task is correct. (e.g. For a console app, it should be "shell")
I have created a tasks.json file for you. It works with my Main.cpp(put a Hello world program in it) and Classes.cpp(A simple class). Compare yours to mine to see if you did something wrong.
{
"version": "2.0.0",
"tasks": [
{
"taskName": "Build",
"type": "shell",
"command": "g++",
"args": [
"Main.cpp",
"Classes.cpp",
"-o",
"Planets",
"-lGL",
"-lglut"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
}
]
}