applied patch to build on OSX Leopard and Sun's C++ compiler on Solaris from Justin Bronn

This commit is contained in:
Artem Pavlenko 2008-01-21 20:15:07 +00:00
parent 418e3fc43a
commit 2b60d6d425
14 changed files with 220 additions and 69 deletions

View file

@ -27,7 +27,12 @@ if platform.uname()[4] == 'x86_64':
else:
LIBDIR_SCHEMA='lib'
#### SCons build options and initial setup ####
# All of the following options may be modified at the command-line, for example:
# `python scons/scons PREFIX=/opt`
opts = Options('config.py')
opts.Add('CXX', 'The C++ compiler to use (defaults to g++).', 'g++')
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
@ -73,29 +78,44 @@ Help(opts.GenerateHelpText(env))
conf = Configure(env)
#### Libraries and headers dependency checks ####
# Helper function for uniquely appending paths to a SCons path listing.
def uniq_add(env, key, val):
if not val in env[key]: env[key].append(val)
# Libraries and headers dependency checks
env['CPPPATH'] = ['#agg/include', '#tinyxml', '#include', '#']
for path in [env['BOOST_INCLUDES'],
env['PNG_INCLUDES'],
env['JPEG_INCLUDES'],
env['TIFF_INCLUDES'],
env['PGSQL_INCLUDES'],
env['PROJ_INCLUDES'],
env['GDAL_INCLUDES']] :
if path not in env['CPPPATH']: env['CPPPATH'].append(path)
env['LIBPATH'] = ['#agg', '#src']
for path in [env['BOOST_LIBS'],
env['PNG_LIBS'],
env['JPEG_LIBS'],
env['TIFF_LIBS'],
env['PGSQL_LIBS'],
env['PROJ_LIBS'],
env['GDAL_LIBS']]:
if path not in env['LIBPATH']: env['LIBPATH'].append(path)
# Solaris & Sun Studio settings (the `SUNCC` flag will only be
# set if the `CXX` option begins with `CC`)
SOLARIS = env['PLATFORM'] == 'SunOS'
SUNCC = SOLARIS and env['CXX'].startswith('CC')
# For Solaris include paths (e.g., for freetype2, ltdl, etc.).
if SOLARIS:
blastwave_dir = '/opt/csw/%s'
uniq_add(env, 'CPPPATH', blastwave_dir % 'include')
uniq_add(env, 'LIBPATH', blastwave_dir % LIBDIR_SCHEMA)
# If the Sun Studio C++ compiler (`CC`) is used instead of GCC.
if SUNCC:
env['CC'] = 'cc'
# To be compatible w/Boost everything needs to be compiled
# with the `-library=stlport4` flag (which needs to come
# before the `-o` flag).
env['CXX'] = 'CC -library=stlport4'
if env['THREADING'] == 'multi':
env['CXXFLAGS'] = ['-mt']
# Adding the prerequisite library directories to the include path for
# compiling and the library path for linking, respectively.
for prereq in ('BOOST', 'PNG', 'JPEG', 'TIFF', 'PROJ', 'GDAL',):
inc_path = env['%s_INCLUDES' % prereq]
lib_path = env['%s_LIBS' % prereq]
uniq_add(env, 'CPPPATH', inc_path)
uniq_add(env, 'LIBPATH', lib_path)
env.ParseConfig(env['FREETYPE_CONFIG'] + ' --libs --cflags')
@ -121,6 +141,7 @@ C_LIBSHEADERS = [
['z', 'zlib.h', True],
['jpeg', ['stdio.h', 'jpeglib.h'], True],
['proj', 'proj_api.h', True],
['iconv', 'iconv.h', True],
['pq', 'libpq-fe.h', False]
]
@ -168,23 +189,20 @@ inputplugins = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])]
bindings = [ binding.strip() for binding in Split(env['BINDINGS'])]
#### Build instructions & settings ####
# Build agg first, doesn't need anything special
SConscript('agg/SConscript')
# Build the core library
SConscript('src/SConscript')
# Build shapeindex and remove its dependency from the LIBS
if 'boost_program_options%s-mt' % env['BOOST_APPEND'] in env['LIBS']:
SConscript('utils/shapeindex/SConscript')
env['LIBS'].remove('boost_program_options%s-mt' % env['BOOST_APPEND'])
# Build the input plug-ins
if 'postgis' in inputplugins and 'pq' in env['LIBS']:
SConscript('plugins/input/postgis/SConscript')
env['LIBS'].remove('pq')
@ -201,8 +219,7 @@ if 'gdal' in inputplugins and 'gdal' in env['LIBS']:
if 'gigabase' in inputplugins and 'gigabase_r' in env['LIBS']:
SConscript('plugins/input/gigabase/SConscript')
# Check out the Python situation
# Build the Python bindings.
if 'python' in env['BINDINGS']:
if not os.access(env['PYTHON'], os.X_OK):
color_print(1,"Cannot run python interpreter at '%s', make sure that you have the permissions to execute it." % env['PYTHON'])
@ -222,22 +239,44 @@ if 'python' in env['BINDINGS']:
color_print(4,'Python %s prefix... %s' % (env['PYTHON_VERSION'], env['PYTHON_PREFIX']))
SConscript('bindings/python/SConscript')
env = conf.Finish()
# Setup the c++ args for our own codebase
if env['PLATFORM'] == 'Darwin': pthread = ''
else: pthread = '-pthread'
# Common C++ flags.
common_cxx_flags = '-D%s -DBOOST_SPIRIT_THREADSAFE ' % env['PLATFORM'].upper()
common_cxx_flags = '-ansi -Wall %s -ftemplate-depth-100 -D%s -DBOOST_SPIRIT_THREADSAFE ' % (pthread, env['PLATFORM'].upper());
if env['DEBUG']:
env.Append(CXXFLAGS = common_cxx_flags + '-O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG')
# Mac OSX (Darwin) special settings
if env['PLATFORM'] == 'Darwin':
pthread = ''
# Getting the macintosh version number, sticking as a compiler macro
# for Leopard -- needed because different workarounds are needed than
# for Tiger.
if platform.mac_ver()[0].startswith('10.5'):
common_cxx_flags += '-DOSX_LEOPARD '
else:
env.Append(CXXFLAGS = common_cxx_flags + '-O2 -finline-functions -Wno-inline -DNDEBUG')
pthread = '-pthread'
# Common debugging flags.
debug_flags = '-g -DDEBUG -DMAPNIK_DEBUG'
ndebug_flags = '-DNDEBUG'
# Customizing the C++ compiler flags depending on:
# (1) the C++ compiler used; and
# (2) whether debug binaries are requested.
if SUNCC:
if env['DEBUG']:
env.Append(CXXFLAGS = common_cxx_flags + debug_flags)
else:
env.Append(CXXFLAGS = common_cxx_flags + '-O %s' % ndebug_flags)
else:
# Common flags for GCC.
gcc_cxx_flags = '-ansi -Wall %s -ftemplate-depth-100 %s' % (pthread, common_cxx_flags)
if env['DEBUG']:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags)
else:
env.Append(CXXFLAGS = gcc_cxx_flags + '-O2 -finline-functions -Wno-inline %s' % ndebug_flags)
# Install some free default fonts
SConscript('fonts/SConscript')

