OK, this is probably very basic, but I can't find the problem. I'm trying to link my C++ program with a C shared library (YAJL to name it) with -lyajl ; the linker seems to find it (it does not complain for that) but cannot find the symbols I use in my code :
$> g++ test.c -lyajl
Undefined symbols for architecture x86_64:
"yajl_tree_parse(char const*, char*, unsigned long)", referenced from:
_main in ccEqsAaJ.o
"yajl_tree_get(yajl_val_s*, char const**, yajl_type)", referenced from:
_main in ccEqsAaJ.o
"yajl_tree_free(yajl_val_s*)", referenced from:
_main in ccEqsAaJ.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
$>
I made a minimalist test.c file to isolate the behavior. Well, what's very strange is that gcc seems perfectly OK with the code (as, incidentally, test.c is just C code, no C++ feature here):
$> gcc test.c -lyajl
$>
What is gcc doing that g++ doesn't seem to be able to do right ?
Could it be that the symbols in libyajl.so are C linkage, but your code (or the header file you are using) does not declare them extern "C"? In that case, compiling your code as C++ would result in name-mangled symbols in your object file, which would not match the (C linkage, unmangled) symbols in the library.
The solution would be to write, in the header file, something like this:
#ifdef __cplusplus
// "__cplusplus" is defined whenever it's a C++ compiler,
// not a C compiler, that is doing the compiling.
extern "C" {
#endif
// Exchange "void" with the real return type for these functions
void yajl_tree_parse(char const*, char*, unsigned long);
void yajl_tree_get(yajl_val_s*, char const**, yajl_type);
void yajl_tree_free(yajl_val_s*);
#ifdef __cplusplus
}
#endif
If extern "C" does not fix it, try this.
I had the same problem trying to link against the static library- libyajl_s.a.
It is possible to work around the problem by compiling the yajl source into the executable,
but I really needed the static library.
On closer inspection of the yajl source you will see that the source is looking for headers in two separate folders, e.g.
#include <api/yajl_tree.h>
#include <api/yajl_parse.h>
#include "yajl_parser.h"
The linker seems to resolve yajl_tree_parse, yajl_tree_get and yajl_tree_free to their prototypes in yajl_tree.h and not to their definitions in yajl_tree.c. In other words- they remain undefined in the resulting library.
The solution was to move all headers from the api folder into the src folder and remove all references to <api/...>. The linker then picked up the yajl_tree_xxx function definitions correctly.
Related
I am trying to compile some C++ that depends on QuantLib, which in turn depends on Boost. I am working on a MacBook Pro M1 (ARM architecture). I installed Boost and QuantLib using the instructions on this page: https://www.quantlib.org/install/macosx.shtml. I then tried to compile the following source code:
#include <iostream>
#include <ql/quantlib.hpp>
int main(int, char*[])
{
QuantLib::Option::Type OptionType(QuantLib::Option::Call);
std::cout << "Option Type = " << OptionType << std::endl;
return 0;
}
using the following command:
clang++ -std=c++11 ql_ex1.cpp -o build/ql_ex1 $(INC) $(LIB) \
-I/opt/homebrew/Cellar/quantlib/1.23/include -I/opt/homebrew/Cellar/boost/1.76.0/include \
-L/opt/homebrew/Cellar/boost/1.76.0/lib -L/opt/homebrew/Cellar/quantlib/1.23/lib
This gave me the following error message:
Undefined symbols for architecture arm64:
"boost::assertion_failed(char const*, char const*, char const*, long)", referenced from:
long double boost::math::detail::sinpx<long double>(long double) in ql_ex1-044d3e.o
"boost::assertion_failed_msg(char const*, char const*, char const*, char const*, long)", referenced from:
boost::array<long double, 171ul>::operator[](unsigned long) const in ql_ex1-044d3e.o
...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1
So far I have tried the following approaches,
Install x86 binaries and run clang++ in emulation. I see the same Undefined symbols error.
Try to identify a Boost shared library file that I need to link to. I have not been able to find anything that contains the assertion_failed symbol.
Can someone point me to where (if anywhere) this symbol is defined? It would be useful to know if I am just missing the right compiler options or whether there is a more fundamental issue that needs to be addressed.
I think you're missing a -lQuantLib in your command line? You're telling the compiler where to look for the libraries (the -L switches`) but not which libraries to link.
Also, check whether homebrew also installed a quantlib-config script on your computer. If so, it should provide the switches you need; try running
quantlib-config --cflags
which should output the -I flags specifying the location of the QuantLib headers (and possibly the -std=c++11 flag you're passing manually), and
quantlib-config --libs
which should output the corresponding -L switches as well as the -lQuantLib you missed.
If they work, you can use the command
clang++ ql_ex1.cpp -o build/ql_ex1 $(INC) $(LIB) \
-I/opt/homebrew/Cellar/boost/1.76.0/include \
`quantlib-config --cflags` `quantlib-config --libs`
and let the script fill in the info for you.
I am trying to build a simple SSH client from Wil Allsopp's pen testing book. Working on Mac OS High Sierra with gcc-4.2 with libssh installed using Homebrew. The simplest version of the code is:
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
ssh_session my_ssh_session;
my_ssh_session = ssh_new();
ssh_free(my_ssh_session);
return 0;
}
However a simple gcc build (gcc -Wall ssh_client.c) produces the following error:
Undefined symbols for architecture x86_64:
"_ssh_free", referenced from:
_main in ssh_client-aa8f09.o
"_ssh_new", referenced from:
_main in ssh_client-aa8f09.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
Can anyone explain these errors and how I can fix them?
Your build line doesn't appear to contain any include and linker flags. I imagine it is picking up the headers but not the library for ssh to link against. Have a look into pkgconfig for an easy way to maintain this.
I have been using OpenCV for a while and also the imwrite function, but unfortunately this is not working any more.
I am running with OpenCV 2.4.3 with following sample code:
imwrite("somepath/somefile.png", myMat);
The error:
Undefined symbols for architecture x86_64:
"cv::imwrite(std::string const&, cv::_InputArray const&, std::__debug::vector<int, std::allocator<int> > const&)", referenced from:
MyProject::this_callback(int, void*) in MyProject.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The error looks somewhat familiar but i cannot determine whats wrong.
Yes, I've thought you were using XCode. I had the same problem. :)
If you change the project setup so that:
you use GNU++11 as C++ language dialect
libstdc++ (GNU C++ standard) as C++ standard library
your linking problem will go away.
I use Apple LLVM 4.1.
When I had this problem, I have tried just adding a new target to one of my old projects I knew, worked. Then I've just made that target a one-source-file program.
This must be a "magic" part of XCode as I think there was a time I could not get the same project working after a restart. :S
I did what Barnabas did and also got the issue on cvdef.h. I was getting desperate so and what I did was just changed the header file.
in /usr/local/cvdef.h line 205:
I changed
include <cstdint>
typedef std::uint32_t uint;
to:
include <tr1/cstdint>
typedef std::tr1::uint32_t uint;
based on this post
I think opencv devs should apply some changes to the code for 64bit..
use something like clang version 3.8.0 (trunk 257459), instead of gcc version 4.9.2 (MacPorts gcc49 4.9.2_1+universal) to compile
for reference, cmd: clang++ -std=c++11 `pkg-config --cflags --libs opencv` code.cpp -o code
I have the below in a Cmake file:
add_library(stasm STATIC IMPORTED)
set_property(TARGET stasm PROPERTY
IMPORTED_LOCATION /media/Data/sdks/stasm3.1/linux/libstasm.a)
target_link_libraries( StasmOpencvExample ${OpenCV_LIBS} stasm)
I generated the libstasm.a by doing:
How to create a static library with g++? , the first answer, taking all of the .o files from the linux folder and putting it into an archive.
but when i run make on my project i get:
Scanning dependencies of target StasmOpencvExample
[100%] Building CXX object CMakeFiles/StasmOpencvExample.dir/stasm_opencv_example.cpp.o
Linking CXX executable StasmOpencvExample
CMakeFiles/StasmOpencvExample.dir/stasm_opencv_example.cpp.o: In function `main':
stasm_opencv_example.cpp:(.text+0x9a): undefined reference to `AsmSearchDll(int*, int*, char const*, char const*, int, int, int, char const*, char const*)'
collect2: ld returned 1 exit status
has anyone gotten a cmake project to work with stasm on linux before? I also had to remove a n include "windows.h" from stasm_dll.cpp, and other windows specific code that wasn't properly done to allow working on linux.
I have already gotten the linux folder to generate the binaries and they work great, now I just need to incorporate this functionality into my own project..
It seems that the reason was that Stasm was created to make executables on Windows that did Image processing. Stasm DOES NOT act like a library, I'm currently making my own static and shared library that will act like a library that you can use to import into a random project and specify the parameters.
Basically modifiying main.cpp to another class and taking out the testing/unecessary code and get a thin processing version.
I have just built and installed tiff-4.0.0beta6 on my Mac computer running Snow Leopard. I followed the tutorial at http://www.kyngchaos.com/macosx/build/libtiff. The install went fine but there are issues with the TIFF data type.
For exmaple, when I compile the following simple code:
#include "tiffio.h"
main()
{
TIFF* tif = TIFFOpen("foo.tif", "r");
TIFFClose(tif);
}
I get the error message:
hlrg-labs-imac:metrics Ben$ gcc main.c
Undefined symbols:
"_TIFFOpen", referenced from:
_main in cciewEwr.o
"_TIFFClose", referenced from:
_main in cciewEwr.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
When I compile the code:
#include "tiffio.h"
main()
{
TIFF tif;
}
I get the compilation error:
hlrg-labs-imac:metrics Ben$ gcc main.c
main.c: In function ‘main’:
main.c:5: error: storage size of ‘tif’ isn’t known
Any suggestions on this would be greatly appreciated.
Thanks.
When you compile you need to include the -ltiff switch. For example:
gcc main.c -ltiff -o main
Also, in your second example it should be
main(){ TIFF* tif; }