How does gcc link static library? - c++

I have a simple program use static library for control pci device. I have got some examples. But i want to make myself some examples but i can't link static libraries.
I have 3 file: led.cpp main.cpp main.h
gcc -c led.cpp -I../utils -I../driver -o led.o
gcc -c main.cpp -I../utils -I../driver -o main.o
it' s ok. Succesfuly creating main.o and led.o object files.
But when linking state, its broken. 24dsi20c500k_utils.a and 24dsi20c500k_dsl.a static libraries.
gcc led.o main.o ../utils/24dsi20c500k_utils.a ../docsrc/24dsi20c500k_dsl.a -o led
Output is shown:
led.o: In function `led_tests(int)':
led.cpp:(.text+0x18): undefined reference to `gsc_label(char const*)'
led.cpp:(.text+0x31): undefined reference to `dsi20c500k_initialize(int, int)'
led.cpp:(.text+0x39): undefined reference to `gsc_label_level_inc()'
led.cpp:(.text+0x5b): undefined reference to `dsi20c500k_led(int, int, int, int*)'
led.cpp:(.text+0x81): undefined reference to `dsi20c500k_led(int, int, int, int*)'
led.cpp:(.text+0xa2): undefined reference to `gsc_label_level_dec()'
led.cpp:(.text+0xb1): undefined reference to `dsi20c500k_initialize(int, int)'
main.o: In function `_perform_tests(int)':
main.cpp:(.text+0x3a1): undefined reference to `gsc_label(char const*)'
main.cpp:(.text+0x3c6): undefined reference to `gsc_id_driver(int, char const*)'
main.o: In function `main':
main.cpp:(.text+0x42c): undefined reference to `gsc_label_init(int)'
main.cpp:(.text+0x49a): undefined reference to `gsc_id_host()'
main.cpp:(.text+0x4a4): undefined reference to `gsc_count_boards(char const*)'
main.cpp:(.text+0x4b6): undefined reference to `gsc_select_1_board(int, int*)'
main.cpp:(.text+0x4d7): undefined reference to `gsc_label(char const*)'
main.cpp:(.text+0x500): undefined reference to `gsc_dev_open(unsigned int, char const*)'
main.cpp:(.text+0x54f): undefined reference to `gsc_dev_close(unsigned int, int)'
collect2: ld returned 1 exit status
make: *** [led] Error 1
if i rename cpp files to c files compilation succesfull. What is the problem?

gcc -c main.cpp will compile your code as C++ code.
What likely happens then, is that your main.cpp includes other header files, that are not meant to be compiled as C++. This means that when including these header files in a C++ program , gcc will assume all the stuff the header files declares are C++.
And if they're not, you get linker errors if you try to link to C code that the compiler assumed was C++.
You can remedy this by stating that those header files are C. e.g. in your main.cpp you'd do
extern "C" {
#include "some_c_lib.h"
}

You probably didn't use extern "C".
if i rename cpp files to c files compilation succesfull. What is the
problem?

Related

Undefine reference of <function name>

When I've try to compile program (test for my lib) I've got undefined reference of for every called method. I've read answers on "gcc undefined reference to", but it has not help.
PS I using: Debian 7.2.0 and C++11 standart.
#include <RFw/String.hpp>
#include <stdio.h>
using namespace RFw;
int main() {
Array<char> _arr_ (5);
_arr_[0] = 'b';
_arr_[1] = 'c';
printf("%c%c\n", _arr_[0], _arr_[2]);
printf(RFw::getVersion());
return 0;
}
Makefile target:
test:
c++ test.cpp -I./include-core/ -o bin/test -L./bin -l${core_NAME_ROOT}
Console output:
test.cpp:13:9: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
printf(RFw::getVersion());
^~~~~~~~~~~~~~~~~
1 warning generated.
/tmp/test-lxdZF4.o: In function `main':
test.cpp:(.text+0x20): undefined reference to `RFw::Array<char>::Array(int)'
test.cpp:(.text+0x33): undefined reference to `RFw::Array<char>::operator[](int)'
test.cpp:(.text+0x54): undefined reference to `RFw::Array<char>::operator[](int)'
test.cpp:(.text+0x75): undefined reference to `RFw::Array<char>::operator[](int)'
test.cpp:(.text+0x99): undefined reference to `RFw::Array<char>::operator[](int)'
test.cpp:(.text+0xff): undefined reference to `RFw::Array<char>::~Array()'
test.cpp:(.text+0x11a): undefined reference to `RFw::Array<char>::~Array()'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::operator[](int) const'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::Array(int)'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::getLength() const'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Exception::onThrow()'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::resize(int)'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::addElementOnEnd(char)'
./bin/libregemfw0.1-core.so: undefined reference to `vtable for RFw::Object'
./bin/libregemfw0.1-core.so: undefined reference to `typeinfo for RFw::Object'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Object::~Object()'
./bin/libregemfw0.1-core.so: undefined reference to `RFw::Array<char>::~Array()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Ошибка 1
The problem is that
c++ test.cpp -I./include-core/ -o bin/test -L./bin -l${core_NAME_ROOT}c++ test.cpp -I./include-core/ -o bin/test -L./bin -l${core_NAME_ROOT}
will first process the library and then your .cpp file. When processing a library, referenced symbols are resolved ("linked") and all unresolved symbols in the library that aren't needed are thrown away. That means that as soon as your .cpp file is being processed, these symbols are already rejected. You have the library twice in your command line, but the second one is being ignored since the library was already processed.
You should always put the libraries (once) at the end of the compiler command line:
c++ test.cpp -I./include-core/ -o bin/test test.cpp -L./bin -l${core_NAME_ROOT}