View file

@ -21,4 +21,7 @@ import glob
Import('env')
env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS='-O3 -fPIC -DNDEBUG')
if env['PLATFORM'] == 'SunOS':
env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS='-O -KPIC -DNDEBUG')
else:
env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS='-O3 -fPIC -DNDEBUG')

View file

@ -906,7 +906,12 @@ namespace boost { namespace property_tree
// Make sure that no pointer other than char_type * is allowed
BOOST_STATIC_ASSERT((is_pointer<Type>::value == false ||
is_same<char_type, typename remove_const<typename remove_pointer<Type>::type>::type>::value == true));
#ifdef __SUNPRO_CC
// For the Sun Studio compiler the declaration needs to be within a statement.
if (typename traits_type::template inserter<Type>()(m_impl->m_data, value, loc)){}
#else
typename traits_type::template inserter<Type>()(m_impl->m_data, value, loc);
#endif
}
// Put value in data of child ptree (custom path separator)

View file

@ -251,7 +251,7 @@ class MAPNIK_DECL enumeration {
std::cerr << "### FATAL: Not enough strings for enum "
<< our_name_ << " defined in file '" << filename
<< "' at line " << line_no << std::endl;
exit(1);
std::exit(1);
}
}
if ( std::string("") != our_strings_[THE_MAX])
@ -260,7 +260,7 @@ class MAPNIK_DECL enumeration {
<< " defined in file '" << filename << "' at line " << line_no
<< " has too many items or is not terminated with an "
<< "empty string." << std::endl;
exit(1);
std::exit(1);
}
return true;
}

View file

