Reputation: 33944
We have a cross compiled visual studio Makefile project. We have already had to introduce a solution similar to this to get it to recognize compiler errors. Ie. We have introduced a Perl script to parse the output from GCC and convert it into a form that Visual studio will understand. If we declare:
int succ = thisRandomFunction(userPointer, 1, 1);
with no definition for thisRandomFunction
then we will get the linker error:
1> ./program.a(taskqueue.o): In function `TaskQueueAdd': 1>
D:\Git\program\taskqueue.c(94,1) : undefined reference to `thisRandomFunction' 1>
collect2: ld returned 1 exit status 1> make: *** [program.exe] Error 1
But visual studio doesn't actually recognize this as an error. A Visual Studio C++ console program with the same problem has the linker error:
1> TestUndefinedReference.cpp
1>TestUndefinedReference.obj : error LNK2019: unresolved external symbol "int __cdecl something(int)" (?something@@YAHH@Z) referenced in function _main
1>D:\Projects\New folder\TestUndefinedReference\Debug\TestUndefinedReference.exe : fatal error LNK1120: 1 unresolved externals
By using this converter:
sub parseLinkerError
{
my $str = $_[0];
my $find = "undefined reference to";
my $replace = "error LNK2019: unresolved external symbol";
$str =~ s/$find/$replace/g;
return $str
}
We can convert this:
1> d:\Git\program/taskqueue.c:94: undefined reference to `thisRandomFunction'
into this
1> D:/Git/eV+/program/taskqueue.c(94,1) error LNK2019: unresolved external symbol `thisRandomFunction'
But this isnt enough to trick the visual studio linker error interpreter. What are the minimum requirements for it to see a linker error? Are there any solutions that can work without directly parsing the text?
Upvotes: 5
Views: 608
Reputation: 66981
According to the documentation...
The format of the output should be:
{filename (line# [, column#]) | toolname} :
[any text] {error | warning} code####: localizable string
Where:
For example:
C:\sourcefile.cpp(134) : error C2143: syntax error : missing ';' before '}'
LINK : fatal error LNK1104: cannot open file 'somelib.lib'
D:/Git/eV+/program/taskqueue.c(94,1) error LNK2019: unresolved external symbol `thisRandomFunction'
^
Upvotes: 1
Reputation: 33944
So it seems like adding this line is enough to do it:
taskqueue.obj : error LNK2019: unresolved external symbol "thisRandomFunction" referenced in function TaskQueueAdd
As far as i can tell the error will be detected via the following keys:
[*].obj : error LNK2019: unresolved external symbol "[*]" referenced in function [*]
Where the [*]
can be anything or nothing (it doesn't even need to be the actual function).
So the following script is enough to parse it:
my $previousUsedInFunction = "";
sub parseLinkerError
{
my $str = $_[0];
my $find = "undefined reference to";
#check that our string contains the undefined reference to substring.
if (index($str, $find) != -1) {
#Use regular expressions to get the important filename.
my $filename = "";
if ($str =~ /\\([a-zA-Z0-9_.]*)\(/) {
$filename = $1;
#replace whatever filename we find with the .obj equivelent.
$filename =~ s/\.cpp$/\.obj/g;
$filename =~ s/\.h$/\.obj/g;
$filename =~ s/\.c$/\.obj/g;
}
#Use regular expressions to find the function name.
my $function = "";
if ($str =~ /\`([a-zA-Z0-9_.()]*)\'/) {
$function = $1;
}
#create the final string similar to what visual studio expects.
my $finalStr = " " . $filename . ' : error LNK2019: unresolved external symbol "' . $function . '" referenced in function ' . $previousUsedInFunction . "\n";
return $finalStr;
}
return $str;
}
Where the string $previousUsedInFunction
is generated in the main parsing loop using the following if statement (to detect if we had an in function reference) :
elsif (/\.o\): In function \`([a-zA-Z0-9_.():]*)\'/) {
print ("$_");
$previousUsedInFunction = $1;
}
Upvotes: 0