How can I verify linked libraries?

I am having lots of trouble getting a specific set of drivers working, called libnifalcon.
I am pretty sure that the installation was successful, but when I try to compile the example programs I get the errors:
mars#marslab:~/Documents/libnifalcon-1.0/examples/findfalcons$ g++ findfalcons.cpp
/tmp/cc8TtfGn.o: In function `runFalconTest()':
findfalcons.cpp:(.text+0x6b): undefined reference to `libnifalcon::FalconDevice::FalconDevice()'
findfalcons.cpp:(.text+0xdd): undefined reference to `libnifalcon::FalconDevice::getDeviceCount(unsigned int&)'
findfalcons.cpp:(.text+0x1bd): undefined reference to `libnifalcon::FalconDevice::open(unsigned int)'
findfalcons.cpp:(.text+0x224): undefined reference to `libnifalcon::FalconDevice::isFirmwareLoaded()'
findfalcons.cpp:(.text+0x2ac): undefined reference to `libnifalcon::FalconFirmware::loadFirmware(bool, unsigned int const&, unsigned char*)'
findfalcons.cpp:(.text+0x33b): undefined reference to `libnifalcon::FalconDevice::isFirmwareLoaded()'
findfalcons.cpp:(.text+0x3dd): undefined reference to `libnifalcon::FalconDevice::runIOLoop(unsigned int)'
findfalcons.cpp:(.text+0x504): undefined reference to `libnifalcon::FalconDevice::runIOLoop(unsigned int)'
findfalcons.cpp:(.text+0x512): undefined reference to `libnifalcon::FalconDevice::close()'
findfalcons.cpp:(.text+0x52b): undefined reference to `libnifalcon::FalconDevice::~FalconDevice()'
findfalcons.cpp:(.text+0x53f): undefined reference to `libnifalcon::FalconDevice::~FalconDevice()'
/tmp/cc8TtfGn.o: In function `void libnifalcon::FalconDevice::setFalconFirmware<libnifalcon::FalconFirmwareNovintSDK>()':
findfalcons.cpp:(.text._ZN11libnifalcon12FalconDevice17setFalconFirmwareINS_23FalconFirmwareNovintSDKEEEvv[void libnifalcon::FalconDevice::setFalconFirmware<libnifalcon::FalconFirmwareNovintSDK>()]+0x1d): undefined reference to `libnifalcon::FalconFirmwareNovintSDK::FalconFirmwareNovintSDK()'
collect2: ld returned 1 exit status
How can I verify the libraries are linked correctly? What can I do if they aren't?
You're not linking with anything, i.e.
g++ file.cpp
does not link to any libraries other than the standard library. You need to link with other modules or libraries, probably libnifalcon
g++ findfalcons.cpp -lnifalcon
or... you probably will need to do something like
g++ -L/path/to/libnifalcon findfalcons.cpp -lnifalcon
where -I tells where to look for libraries.