@ -27,6 +27,11 @@
#include <cmath>
// When using Sun's C++ compiler, use the `std` namespace to get the math routines.
#ifdef __SUNPRO_CC
using std::pow;
#endif
namespace mapnik
{
struct MAPNIK_DECL gamma

View file

@ -32,6 +32,12 @@
// stl
#include <cmath>
// When using Sun's C++ compiler, use the `std` namespace to get the math routines.
#ifdef __SUNPRO_CC
using std::fabs;
using std::sqrt;
#endif
namespace mapnik
{
template <typename T>

View file

@ -27,11 +27,15 @@
#include <boost/cstdint.hpp>
#ifdef __SUNPRO_CC
// Foo
#else
using boost::int32_t;
using boost::uint32_t;
using boost::int16_t;
using boost::uint16_t;
using boost::uint8_t;
#endif
namespace mapnik
{

View file

@ -28,6 +28,12 @@
#include <mapnik/octree.hpp>
#include <cassert>
// When using Sun's C++ compiler, use the `std` namespace to get memcpy, memset routines.
#ifdef __SUNPRO_CC
using std::memcpy;
using std::memset;
#endif
namespace mapnik
{
template <class T> class ImageData

View file

@ -79,8 +79,12 @@ namespace mapnik
static MaxAlign staticMemory;
return new(&staticMemory) T;
}
#ifdef __SUNPRO_CC
// Sun C++ Compiler doesn't handle `volatile` keyword same as GCC.
static void destroy(T* obj)
#else
static void destroy(volatile T* obj)
#endif
{
obj->~T();
}
@ -89,7 +93,15 @@ namespace mapnik
template <typename T,
template <typename T> class CreatePolicy=CreateStatic> class singleton
{
friend class CreatePolicy<T>;
#ifdef __SUNPRO_CC
/* Sun's C++ compiler will issue the following errors if CreatePolicy<T> is used:
Error: A class template name was expected instead of mapnik::CreatePolicy<mapnik::T>
Error: A "friend" declaration must specify a class or function.
*/
friend class CreatePolicy;
#else
friend class CreatePolicy<T>;
#endif
static T* pInstance_;
static bool destroyed_;
singleton(const singleton &rhs);

View file

@ -39,6 +39,8 @@ import os.path
cplusplus = __import__('c++', globals(), locals(), [])
compilers = ['CC', 'sunCC']
# use the package installer tool lslpp to figure out where cppc and what
# version of it is installed
def get_cppc(env):
@ -69,16 +71,11 @@ def generate(env):
cplusplus.generate(env)
env['CXX'] = cxx
env['SHCXX'] = shcxx
#env['SHCXX'] = shcxx
env['CXXVERSION'] = version
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -KPIC')
env['SHOBJPREFIX'] = 'so_'
env['SHOBJSUFFIX'] = '.o'
def exists(env):
path, cxx, shcxx, version = get_cppc(env)
if path and cxx:
cppc = os.path.join(path, cxx)
if os.path.exists(cppc):
return cppc
return None
return env.Detect(compilers)

View file

@ -35,6 +35,8 @@ libraries = ['agg'] + env['LIBS']
if env['PLATFORM'] == 'Darwin':
libraries.append('iconv')
linkflags = '-Wl,-install_name,libmapnik.dylib'
elif env['PLATFORM'] == 'SunOS' and env['CXX'].startswith('CC'):
linkflags = '-R. -h libmapnik.so'
else: # Linux and others
linkflags = '-Wl,-rpath-link,. -Wl,-soname,libmapnik.so.' + ("%d.%d" % (ABI_VERSION[0],ABI_VERSION[1]))

View file

@ -26,6 +26,15 @@
#include <mapnik/ellipsoid.hpp>
#include <cmath>
// When using Sun's C++ compiler, use the `std` namespace to get the math routines.
#ifdef __SUNPRO_CC
using std::atan2;
using std::cos;
using std::pow;
using std::sin;
using std::sqrt;
#endif
namespace mapnik {
static const double deg2rad = 0.0174532925199432958;

View file

@ -48,7 +48,10 @@ namespace mapnik
}
template <typename T>
inline bool Envelope<T>::operator==(const Envelope<T>& other) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::operator==(const Envelope<T>& other) const
{
return minx_==other.minx_ &&
miny_==other.miny_ &&
@ -57,43 +60,64 @@ namespace mapnik
}
template <typename T>
inline T Envelope<T>::minx() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::minx() const
{
return minx_;
}
template <typename T>
inline T Envelope<T>::maxx() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::maxx() const
{
return maxx_;
}
template <typename T>
inline T Envelope<T>::miny() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::miny() const
{
return miny_;
}
template <typename T>
inline T Envelope<T>::maxy() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::maxy() const
{
return maxy_;
}
template <typename T>
inline T Envelope<T>::width() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::width() const
{
return maxx_-minx_;
}
template <typename T>
inline T Envelope<T>::height() const
#if !defined(__SUNPRO_CC)
inline
#endif
T Envelope<T>::height() const
{
return maxy_-miny_;
}
template <typename T>
inline void Envelope<T>::width(T w)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::width(T w)
{
T cx=center().x;
minx_=static_cast<T>(cx-w*0.5);
@ -101,7 +125,10 @@ namespace mapnik
}
template <typename T>
inline void Envelope<T>::height(T h)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::height(T h)
{
T cy=center().y;
miny_=static_cast<T>(cy-h*0.5);
@ -109,20 +136,29 @@ namespace mapnik
}
template <typename T>
inline coord<T,2> Envelope<T>::center() const
#if !defined(__SUNPRO_CC)
inline
#endif
coord<T,2> Envelope<T>::center() const
{
return coord<T,2>(static_cast<T>(0.5*(minx_+maxx_)),
static_cast<T>(0.5*(miny_+maxy_)));
}
template <typename T>
inline void Envelope<T>::expand_to_include(const coord<T,2>& c)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::expand_to_include(const coord<T,2>& c)
{
expand_to_include(c.x,c.y);
}
template <typename T>
inline void Envelope<T>::expand_to_include(T x,T y)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::expand_to_include(T x,T y)
{
if (x<minx_) minx_=x;
if (x>maxx_) maxx_=x;
@ -140,19 +176,28 @@ namespace mapnik
}
template <typename T>
inline bool Envelope<T>::contains(const coord<T,2> &c) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::contains(const coord<T,2> &c) const
{
return contains(c.x,c.y);
}
template <typename T>
inline bool Envelope<T>::contains(T x,T y) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::contains(T x,T y) const
{
return x>=minx_ && x<=maxx_ && y>=miny_ && y<=maxy_;
}
template <typename T>
inline bool Envelope<T>::contains(const Envelope<T> &other) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::contains(const Envelope<T> &other) const
{
return other.minx_>=minx_ &&
other.maxx_<=maxx_ &&
@ -161,26 +206,38 @@ namespace mapnik
}
template <typename T>
inline bool Envelope<T>::intersects(const coord<T,2> &c) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::intersects(const coord<T,2> &c) const
{
return intersects(c.x,c.y);
}
template <typename T>
inline bool Envelope<T>::intersects(T x,T y) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::intersects(T x,T y) const
{
return !(x>maxx_ || x<minx_ || y>maxy_ || y<miny_);
}
template <typename T>
inline bool Envelope<T>::intersects(const Envelope<T> &other) const
#if !defined(__SUNPRO_CC)
inline
#endif
bool Envelope<T>::intersects(const Envelope<T> &other) const
{
return !(other.minx_>maxx_ || other.maxx_<minx_ ||
other.miny_>maxy_ || other.maxy_<miny_);
}
template <typename T>
inline Envelope<T> Envelope<T>::intersect(const EnvelopeType& other) const
#if !defined(__SUNPRO_CC)
inline
#endif
Envelope<T> Envelope<T>::intersect(const EnvelopeType& other) const
{
T x0=std::max(minx_,other.minx_);
@ -193,7 +250,10 @@ namespace mapnik
}
template <typename T>
inline void Envelope<T>::re_center(T cx,T cy)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::re_center(T cx,T cy)
{
T dx=cx-center().x;
T dy=cy-center().y;
@ -204,7 +264,10 @@ namespace mapnik
}
template <typename T>
inline void Envelope<T>::init(T x0,T y0,T x1,T y1)
#if !defined(__SUNPRO_CC)
inline
#endif
void Envelope<T>::init(T x0,T y0,T x1,T y1)
{
if (x0<x1)
{

View file

@ -179,7 +179,7 @@ namespace mapnik {
size_t inleft = input.size();
std::wstring output(inleft,0);
size_t outleft = inleft * sizeof(wchar_t);
#ifdef DARWIN
#if (!defined(OSX_LEOPARD) && defined(DARWIN)) || defined(SUNOS)
const char * in = input.c_str();
#else
char * in = const_cast<char*>(input.data());