How to link an archive without depending on an IDE? - c++

I've been using a TCP sockets tutorial for C++, and came across the following line -
Before we begin, you will need to include winsock.h and link libws2_32.a to your project in order to use the API that are necessary for TCP/IP. If this is not possible, use LoadLibrary() to load ws2_32.dll at runtime, or some similar method.
After some research, I found a source that claimed this could be done with the following two lines -
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
However, one of the two seem to not be working (I assume that it would be the second line, as the first is fairly straightforward). Here is the code I am trying to run -
#include <iostream>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
std::cout << gethostbyname("www.google.com") << std::endl;
return 0;
}
This code, which should be printing the IP address of Google, instead gives the following error -
C:\Users\Owner\AppData\Local\Temp\ccOXoE0F.o:SC.cpp:(.text+0x1e): undefined reference to 'gethosebyname#4'
collect2: ld returned 1 exit status
Some more googling revealed that the reason for this is an improper linking of the library. According to these sources, the only way to link this is through an IDE. I generally use Notepad++ along with the command prompt, and so I ask if it is possible to properly link this archive without using an IDE.
If it isn't possible, then it looks like I'll have to get back into using IDEs.

No, IDEs have nothing to do with this, and your desire is correct and entirely understandable. Since you seem to be on Windows, I'm not sure what kind of command-line toolchain you are using, but if it's one of the GNU-compatible ones (GCC with MinGW, for example), then you can specify the -lws2_32 linker flag to link against the library.

Related

Compiling boost::asio example on Windows

I am trying to switch to Windows environment from Linux, but find it a very hard path.
This time I wanted to test if I can work with boost library.
I had problems with compiling boost on windows, so I downloaded precompiled version. I unpacked everything and tested positively that I can compile the header-only librariers.
Then I copied some simple boost::asio example. I set up everything in Eclipse. Compilation went fine, but during linking I got 'undefined reference' problem to 'boost::system' internal stuff.
C:/Users/jacek/cpp/boost_1_62_0/boost/system/error_code.hpp:221: undefined reference to `boost::system::generic_category()'
C:/Users/jacek/cpp/boost_1_62_0/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
C:/Users/jacek/cpp/boost_1_62_0/boost/system/error_code.hpp:223: undefined reference to `boost::system::system_category()'
So I added '-lboost_system', as well as the path to the libraries directory, to my linking options. But this did not help.
g++ "-LC:\\Users\\jacek\\cpp\\boost_1_62_0\\lib64-msvc-14.0" -o TestAsio.exe "src\\Main.o" -lboost_system
I checked the libraries directory and found there is a bunch of files containing 'boost_system' in the name. They are:
libboost_system-vc140-mt-1_62.lib
libboost_system-vc140-mt-gd-1_62.lib
libboost_system-vc140-mt-s-1_62.lib
libboost_system-vc140-mt-sgd-1_62.lib
libboost_system-vc140-s-1_62.lib
libboost_system-vc140-sgd-1_62.lib
I did not know which I should use. I tried adding 'libboost_system-vc140-mt-1_62' to the linking options, I tried all other files, I tried renaming the files to the linux pattern 'libboost_system.a', but nothing worked.
g++ "-LC:\\Users\\jacek\\cpp\\boost_1_62_0\\lib64-msvc-14.0" -o TestAsio.exe "src\\Main.o" -llibboost_system-vc140-mt-1_62 -llibboost_system-vc140-mt-gd-1_62 -llibboost_system-vc140-mt-s-1_62 -llibboost_system-vc140-mt-sgd-1_62 -llibboost_system-vc140-s-1_62 -llibboost_system-vc140-sgd-1_62
What am I doing wrong here?
Please help...
YotKay
I solved it myself with the help of a comment from this post: boost asio example compilation error
It looks like the precompiled version of Boost is created with Visual Studion and is NOT COMPATIBLE with G++. I if I decided to install MinGW then I cannot use the precompiled version of boost, but must compile it myself using g++.
I did that.
Now I have libraries compiled with G++.
I specify the path to the boost system library like that:
c:\Users\jacek\cpp\boost_1_62_0\libraries\boost\bin.v2\libs\system\build\gcc-mingw-6.2.0\debug\link-static\
and add this option:
-lboost_system-mgw62-d-1_62
Now the problem with boost::system disappears. However, another one pops up with boost asio, but luckily the answer is here: MinGW linker error: winsock
The example works fine now on my Windows 10 laptop.
#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <iostream>
using namespace boost::asio;
int main()
{
io_service ioservice;
steady_timer timer{ioservice, std::chrono::seconds{3}};
timer.async_wait([](const boost::system::error_code &ec)
{ std::cout << "3 sec\n"; });
ioservice.run();
}

