Compiling boost on Mac OS X Mavericks [duplicate] - c++

This question already has answers here:
C++ Boost: undefined reference to boost::system::generic_category()
(13 answers)
Closed 8 years ago.
There are many threads on this topic, but I've tried some of the solutions and nothing seems to work.
If I install boost with:
brew install booost --c++11
and try to compile the following program tut1.cpp:
#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: tut1 path\n";
return 1;
}
std::cout << argv[1] << " " << file_size(argv[1]) << '\n';
return 0;
}
using
clang -I /usr/local/Cellar/boost/1.55.0_1/include/ -L /usr/local/Cellar/boost/1.55.0_1/lib/ tut1.cpp
and it fails horribly:
Undefined symbols for architecture x86_64:
"boost::filesystem::path::codecvt()", referenced from:
boost::filesystem::path::path<char*>(char* const&, boost::enable_if<boost::filesystem::path_traits::is_pathable<boost::decay<char*>::type>, void>::type*) in tut1-6a2087.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 linking seems to be the problem because if I invoke the -c option the object file gets created.
Any ideas what the hell is going on?

You want to link against boost filesystem and boost system:
-lboost_filesystem -lboost_system
So the complete compile command would be:
clang++ -I /usr/local/opt/boost/include -L /usr/local/opt/boost/lib tut1.cpp -lboost_filesystem -lboost_system

Related

g++ failing when trying to use GDAL library [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 months ago.
I just want to compile this easy example of the GDAL library in my Ubuntu 22.04 system using the system-packed g++, version 11.3.0:
#include <iostream>
#include "gdal_priv.h"
#include "cpl_conv.h"
#include "gdal.h"
using namespace std;
int main(int argc, char* argv[])
{
GDALDataset *poDataset;
GDALAllRegister();
poDataset = (GDALDataset *) GDALOpen(argv[1], GA_ReadOnly);
if (poDataset == NULL)
{
cout << "No dataset loaded for file " << argv[1] << ". Exiting." << endl;
return 1;
}
cout << "Driver: "
<< poDataset->GetDriver()->GetDescription()
<< "/"
<< poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME)
<< endl;
cout << "Size: "
<< poDataset->GetRasterXSize() << "x"
<< poDataset->GetRasterYSize() << "x"
<< poDataset->GetRasterCount()
<< endl;
if (poDataset->GetProjectionRef() != NULL)
{
cout << "Projection: " << poDataset->GetProjectionRef() << endl;
}
}
Of course I installed the GDAL libraries, as it can be seen here:
~$ dpkg -l | grep gdal
ii gdal-bin 3.4.1+dfsg-1build4 amd64 Geospatial Data Abstraction Library - Utility programs
ii gdal-data 3.4.1+dfsg-1build4 all Geospatial Data Abstraction Library - Data files
ii libgdal-dev 3.4.1+dfsg-1build4 amd64 Geospatial Data Abstraction Library - Development files
ii libgdal30 3.4.1+dfsg-1build4 amd64 Geospatial Data Abstraction Library
ii python3-gdal 3.4.1+dfsg-1build4 amd64 Python 3 bindings to the Geospatial Data Abstraction Library
Everything seems to be settled and ready to go, but then, when I trigger this g++ command to compile my little program
g++ -I/usr/include/gdal -L/usr/lib -lgdal open_file.cpp -o open_file -g
it fails with this output:
/usr/bin/ld: /tmp/ccU6PwuP.o: in function `main':
/home/jose/Code/concepts/gdal/open_file.cpp:13: undefined reference to `GDALAllRegister'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:14: undefined reference to `GDALOpen'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:29: undefined reference to `GDALDataset::GetRasterXSize()'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:30: undefined reference to `GDALDataset::GetRasterYSize()'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:31: undefined reference to `GDALDataset::GetRasterCount()'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:34: undefined reference to `GDALDataset::GetProjectionRef() const'
/usr/bin/ld: /home/jose/Code/concepts/gdal/open_file.cpp:36: undefined reference to `GDALDataset::GetProjectionRef() const'
collect2: error: ld returned 1 exit status
Which doesn't make any sense, because I am indeed passing the GDAL libraries in -I/usr/include/gdal and the definition of the "undefined" references do exist in the multiple .h files there.
Moreover, this works using clang++:
clang++ -I/usr/include/gdal -L/usr/lib -lgdal open_file.cpp -o open_file -g
Did anyone have a similar issue, or can give some hint on where the problem might be? Thank you.
Include paths have nothing to do with the symbols.
-I/usr/include/gdal -L/usr/lib both are not necessary as they are set by default. But you should use #include <gdal/gdal.h>, not just <gdal.h> and certainly not "gdal.h".
Move -lgdal after all other cpp/object files.
In general, it should be g++ <OPTIONS> <OBJECTS> <LIBRARIES> where library A which uses symbols from lib B should appear after B i.e. -lB -lA, the order matters for ld. Because it will use the library to resolve just the currently missing symbols and then will promptly forget the library ever existed. So any newly found unresolved symbols will not be resolved, hence shifting the library arguments "right". One can resolve circular dependencies by repeating libraries more than once.

