Reputation: 153
I am using VSCode and the code runner extension to try to run a simple c++ project with include files.
The project is made of a main.cpp:
#include <iostream>
#include <time.h>
#include "cval.hpp"
using namespace std;
int main(void)
{
putHello();
return 0;
}
A hello.hpp header file:
#ifndef CVAL_H
#define CVAL_H
void putHello(void);
#endif
And the hello.cpp:
#include <iostream>
using namespace std;
void putHello(void){
cout<<"Hello"<<endl;
}
If I define putHello()
in main.cpp, the code compiles. If I include #include cval.cpp
the code compiles.
However, when I only include the cval.hpp
header and use the Code runner extension, I get the following error:
Undefined symbols for architecture x86_64:
"putHello()", referenced from:
_main in main-a07db2.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I understand this is a problem that I am not compiling cval.cpp
so the linker cannot find it and link it properly. However, is there a way to get VSCode to automatically compile files that were included in headers?
I don't want to have to specify it all the time or have to include the .cpp files, and it is able to include these files with out a problem in my C code projects.
Upvotes: 8
Views: 13708
Reputation: 759
I modified the accepted answer to place all compiled files in a single directory allowing for easier .gitignore and general tidiness in my main workspace. Note I'm using C on macOS but same concept applies for C++.
"c": "cd $dir && mkdir -p out && clang -o out/$fileNameWithoutExt *.c && out/$fileNameWithoutExt"
Upvotes: 0
Reputation: 1
Thanks, the first solution worked for me but I had to add a '$' before fileNameWithoutExt:
"cpp": "cd $dir && g++ -o $fileNameWithoutExt *.cpp && ./$fileNameWithoutExt"
Upvotes: 0
Reputation: 76
There are two ways to solve it.
In settings(cmd + ,), find Run Code Configuration.
There is a tab 'Executor map' and open 'edit in settings.json'.
Then you can see the settings for code-runner extension (executor map).
Change the cpp part into this
"cpp": "cd $dir && g++ -o fileNameWithoutExt *.cpp && ./$fileNameWithoutExt"
This code compiles every cpp file in the current directory, so the header will be included properly.
A problem of this solution is, if there are other cpp files with main(), then it will not be compiled properly.
So you'd better use one folder for one cpp program.
I made a second solution to avoid this problem, but it only works for mac (because I made a function on the bash profile, and I'm not familiar enough with powershell script syntax to make that function on windows)
If you use macOS, try this one.
On vscode, press (shift + cmd + p) and type
Shell Command: Install 'code' command in PATH
And then open terminal, and type
sudo code ~/.bash_profile
if you use zsh, then instead of that, type
sudo code ~/.zshrc
and copy paste this code
function cppcompile()
{
filename=$1
re="^\#include \""
while read line
do
if [[ $line =~ $re ]]; then
temp=${line:9}
temp1=${temp#\"}
temp2=${temp1%\.*\"}
g++ -std=c++11 -c $temp2.cpp
fi
done < $filename.cpp
g++ -std=c++11 -c $filename.cpp
g++ -o $filename *.o
./$filename
rm *.o
}
and then open the executor map again, and change the cpp part into
"cpp": "cd $dir && cppcompile $fileNameWithoutExt"
cppcompile function will read your code and find headers, and compile headers and main code.
So it can compile the only one main code and the headers linked to that main, and it doesn't matter if there are other cpp files with main in the same directory.
Upvotes: 6