Simple C++ program using pqxx (postgres)

I'm trying a very basic C++ program using Code::Blocks. I'm on Ubuntu 12.04 and installed pqxx from the software manager. Here's the code.
#include <pqxx/pqxx>
#include <iostream>
using namespace std;
int main()
{
pqxx::connection MyConn ("dbname=dbESM user=postgres");
cout << "Hello world!" << endl;
return 0;
}
But I get the following error on hitting F9 to compile and run:
/usr/include/pqxx/connection.hxx|87|undefined reference to
`pqxx::connectionpolicy::connectionpolicy(std::basic_string, std::allocator > const&)'
The above message is from the file connection.hxx and the line highlighted is this:
explicit connect_direct(const PGSTD::string &opts) : connectionpolicy(opts) {}
The connection.hxx file is not mine - I think it's part of pqxx.
I'm pretty new to this platform so I'm avoiding the terminal to compile code. Any help would be greatly appreciated.
You need to add the reference to the libpqxx library to the project.
Inside Code::blocks, when the project is open, locate Project in the menus, then follow Build options, then open the tab called Linker settings, then hit Add, then enter pqxx.
If you were using the libpq C library instead, the procedure would be identical except the name would be pq.
You need to link against the according library, just #including the header files isn't enough. If available, you could use pkg-config to determine the according libraries. Further, what IDE are you using? Without that, the "on hitting F9" reference is useless. Also, compiling this on the commandline might even be easier, since it is clearer what exactly is happening.

Weird 'undefined reference' error

I have run into a peculiar error in a C++ project at work.
I have found a fix, but I am now really satisfied, as I would like to understand what actually causes the error.
When building this snippet of code:
#include <iostream>
#include "snmp/snmp/SW_SNMP_Values.hpp"
#include "snmp/agent/SW_Agent.hpp"
#include "snmp/agent/SW_Agent_PP.hpp"
int main()
{
//SW_Agent_PP agent;
return 0;
}
Notice that SW_Agent_PP is COMMENTED OUT!! When building this, I get a ton of undefined reference errors, for classes that are in use by the SW_Agent_PP object.
The FIX is to ACTUALLY CREATE THE OBJECT! so if I do this:
#include <iostream>
#include "snmp/snmp/SW_SNMP_Values.hpp"
#include "snmp/agent/SW_Agent.hpp"
#include "snmp/agent/SW_Agent_PP.hpp"
int main()
{
SW_Agent_PP agent;
return 0;
}
everything works fine and dandy.
How can I get linker errors for NOT using something? I would like to hear if anyone have run into similar experiences before, and if they found what caused it.
I am sorry, but I cannot release more code as it is company property.
Many thanks in advance!
Linkers are complicated and this behaviour is by no means unusual. Here's one possible explanation:
You are linking with a static library libfoo.a.
libfoo.a contains foo.o that contains SW_Agent_PP::SW_Agent_PP() and a bunch of other functions.
Another library libbar.a, listed after libfoo.a in the link line, uses a bunch of other functions from libfoo.a.
The linker processes static libraries in order and never goes back. Therefore the references in libbar.a can be only satisfied if corresponding object was pulled from libfoo.a by main().
The solution is to reorder the libraries in the link line.
There are other possible explanations. It's hard to tell without seeing actual code.

C++:Undefined reference to 'FMOD:: X'

After looking around for various sound API libraries, I have decided to use FMOD for the time being.
Problem is that whenever I try to compile one of the code examples, I get the following errors:
obj\Release\main.o:main.cpp|| undefined reference to `FMOD::System::getVersion(unsigned int*)#8'|
obj\Release\main.o:main.cpp|| undefined reference to `FMOD::System::init(int, unsigned int, void*)#16'|
obj\Release\main.o:main.cpp|| undefined reference to `FMOD::System::createSound(char const*, unsigned int, FMOD_CREATESOUNDEXINFO*, FMOD::Sound**)#20'|
obj\Release\main.o:main.cpp|| undefined reference to `FMOD::Sound::setMode(unsigned int)#8'|
The code example that I am using being this:
#include <D:\Games\FMOD Programmers API Win32\api\inc\fmod.hpp>
#include <D:\Games\FMOD Programmers API Win32\api\inc\fmod_errors.h>
#include <sstream>
#include <windows.h> // for PlaySound()
#include <time.h>
#include <mmsystem.h>
using namespace std;
int main(int argc, char* argv[])
{
FMOD::System *system;
FMOD::Sound *sound1, *sound2, *sound3;
FMOD::Channel *channel = 0;
FMOD_RESULT result;
int key;
unsigned int version;
/*
Create a System object and initialize.
*/
result = FMOD::System_Create(&system);
result = system->getVersion(&version);
result = system->init(32, FMOD_INIT_NORMAL, 0);
result = system->createSound("../media/drumloop.wav", FMOD_HARDWARE, 0, &sound1);
result = sound1->setMode(FMOD_LOOP_OFF); /* drumloop.wav has embedded loop points which automatically makes looping turn on, */
/* so turn it off here. We could have also just put FMOD_LOOP_OFF in the above CreateSound call. */
// Code continues into other bits that work...
I am using the latest version of FMOD and am using the Code::Blocks IDE (ver 10.05), with the GNU GCC compiler. The project is of type "Console application". The fmodex.dll file is in the folder of my project. I am using windows XP 32 bit SP3.
I have linked to the libfmodex.a library and have tried linking to the other libraries it has there as well, but this does not solve the problem.
My question is, therefore, what do I need to do to stop these errors occurring? As when I encountered similar "Undefined reference to x" errors before using other libraries. I had just forgotten to link to them in Code::Blocks and as soon as I did, they would work.
Do say if you need more information regarding the code etc.
When using FMOD with Code::Blocks you need to use the C API, not the C++ API. FMOD is built with Visual Studio, therefore the C++ symbols use the VC mangling scheme. There is a note in the "Getting Started with FMOD for Windows" document that mentions this.
http://en.wikipedia.org/wiki/Name_mangling#How_different_compilers_mangle_the_same_functions
I do not have a Windows box ready to verify this on, but try replacing those backslashes with forward slashes in the include paths, or escape the backslashes.
#include <D:/Games/FMOD Programmers API Win32/api/inc/fmod.hpp>
#include <D:/Games/FMOD Programmers API Win32/api/inc/fmod_errors.h>
or
#include <D:\\Games\\FMOD Programmers API Win32\\api\\inc\\fmod.hpp>
#include <D:\\Games\\FMOD Programmers API Win32\\api\\inc\\fmod_errors.h>
(Or, better, just add D:\Games\FMOD Programmers API Win32\api\inc\ to your list of include paths, and include the files by filename instead of full path; then your code might actually compile somewhere other than your specific computer!)
Those undefined reference errors mean that the compiler, or rather the linker part of the compiler, cannot find the library.
I don't use Code::Blocks so I don't know where the setting is, but you need to tell your project to use the library and where to find it.
Just putting the DLL in the directory is enough for running the program, but for linking it you need a .lib file.

Code Blocks, MinGW, Boost, and static linking issues

I am using Code Blocks with MinGW and am trying to get a simple program to compile with static linking. I have built the Boost libraries using these directions. Everything worked out fine and I was able to successfully compile this simple program (it compiles, I know it doesn't work because it exits before the message is sent to the console, but I just want it to compile).
If I have a DLL in my linker libraries, it compiles fine, but when I switch it with the static .a libraries of the same contents, I get undefined references such as "undefined reference to `_imp___ZN5boost6threadD1Ev'|".
I have no idea what the problem is and can't find the solution. I think it might have to do with linker settings but I can't find information on how to change them. I would be extremely grateful for any help that could be provided.
#include <iostream>
#include <boost/thread.hpp>
void myfunction()
{
std::cout << "this is a thread" << std::endl;
return;
}
int main()
{
boost::thread mythread(&myfunction);
return 0;
}
It's from trying to link statically when the headers are configured for a dynamic link. I explain this for libssh in this question. Poking around in boost/thread/detail/config.hpp makes me think you should #define BOOST_THREAD_USE_LIB, or use the -D flag to do the same.