Basic practice of dynamic library C++

I am trying dynamic-linking test.
mylib.cpp
#include<iostream>
#include<stdio.h>
using namespace std;
int hello(){
cout<<"Hello,World!"<<endl;
return 1;
}
then compile
g++ -shared -o libmylib.so mylib.cpp
Now there appears the libmylib.so
test.cpp
#include <iostream>
int hello();
int main() {
hello();
std::cout << "Test Finish!\n";
return 0;
}
Try to compile with this,
g++ -o test test.cpp -L ./
There comes the error
Undefined symbols for architecture x86_64:
"hello()", referenced from:
_main in test-37bd2a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Do I need to add some options or are there something wrong in my source code??
Thank you for your help.
Do I need to add some options
yes, link with the library.
g++ ... -lmylib

Trying to find maximum size of atomic load/store operation [duplicate]

Just a bit code of C++11:
#include<iostream>
#include<atomic>
struct A { int a[4]; };
struct B { int x, y; };
int main()
{
std::cout << std::boolalpha
<< "std::atomic<A> is lock free? "
<< std::atomic<A>{}.is_lock_free() << '\n'
<< "std::atomic<B> is lock free? "
<< std::atomic<B>{}.is_lock_free() << '\n';
}
Compile with mac+clang, it gives error:
Undefined symbols for architecture x86_64:
"___atomic_is_lock_free", referenced from:
_main in atomics.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
clang + ubuntu docker gives:
root#b01946bedcf2:/# clang++ --version
clang version 4.0.0-1ubuntu1 (tags/RELEASE_400/rc1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
root#b01946bedcf2:/# clang++ 1.cpp -std=c++11 -lpthread
/tmp/1-7cc6e9.o: In function `std::atomic<A>::is_lock_free() const':
1.cpp:(.text._ZNKSt6atomicI1AE12is_lock_freeEv[_ZNKSt6atomicI1AE12is_lock_freeEv]+0x1b): undefined reference to `__atomic_is_lock_free'
/tmp/1-7cc6e9.o: In function `std::atomic<B>::is_lock_free() const':
1.cpp:(.text._ZNKSt6atomicI1BE12is_lock_freeEv[_ZNKSt6atomicI1BE12is_lock_freeEv]+0x1b): undefined reference to `__atomic_is_lock_free'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And on RHEL7+gcc4.8.5, it gives:
$g++ 1.cpp -std=c++11 -lpthread && ./a.out
/tmp/ccW9pNc2.o: In function `std::atomic<A>::is_lock_free() const':
1.cpp:(.text._ZNKSt6atomicI1AE12is_lock_freeEv[_ZNKSt6atomicI1AE12is_lock_freeEv]+0x17): undefined reference to `__atomic_is_lock_free'
collect2: error: ld returned 1 exit status
This is really odd. What's wrong with the code, or does it require a super-high version of compiler?
You need to include the atomic library.
$ g++ 1.cpp -std=c++11 -latomic && ./a.out

Boost.MPI gives Undefined symbols for architecture x86_64

I am trying to run the basic "Hello, World!" example:
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
namespace mpi = boost::mpi;
int main()
{
mpi::environment env;
mpi::communicator world;
std::cout << "I am process " << world.rank() << " of " << world.size()
<< "." << std::endl;
return 0;
}
I have tried numerous variants for running this program:
mpic++ -I /usr/local/include/ test.cpp -o test -lboost_system
also:
mpic++ -I /usr/local/include/boost test.cpp -o test -lboost_system
and using mpicc, and clang++ as a substitute. Each combination gives the follow error:
Undefined symbols for architecture x86_64:
"boost::mpi::environment::environment(bool)", referenced from:
_main in test-b0215f.o
"boost::mpi::environment::~environment()", referenced from:
_main in test-b0215f.o
"boost::mpi::communicator::communicator()", referenced from:
_main in test-b0215f.o
"boost::mpi::communicator::rank() const", referenced from:
_main in test-b0215f.o
"boost::mpi::communicator::size() const", referenced from:
_main in test-b0215f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Homebrew says that both MPICH2 and boost1.63.0 are installed. I can confirm that mpic++ runs by compiling and then running this program:
// required MPI include file
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[]) {
int numtasks, rank, len, rc;
char hostname[MPI_MAX_PROCESSOR_NAME];
// initialize MPI
MPI_Init(&argc,&argv);
// get number of tasks
MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
// get my rank
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
// this one is obvious
MPI_Get_processor_name(hostname, &len);
printf ("Number of tasks= %d My rank= %d Running on %s\n", numtasks,rank,hostname);
// do some work with message passing
// done with MPI
MPI_Finalize();
}
Which produces the correct output.
I have also verified that (at least part of) Boost is installed by compiling and successfully running the Boost "Hello, World!"
//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.wait();
std::cout << "Hello, world!" << std::endl;
return 0;
}
with:
clang++ -I /usr/local/include/ timer.cpp -o timer -lboost_system
How can I get the Boost.MPI example to run?
When you get linker errors from boost, you usually forgot to link against a boost library.
There is also a boost_mpi library, so you should compile with
clang++ -I /usr/local/include/ timer.cpp -o timer -lboost_system -lboost_mpi
Note that you need a boost version with support for mpi.
Generally consider http://www.boost.org/doc/libs/1_58_0/doc/html/mpi/getting_started.html
Specifically with homebrew you can check How to build boost with mpi support on homebrew?

link error when accessing std::string members on Mac Yosemite with libc++

I'm trying to compile this kind of code and I get link errors when trying to build using latest Xcode (6.0) on MacOSX Yosemite:
#include <iostream>
#include <string>
int main()
{
auto x = &std::string::size;
std::string hello("hello");
std::cout << (hello.*x)() << std::endl;
return 0;
}
$ g++ --std=c++11 -stdlib=libc++ hello.cpp -o hello
KO:
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::size() const", referenced from:
_main in hello-a9a7cd.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Note that the code compiles file using libstdc++:
$ g++ --std=c++11 -stdlib=libstdc++ hello.cpp -o hello
OK
I was having the same problem. See Taking pointer to member std::string::size fails to link with libc++ but works with libstdc++
Basically the solution I came up with is to force the instantiation of the std::string template class.
Here is the proposed solution:
#include <iostream>
#include <string>
template class std::basic_string<char>;
int main()
{
auto x = &std::string::size;
std::string hello("hello");
std::cout << (hello.*x)() << std::endl;
return 0;
}