Why does my program fail to link when I change the order of g++'s arguments? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does the order of '-l' option in gcc matter?
I'm starting to learn the Boost Unit Test framework. I have a minimal test suite:
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( test1 ) {
BOOST_CHECK( 2 == 1 );
}
First I compile the source:
g++ -c src/tests.cc -o src/tests.o
This completes with no errors. I can then link as follows:
g++ -o tests src/tests.o -lboost_unit_test_framework
This also completes with no errors. The resulting binary executes with the expected results. However, if I swap the order of src/tests.o and -lboost_unit_test_framework, I get linker errors:
g++ -o tests -lboost_unit_test_framework src/tests.o
src/tests.o: In function `main':
tests.cc:(.text+0x29): undefined reference to `boost::unit_test::unit_test_main(bool (*)(), int, char**)'
src/tests.o: In function `test1::test_method()':
tests.cc:(.text+0x9d): undefined reference to `boost::unit_test::unit_test_log_t::set_checkpoint(boost::unit_test::basic_cstring, unsigned int, boost::unit_test::basic_cstring)'
tests.cc:(.text+0x146): undefined reference to `boost::test_tools::tt_detail::check_impl(boost::test_tools::predicate_result const&, boost::unit_test::lazy_ostream const&, boost::unit_test::basic_cstring, unsigned int, boost::test_tools::tt_detail::tool_level, boost::test_tools::tt_detail::check_type, unsigned int, ...)'
src/tests.o: In function `__static_initialization_and_destruction_0(int, int)':
tests.cc:(.text+0x24d): undefined reference to `boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::test_case*, unsigned long)'
src/tests.o: In function `boost::unit_test::unit_test_log_t::unit_test_log_t()':
tests.cc:(.text._ZN5boost9unit_test15unit_test_log_tC2Ev[_ZN5boost9unit_test15unit_test_log_tC5Ev]+0x21): undefined reference to `vtable for boost::unit_test::unit_test_log_t'
src/tests.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)':
tests.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)]+0x1d): undefined reference to `boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring)'
tests.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)]+0x5d): undefined reference to `boost::unit_test::test_case::test_case(boost::unit_test::basic_cstring, boost::unit_test::callback0 const&)'
src/tests.o: In function `boost::unit_test::unit_test_log_t::~unit_test_log_t()':
tests.cc:(.text._ZN5boost9unit_test15unit_test_log_tD2Ev[_ZN5boost9unit_test15unit_test_log_tD5Ev]+0xb): undefined reference to `vtable for boost::unit_test::unit_test_log_t'
collect2: ld returned 1 exit status
Why does the order of my arguments cause linker errors?
When GCC performs linking, libraries are treated specially: Only symbols that are missing from object files that came before the library in the command line list are filled in from the library. If you have further object files after a library, missing symbols from that object are not looked up in the library.
In a nutshell, list your object files first and libraries at the end.
The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:
http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html

gnuplot-iostream not linking to boost

Hi I'm trying to use gnuplot-iostream, at the minute I'm just trying to get the code here working. When I try to combile I get errors in the linker saying:
In function `stream<int, boost::iostreams::file_descriptor_flags>':
/usr/include/boost/iostreams/stream.hpp:130: undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(int, boost::iostreams::file_descriptor_flags)'
In function `boost::iostreams::file_descriptor_sink boost::iostreams::detail::wrap<boost::iostreams::file_descriptor_sink>(boost::iostreams::file_descriptor_sink const&, boost::disable_if<boost::iostreams::is_std_io<boost::iostreams::file_descriptor_sink>, void>::type*)':
/usr/include/boost/iostreams/detail/wrap_unwrap.hpp:53: undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(boost::iostreams::file_descriptor_sink const&)'
In function `concept_adapter':
/usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp:67: undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(boost::iostreams::file_descriptor_sink const&)'
/usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp:38: undefined reference to `boost::iostreams::file_descriptor_sink::file_descriptor_sink(boost::iostreams::file_descriptor_sink const&)'
In function `long boost::iostreams::detail::write_device_impl<boost::iostreams::output>::write<boost::iostreams::file_descriptor_sink>(boost::iostreams::file_descriptor_sink&, boost::iostreams::char_type_of<boost::iostreams::file_descriptor_sink>::type const*, long)':
/usr/include/boost/iostreams/write.hpp:121: undefined reference to `boost::iostreams::file_descriptor::write(char const*, long)'
In function `void boost::iostreams::detail::close_impl<boost::iostreams::closable_tag>::close<boost::iostreams::file_descriptor_sink>(boost::iostreams::file_descriptor_sink&, std::_Ios_Openmode)':
/usr/include/boost/iostreams/close.hpp:224: undefined reference to `boost::iostreams::file_descriptor::close()'
In function `std::fpos<__mbstate_t> boost::iostreams::detail::seek_device_impl<boost::iostreams::any_tag>::seek<boost::iostreams::file_descriptor_sink>(boost::iostreams::file_descriptor_sink&, long, std::_Ios_Seekdir, std::_Ios_Openmode)':
/usr/include/boost/iostreams/seek.hpp:137: undefined reference to `boost::iostreams::file_descriptor::seek(long, std::_Ios_Seekdir)'
collect2: ld returned 1 exit status
Note I have boost installed and have previously compiled programs that use iostream.
Any help massively appreciated. Thanks
Ruling out the obvious... are you compiling with g++ -lboost_iostreams? If you can share some information about how the compiler and linker are being invoked it will make it easier to answer your question.
Run into exact problem when tried to use g++ with gnuplot-iostream library.
g++ prog.cpp -L/usr/lib -lboost_filesystem -lboost_system -lboost_iostreams
Resolved the issue for me - the code were compiled successfully with no errors.

Error for the header file of goblin library in c++

I am trying to use Goblin library which is used for special network algorithms. This library provides some header files and objects in C/C++. So, you can easily add a header file to your program and use some special classes and functions.
Unfortunately, when I add the header file, I get error. In the following you can see the simple code and error.
Source:
#include<goblin.h>
int main()
{
return 0;
}
Error:
$ g++ -o test.o test.cpp
/tmp/ccB0Rb25.o: In function `goblinRootObject::~goblinRootObject()':
test.cpp:(.text._ZN16goblinRootObjectD1Ev[goblinRootObject::~goblinRootObject()]+0x10): undefined reference to `goblinNObjects'
test.cpp:(.text._ZN16goblinRootObjectD1Ev[goblinRootObject::~goblinRootObject()]+0x18): undefined reference to `goblinNObjects'
test.cpp:(.text._ZN16goblinRootObjectD1Ev[goblinRootObject::~goblinRootObject()]+0x2c): undefined reference to `goblinRootObject::operator delete(void*)'
/tmp/ccB0Rb25.o: In function `goblinRootObject::~goblinRootObject()':
test.cpp:(.text._ZN16goblinRootObjectD0Ev[goblinRootObject::~goblinRootObject()]+0x10): undefined reference to `goblinNObjects'
test.cpp:(.text._ZN16goblinRootObjectD0Ev[goblinRootObject::~goblinRootObject()]+0x18): undefined reference to `goblinNObjects'
test.cpp:(.text._ZN16goblinRootObjectD0Ev[goblinRootObject::~goblinRootObject()]+0x2c): undefined reference to `goblinRootObject::operator delete(void*)'
collect2: ld returned 1 exit status
try:
g++ -lgoblin -L/pathToLibgoblin/ -o test.o test.cpp