Unresolved Extern - extern

I am using extern in my project for variables and functions so that i can share that with my other source files in future.
How am i trying to use it?
I had made a "Header file" for Declaration of Variables and functions by the name dec.h
There is another file by the name def.c in which I had Defined those Variables and functions. def.c file includes dec.h file.
Now in my main program, when I include dec.h file only and try to build the program, compiler warns as Unresolved Extern [My function names].
Am I trying to do it the wrong way? I have read to use extern that way in the following thread How do I use extern to share variables between source files in C?

The above procedure was right, The problem was that I haven't included the def.c to my project files.

Related

Simple CGO example fails compilation with "duplicate symbol" error

I want to make a simple example of calling C code from Go with CGO. But for some reason I can't achieve desired. Compilation fails with the following error:
go build main.go
# awesomeProject1/print
duplicate symbol '_do_print' in:
$WORK/b002/_x002.o
$WORK/b002/_x003.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The code:
// print/print.c
#include <stdio.h>
void do_print(char * x){
printf("%s", x);
}
// print/print.go
package print
// #include <print.c>
import "C"
func DoPrint() {
C.do_print(C.CString("Hello!"))
}
// main.go
package main
import "awesomeProject1/print"
func main() {
print.DoPrint()
}
If I make do_print function static it compiles but I wouldn't be able to do that for 3rd party code I want to integrate with later.
Am I missing some essential piece from documentation? Tutorials are all alike and claim to work where my example fails. Please help!
Go version 1.16.4
There are two things going on here:
go build compiles *.c in addition to *.go1
#include <print.c> is exactly equivalent to overwriting the include statement with the contents of print.c
As a result, you are compiling the contents of print.c twice: once when print.c is compiled by CC, and once when print.go is compiled by CGo. Thus, the object files for print.c and print.go each contain all of the exported symbols defined in print.c. So you get two copies of do_print. Making do_print static works because a function declared as static will not be exported by CC.
Including a .c file (e.g. #include <file.c>) is pretty much always a bad idea. If you have a legitimate reason to #include function bodies, the convention is to use a header (.h) file. This is what C++ templating libraries do (like Boost, IIRC). Because C files normally are not included, and H files normally are included, including a C file subverts expectations and thus is likely to cause confusion and problems.
1 IIRC, Go will compile C files in a package if any of the Go files in the package import "C". That is, if no Go files in a package use CGo, Go will ignore C files in that package.

How to get the return values for a function in boost test functions?

I am trying to write boost unit tests for a C++ repository. I want to assert the return values of the function, but the visual studio complains it as an unresolved external symbol. If the BOOST_AUTO_TEST_CASE(my_boost_test) uses user-defined types in the repository, there are no issues, but as I use a function, then there are unresolved external symbol issues.
The below test runs without any error, but if I uncomment that function call, then I get an unresolved external symbol issue. Am I using a wrong BOOST_TEST? How to use a function call in the boost unit tests?
#include <boost/test/included/unit_test.hpp>
#include "../my_repo/graph.h" // (getLables(), labelGraph and vertex_t defined here)
BOOST_AUTO_TEST_CASE(my_boost_test)
{
std::string file1("test_tring");
//vector<std::string> records = getLabels(file1);
labelGraph g;
vertex_t root = boost::add_vertex(g);
g[root].name = ".";
BOOST_TEST(1 == 1);
BOOST_TEST(true);
}
The issue is with Visual studio. my_repo was built as a console application in which case there were no .lib files generated. Changing the my_repo from console application to static library output resolved the issues.

‘__gnuc_va_list’ has not been declared

I try to build large project with many directories and sub-directories, some of them are being used to create different libs.
using GNU make using same compilation flags. most of the folder are successfully built, but in a specific folder the build failed, and it gets many errors that some definitions is missing.
For instance, the first error is:
In file included from /usr/include/c++/4.8.2/cwchar:44:0,
from /usr/include/c++/4.8.2/bits/postypes.h:40,
from /usr/include/c++/4.8.2/iosfwd:40,
from /usr/include/c++/4.8.2/memory:72,
...
/usr/include/wchar.h:614:9: error: ‘__gnuc_va_list’ has not been
declared
__gnuc_va_list __arg
)
this error comes from simple #include at of the files in this lib, but same sort of error happens for any file and for different standard library headers.
The strength thing is that this project was completely successfully built before i pulled some updates from remote repository. at this merge no changes were done to this file.
Tried to use
g++ -E /usr/include/wchar.h | grep __gnuc_va_list | head -1
result is:
typedef __builtin_va_list __gnuc_va_list;
As i see at this answer, __builtin_va_list shuould be created by gcc, and it probably did create it- otherwise many other files were failed to compile
I can't understand why it happens and why only at this folder/lib.
I had same problem for libhydrogen on windows and mingw 5.3.0, you can just define it to:
typedef void* __gnuc_va_list;
... then it compiled and the delivered tests.c worked.
i think for unix systems its (unsure):
typedef char* __gnuc_va_list;

Why am I getting duplicate symbol linker errors when building in CMake on Windows?

I have a CMake setup to link together 4 static libraries and 1 shared one into a top level shared library (Let's call it Top.dll). This will work fine except for one thing. I have a module definition file that expresses which symbols should be public. Top.dll builds and so far so good.
Now when I try to link an executable with Top.dll via CMake I get linker errors for every public symbol claiming it is defined in two places (Top.dll and the static library in which it was actually defined) even though Top.dll contains no original definitions of its own. If I remove the static library then as expected I get unresolved symbol errors. If I remove the module definition file, I get the same. It seems like it is either there zero times or twice. Is there some setting I am missing here? I don't think I'm using CMake in a non-basic way...
UPDATE An explanation via CMake
# setup the lib
add_subdirectory(vendor/A) #shared library
add_subdirectory(vendor/B) #static library
add_subdirectory(vendor/C) #static library
add_library(Top SHARED ${ALL_SRC_FILES})
target_link_libraries(Top A B C)
set_target_properties(Top PROPERTIES LINK_FLAGS
"/def:${PROJECT_SOURCE_DIR}/definitions.def") #contains symbols from B
add_subdirectory(C/Tests)
# CMakeLists.txt from C/Tests
add_executable(Tests ${SRC_FILES})
target_link_libraries(Tests Top)
The above is simplified, but I will get errors like the following at the point that the C/tests project is compiled:
B.lib(xxx.obj) : error LNK2005: _ABC already defined in Top.lib(Top.dll)
If I remove B.lib from the target_link_libraries call, then as expected I get unresolved symbols. If I remove the /def line, same result.
I've been able to get around this by setting the target_link_libraries of B and C to private. This may or may not be the correct solution and I will wait for other answers. If I don't do this it appears that the dependency is carried up to the final executable (So it links to both Top.dll and B.lib, etc).

Xcode/GCC predefined macro for target name?

I was wondering if there is an Xcode or GCC preprocessor symbol for the target name of the application.
For example if I'm building an application called "MonkeyChicken", is there a preprocessor symbol such that
printf( __TARGET_NAME__ )
outputs:
MonkeyChicken
I don't believe there is any built-in (gcc has no idea what you're building when you compile a file), but you can always create one using GCC_PREPROCESSOR_DEFINITIONS in an xcconfig file (you are using xcconfig, right?) Something like this should work as you indicate above:
GCC_PREPROCESSOR_DEFINITIONS = __TARGET_NAME__=\"$(PRODUCT_NAME)\"

Resources