mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
Merge pull request #156 from aothms/nix_python_build_script
Nix python build script
This commit is contained in:
@@ -0,0 +1,516 @@
|
||||
#!/usr/bin/python
|
||||
###############################################################################
|
||||
# #
|
||||
# This file is part of IfcOpenShell. #
|
||||
# #
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the Lesser GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3.0 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IfcOpenShell is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# Lesser GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the Lesser GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# #
|
||||
# This script builds IfcOpenShell and its dependencies #
|
||||
# #
|
||||
# Prerequisites for this script to function correctly: #
|
||||
# * git * bzip2 * tar * c(++) compilers * yacc * autoconf #
|
||||
# on debian 7.8 these can be obtained with: #
|
||||
# $ apt-get install git gcc g++ autoconf bison bzip2 #
|
||||
# on ubuntu 14.04: #
|
||||
# $ apt-get install git gcc g++ autoconf bison make #
|
||||
# on OS X El Capitan with homebrew: #
|
||||
# $ brew install git bison autoconf automake #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import subprocess as sp
|
||||
import shutil
|
||||
import time
|
||||
import tarfile
|
||||
import multiprocessing
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.INFO)
|
||||
logger.addHandler(ch)
|
||||
|
||||
PROJECT_NAME="IfcOpenShell"
|
||||
OCE_VERSION="0.16"
|
||||
PYTHON_VERSIONS=["2.7.10", "3.2.6", "3.3.6", "3.4.4", "3.5.1"]
|
||||
BOOST_VERSION="1.59.0"
|
||||
PCRE_VERSION="8.38"
|
||||
LIBXML_VERSION="2.9.3"
|
||||
CMAKE_VERSION="3.4.1"
|
||||
ICU_VERSION="56.1"
|
||||
|
||||
# binaries
|
||||
bash = "bash"
|
||||
uname="uname"
|
||||
git="git"
|
||||
bunzip2="bunzip2"
|
||||
tar="tar"
|
||||
cc="cc"
|
||||
cplusplus="c++"
|
||||
autoconf="autoconf"
|
||||
automake="automake"
|
||||
yacc="yacc"
|
||||
make="make"
|
||||
date = "date"
|
||||
curl="curl"
|
||||
wget="wget"
|
||||
strip="strip"
|
||||
|
||||
# Helper function for coloured printing
|
||||
|
||||
NO_COLOR="\033[0m" # <ref>http://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux</ref>
|
||||
BLACK_ON_WHITE="\033[0;30;107m"
|
||||
RED="\033[31m"
|
||||
GREEN="\033[32m"
|
||||
YELLOW="\033[33m"
|
||||
MAGENTA="\033[35m"
|
||||
|
||||
def cecho(message, color=NO_COLOR):
|
||||
"""Logs message `message` in color `color`."""
|
||||
logger.info("%s%s\033[0m\n" % (color, message))
|
||||
|
||||
def fullpath(arg):
|
||||
return os.path.realpath(os.path.dirname(sys.argv[1]))
|
||||
|
||||
def which(cmd):
|
||||
for path in os.environ["PATH"].split(":"):
|
||||
if os.path.exists(path) and cmd in os.listdir(path):
|
||||
return cmd
|
||||
return None
|
||||
|
||||
def get_os():
|
||||
ret_value = sp.check_output([uname, "-s"]).strip()
|
||||
return ret_value
|
||||
|
||||
# Set defaults for missing empty environment variables
|
||||
|
||||
try:
|
||||
IFCOS_NUM_BUILD_PROCS = os.environ["IFCOS_NUM_BUILD_PROCS"]
|
||||
except KeyError:
|
||||
IFCOS_NUM_BUILD_PROCS=multiprocessing.cpu_count() + 1
|
||||
os.environ["IFCOS_NUM_BUILD_PROCS"]=str(IFCOS_NUM_BUILD_PROCS)
|
||||
|
||||
try:
|
||||
TARGET_ARCH = os.environ["TARGET_ARCH"]
|
||||
del os.environ["TARGET_ARCH"]
|
||||
except KeyError:
|
||||
TARGET_ARCH = sp.check_output([uname, "-m"]).strip()
|
||||
|
||||
CMAKE_DIR=os.path.realpath(os.path.join("..", "cmake"))
|
||||
|
||||
try:
|
||||
DEPS_DIR = os.environ["DEPS_DIR"]
|
||||
except KeyError:
|
||||
DEPS_DIR = os.path.realpath(os.path.join("..", "build", sp.check_output(uname).strip(), TARGET_ARCH))
|
||||
os.environ["DEPS_DIR"] = DEPS_DIR
|
||||
if not os.path.exists(DEPS_DIR):
|
||||
os.makedirs(DEPS_DIR)
|
||||
|
||||
try:
|
||||
BUILD_CFG=os.environ["BUID_CFG"]
|
||||
except KeyError:
|
||||
BUILD_CFG="RelWithDebInfo"
|
||||
os.environ["BUILD_CFG"]=BUILD_CFG
|
||||
|
||||
try:
|
||||
BUILD_TYPE=os.environ["BUILD_TYPE"]
|
||||
except KeyError:
|
||||
BUILD_TYPE="Build"
|
||||
os.environ["BUILD_TYPE"] = BUILD_TYPE
|
||||
|
||||
# Print build configuration information
|
||||
|
||||
cecho ("""This script fetches and builds %s and its dependencies
|
||||
""" % (PROJECT_NAME,), BLACK_ON_WHITE)
|
||||
cecho("""Script configuration:
|
||||
|
||||
""", GREEN)
|
||||
cecho("""* Target Architecture = %s""" % (TARGET_ARCH,), MAGENTA)
|
||||
cecho(" - Whether 32-bit (i686) or 64-bit (x86_64) will be built.")
|
||||
cecho("* Dependency Directory = %s" % (DEPS_DIR,), MAGENTA)
|
||||
cecho(" - The directory where %s dependencies are installed." % (PROJECT_NAME,))
|
||||
cecho("* Build Config Type = %s" % (BUILD_CFG,), MAGENTA)
|
||||
cecho(""" - The used build configuration type for the dependencies.
|
||||
Defaults to RelWithDebInfo if not specified.""")
|
||||
|
||||
if BUILD_CFG == "MinSizeRel":
|
||||
cecho(" WARNING: MinSizeRel build can suffer from a significant performance loss.", RED)
|
||||
|
||||
cecho("* IFCOS_NUM_BUILD_PROCS = %s" % (IFCOS_NUM_BUILD_PROCS,), MAGENTA)
|
||||
cecho(""" - How many compiler processes may be run in parallel.
|
||||
""")
|
||||
|
||||
# Check that required tools are in PATH
|
||||
|
||||
for cmd in [git, bunzip2, tar, cc, cplusplus, autoconf, automake, yacc, make]:
|
||||
if which(cmd) is None:
|
||||
raise ValueError("Required tool '%s' not installed or not added to PATH" % (cmd,))
|
||||
|
||||
# identifiers for the download tool (could be less memory consuming as ints, but are more verbose as strings)
|
||||
download_tool_curl="curl"
|
||||
download_tool_wget="wget"
|
||||
download_tool_git = "git"
|
||||
# curl randomly has trouble and fails with return code 6 without further feedback -> prefer wget
|
||||
if which(wget) != None:
|
||||
download_tool_default = download_tool_wget
|
||||
elif which(curl) != None:
|
||||
download_tool_default = download_tool_curl
|
||||
else:
|
||||
raise ValueError("No download application found, tried: curl, wget")
|
||||
CURL = ["curl", "-sLO"]
|
||||
WGET= ["wget", "-q", "--no-check-certificate"]
|
||||
|
||||
# Create log directory and file
|
||||
|
||||
log_dir = os.path.join(DEPS_DIR, "logs")
|
||||
if not os.path.exists(log_dir):
|
||||
os.makedirs(log_dir)
|
||||
LOG_FILE="%s.log" % (os.path.join(log_dir, sp.check_output([date, "+%Y%m%d"]).strip()),)
|
||||
if not os.path.exists(LOG_FILE):
|
||||
open(LOG_FILE, "w").close()
|
||||
logger.info("using command log file '%s'" % (LOG_FILE,))
|
||||
|
||||
def __check_call__(cmds, cwd=None):
|
||||
logger.info("running command '%s' in directory '%s'" % (" ".join(cmds), cwd))
|
||||
log_file_handle = open(LOG_FILE, "a")
|
||||
proc = sp.Popen(cmds, cwd=cwd, stdout=log_file_handle, stderr=sp.PIPE)
|
||||
_, stderr = proc.communicate()
|
||||
log_file_handle.write(stderr)
|
||||
log_file_handle.close()
|
||||
|
||||
if proc.returncode != 0:
|
||||
print "-" * 70
|
||||
print stderr
|
||||
print "-" * 70
|
||||
raise Exception("Command `%s` returned exit code %d" % (" ".join(cmds), proc.returncode))
|
||||
|
||||
def __check_output__(cmds, cwd=None):
|
||||
"""Wraps `subprocess.check_output` and logs the command being executed,
|
||||
sets up logging `stderr` to `LOG_FILE` (in append mode) and strips the
|
||||
return value because it's unlikely that the newline at the end of output is
|
||||
useful and it often causes errors"""
|
||||
logger.info("running command '%s' in directory '%s'" % (cmds, cwd))
|
||||
log_file_handle = open(LOG_FILE, "a")
|
||||
ret_value = sp.check_output(cmds, cwd=cwd, stderr=log_file_handle).strip()
|
||||
log_file_handle.close()
|
||||
return ret_value
|
||||
|
||||
BOOST_VERSION_UNDERSCORE=BOOST_VERSION.replace(".", "_")
|
||||
ICU_VERSION_UNDERSCORE=ICU_VERSION.replace(".", "_")
|
||||
CMAKE_VERSION_2=CMAKE_VERSION[0:3]
|
||||
|
||||
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
||||
BOOST_LOCATION="http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (BOOST_VERSION, BOOST_VERSION_UNDERSCORE)
|
||||
OPENCOLLADA_LOCATION="https://github.com/KhronosGroup/OpenCOLLADA.git"
|
||||
OPENCOLLADA_COMMIT="f99d59e73e565a41715eaebc00c7664e1ee5e628"
|
||||
|
||||
# Helper functions
|
||||
|
||||
def run_autoconf(arg1, configure_args, cwd):
|
||||
configure_path = os.path.realpath(os.path.join(cwd, "..", "configure"))
|
||||
if not os.path.exists(configure_path):
|
||||
__check_call__([bash, "./autogen.sh"], cwd=os.path.realpath(os.path.join(cwd, ".."))) # only run autogen.sh in the directory it is located and use cwd to achieve that in order to not mess up things
|
||||
# Using `sh` over `bash` fixes issues with building swig
|
||||
__check_call__(["/bin/sh", "../configure"]+configure_args+["--prefix=%s" % (os.path.realpath("%s/install/%s" % (DEPS_DIR, arg1)),)], cwd=cwd)
|
||||
|
||||
def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None):
|
||||
if cmake_dir is None:
|
||||
P=".."
|
||||
else:
|
||||
P=cmake_dir
|
||||
cmake_path= os.path.join(DEPS_DIR, "install", "cmake-%s" % (CMAKE_VERSION,), "bin", "cmake")
|
||||
__check_call__([cmake_path, P]+cmake_args+["-DCMAKE_BUILD_TYPE=%s" % (BUILD_TYPE,)], cwd=cwd)
|
||||
|
||||
def run_icu(arg1, icu_args, cwd):
|
||||
PLATFORM=get_os()
|
||||
if PLATFORM == "Darwin":
|
||||
PLATFORM="MacOSX"
|
||||
__check_call__([bash, "../source/runConfigureICU", PLATFORM]+icu_args+["--prefix=%s/install/%s" % (DEPS_DIR, arg1)], cwd=cwd)
|
||||
|
||||
def git_clone(clone_url, target_dir, revision=None):
|
||||
"""Lazily clones the `git` repository denoted by `clone_url` into
|
||||
`target_dir`, i.e. skips cloning if `target_dir` exists (naively assumes
|
||||
that a working clone exists there) and optionally checks out a revision
|
||||
`revision` after cloning or in the existing clone if `revision` is not
|
||||
`None`."""
|
||||
if not os.path.exists(target_dir):
|
||||
logger.info("cloning '%s' into '%s'" % (clone_url, target_dir))
|
||||
__check_call__([git, "clone", clone_url, target_dir])
|
||||
else:
|
||||
logger.info("directory '%s' exists, skipping cloning" % (target_dir,))
|
||||
if revision != None:
|
||||
__check_call__([git, "checkout", revision], cwd=target_dir)
|
||||
|
||||
def build_dependency(name, mode, build_tool_args, download_url, download_name, download_tool=download_tool_default, revision=None):
|
||||
"""Handles building of dependencies with different tools (which are
|
||||
distinguished with the `mode` argument. `build_tool_args` is expected to be
|
||||
a list which is necessary in order to not mess up quoting of compiler and
|
||||
linker flags."""
|
||||
check_dir = os.path.join(DEPS_DIR, "install", name)
|
||||
if os.path.exists(check_dir):
|
||||
logger.info( "Found existing %s, skipping" % (name,))
|
||||
return
|
||||
build_dir = os.path.join(DEPS_DIR, "build")
|
||||
if not os.path.exists(build_dir):
|
||||
os.makedirs(build_dir)
|
||||
|
||||
logger.info("\rFetching %s... " % (name,))
|
||||
if download_tool == download_tool_curl:
|
||||
download_path = os.path.join(build_dir, download_name)
|
||||
if not os.path.exists(download_path):
|
||||
__check_call__(CURL+[download_url, download_name], cwd=build_dir)
|
||||
else:
|
||||
logger.info("Download '%s' already exists, assuming it's an undamaged download and that it has been extracted if possible, skipping" % (download_path,))
|
||||
elif download_tool == download_tool_wget:
|
||||
download_path = os.path.join(build_dir, download_name)
|
||||
if not os.path.exists(download_path):
|
||||
__check_call__(WGET+[os.path.join(download_url, download_name)], cwd=build_dir)
|
||||
else:
|
||||
logger.info("Download '%s' already exists, assuming it's an undamaged download and that it has been extracted if possible, skipping" % (download_path,))
|
||||
elif download_tool == download_tool_git:
|
||||
git_clone(download_url, target_dir=os.path.join(build_dir, download_name), revision=revision)
|
||||
else:
|
||||
raise ValueError("download tool '%s' is not supported" % (download_tool,))
|
||||
download_dir = os.path.join(build_dir, download_name)
|
||||
if os.path.isdir(download_dir):
|
||||
extract_dir_name=download_name
|
||||
extract_dir = os.path.join(build_dir, extract_dir_name)
|
||||
else:
|
||||
download_tarfile_path = os.path.join(build_dir, download_name)
|
||||
if download_name.endswith(".tar.gz") or download_name.endswith(".tgz"):
|
||||
compr = "gz"
|
||||
elif download_name.endswith(".tar.bz2"):
|
||||
compr = "bz2"
|
||||
else:
|
||||
raise RuntimeError("fix source for new download type")
|
||||
download_tarfile = tarfile.open(name=download_tarfile_path, mode="r:%s" % (compr,))
|
||||
extract_dir_name= os.path.commonprefix(download_tarfile.getnames()) # tarfile seriously doesn't have a function to retrieve the root directory more easily
|
||||
#__check_output__([tar, "--exclude=\"*/*\"", "-tf", download_name], cwd=build_dir).strip() no longer works
|
||||
if extract_dir_name is None:
|
||||
extract_dir_name= __check_output__([bash, "-c", "tar -tf %s 2> /dev/null | head -n 1 | cut -f1 -d /" % (download_name,)], cwd=build_dir)
|
||||
extract_dir = os.path.join(build_dir, extract_dir_name)
|
||||
if not os.path.exists(extract_dir):
|
||||
__check_call__([tar, "-xf", download_name], cwd=build_dir)
|
||||
|
||||
if mode != "bjam":
|
||||
extract_build_dir = os.path.join(extract_dir, "build")
|
||||
if os.path.exists(extract_build_dir):
|
||||
shutil.rmtree(extract_build_dir)
|
||||
os.makedirs(extract_build_dir)
|
||||
|
||||
logger.info("\rConfiguring %s..." % (name,))
|
||||
if mode == "icu":
|
||||
run_icu(name, build_tool_args, cwd=extract_build_dir)
|
||||
elif mode == "autoconf":
|
||||
run_autoconf(name, build_tool_args, cwd=extract_build_dir)
|
||||
elif mode == "cmake":
|
||||
run_cmake(name, build_tool_args, cwd=extract_build_dir)
|
||||
else:
|
||||
raise ValueError()
|
||||
logger.info("\rBuilding %s... " % (name,))
|
||||
__check_call__([make, "-j%s" % (IFCOS_NUM_BUILD_PROCS,)], cwd=extract_build_dir)
|
||||
logger.info( "\rInstalling %s... " % (name,))
|
||||
__check_call__([make, "install"], cwd=extract_build_dir)
|
||||
logger.info( "\rInstalled %s \n" % (name,))
|
||||
else:
|
||||
logger.info( "\rConfiguring %s..." % (name,))
|
||||
__check_call__([bash, "./bootstrap.sh"], cwd=extract_dir)
|
||||
logger.info("\rBuilding %s... " % (name,))
|
||||
__check_call__(["./b2", "-j%s" % (IFCOS_NUM_BUILD_PROCS,)]+build_tool_args, cwd=extract_dir)
|
||||
logger.info("\rInstalling %s... " % (name,))
|
||||
shutil.copy(os.path.join(extract_dir, "boost"), os.path.join(DEPS_DIR, "install", "boost-%s" % (BOOST_VERSION,)))
|
||||
logger.info("\rInstalled %s \n" % (name,))
|
||||
|
||||
cecho("Collecting dependencies:", GREEN)
|
||||
|
||||
# Set compiler flags for 32bit builds on 64bit system
|
||||
# TODO: This is untested
|
||||
|
||||
ADDITIONAL_ARGS=[]
|
||||
BOOST_ADDRESS_MODEL=[]
|
||||
if TARGET_ARCH == "i686" and __check_output__([uname, "-m"]).strip() == "x86_64":
|
||||
ADDITIONAL_ARGS=["-m32", "-arch i386"]
|
||||
BOOST_ADDRESS_MODEL=["architecture=x86", "address-model=32"]
|
||||
|
||||
if get_os() == "Darwin":
|
||||
ADDITIONAL_ARGS=["-mmacosx-version-min=10.6"]+ADDITIONAL_ARGS
|
||||
|
||||
# If the linker supports GC sections, set it up to reduce binary file size
|
||||
# -fPIC is required for the shared libraries to work
|
||||
|
||||
try:
|
||||
CXXFLAGS=os.environ["CXXFLAGS"]
|
||||
except KeyError:
|
||||
CXXFLAGS=""
|
||||
try:
|
||||
CFLAGS=os.environ["CFLAGS"]
|
||||
except KeyError:
|
||||
CFLAGS=""
|
||||
try:
|
||||
LDFLAGS=os.environ["LDFLAGS"]
|
||||
except KeyError:
|
||||
LDFLAGS=""
|
||||
if sp.call([bash, "-c", "man ld 2> /dev/null | grep gc-sections &> /dev/null"]) == 0:
|
||||
CXXFLAGS_MINIMAL="%s -fPIC %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CXXFLAGS_MINIMAL"]=CXXFLAGS_MINIMAL
|
||||
CFLAGS_MINIMAL="%s -fPIC %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CFLAGS_MINIMAL"]=CFLAGS_MINIMAL
|
||||
CXXFLAGS="%s -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CXXFLAGS"]=CXXFLAGS
|
||||
CFLAGS="%s -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden %s"% (CFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CFLAGS"]=CFLAGS
|
||||
LDFLAGS="%s -Wl,--gc-sections %s" % (LDFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["LDFLAGS"]=LDFLAGS
|
||||
else:
|
||||
CXXFLAGS_MINIMAL="%s -fPIC %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CXXFLAGS_MINIMAL"]=CXXFLAGS_MINIMAL
|
||||
CFLAGS_MINIMAL="%s -fPIC %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CFLAGS_MINIMAL"]=CFLAGS_MINIMAL
|
||||
CXXFLAGS="%s -fPIC -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CXXFLAGS"]=CXXFLAGS
|
||||
CFLAGS="%s -fPIC -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["CFLAGS"]=CFLAGS
|
||||
LDFLAGS="%s %s" % (LDFLAGS, str.join(" ", ADDITIONAL_ARGS))
|
||||
os.environ["LDFLAGS"]=LDFLAGS
|
||||
|
||||
# Some dependencies need a more recent CMake version than most distros provide
|
||||
build_dependency(name="cmake-%s" % (CMAKE_VERSION,), mode="autoconf", build_tool_args=[], download_url="https://cmake.org/files/v%s" % (CMAKE_VERSION_2,), download_name="cmake-%s.tar.gz" % (CMAKE_VERSION,))
|
||||
|
||||
# Extract compiler flags from CMake to harmonize settings with other autoconf dependencies
|
||||
CMAKE_FLAG_EXTRACT_DIR="ifcopenshell_cmake_test_%s" % (time.time(),)
|
||||
# was sp.check_output([bash, "-c", "cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | head -c 32"]), in bash script, unclear what the exact required format is and whether it's needed
|
||||
if os.path.exists(CMAKE_FLAG_EXTRACT_DIR):
|
||||
shutil.rmtree(CMAKE_FLAG_EXTRACT_DIR)
|
||||
os.makedirs(CMAKE_FLAG_EXTRACT_DIR)
|
||||
BUILD_CFG_UPPER=BUILD_CFG.upper()
|
||||
for FL in ["C", "CXX"]:
|
||||
__check_call__([bash, "-c", """echo "
|
||||
message(\"\${CMAKE_%s_FLAGS_%s}\")
|
||||
" > CMakeLists.txt""" % (FL, BUILD_CFG_UPPER)], cwd=CMAKE_FLAG_EXTRACT_DIR)
|
||||
FL="%sFLAGS" % (FL,)
|
||||
FLM="%sFLAGS_MINIMAL" % (FL,)
|
||||
# @TODO: bash code unclear
|
||||
# exec("%sFLAGS=%s" % (FL, sp.check_output([os.path.join(DEPS_DIR, "install", "cmake-%s" % (CMAKE_VERSION,), "bin", "cmake"), "."
|
||||
# declare ${FL}FLAGS_MINIMAL="`$DEPS_DIR/install/cmake-$CMAKE_VERSION/bin/cmake . 2>&1 >/dev/null` ${!FLM}"
|
||||
shutil.rmtree(CMAKE_FLAG_EXTRACT_DIR)
|
||||
|
||||
build_dependency(name="pcre-%s" % (PCRE_VERSION,), mode="autoconf", build_tool_args=["--disable-shared"], download_url="ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/", download_name="pcre-%s.tar.bz2" % (PCRE_VERSION,))
|
||||
|
||||
# An issue exists with swig-1.3 and python >= 3.2
|
||||
# Therefore, build a recent copy from source
|
||||
build_dependency(name="swig", mode="autoconf", build_tool_args=["--with-pcre-prefix=%s/install/pcre-%s" % (DEPS_DIR, PCRE_VERSION)], download_url="https://github.com/swig/swig.git", download_name="swig", download_tool=download_tool_git, revision="rel-3.0.8")
|
||||
|
||||
build_dependency(name="oce-%s" % (OCE_VERSION,), mode="cmake", build_tool_args=["-DOCE_DISABLE_TKSERVICE_FONT=ON", "-DOCE_TESTING=OFF", "-DOCE_BUILD_SHARED_LIB=OFF", "-DOCE_DISABLE_X11=ON", "-DOCE_VISUALISATION=OFF", "-DOCE_OCAF=OFF", "-DOCE_INSTALL_PREFIX=%s/install/oce-%s" % (DEPS_DIR, OCE_VERSION)], download_url="https://github.com/tpaviot/oce/archive/", download_name="OCE-%s.tar.gz" % (OCE_VERSION,))
|
||||
build_dependency("libxml2-%s" % (LIBXML_VERSION,), "autoconf", build_tool_args=["--without-python", "--disable-shared", "--without-zlib", "--without-iconv", "--without-lzma"], download_url="ftp://xmlsoft.org/libxml2/", download_name="libxml2-%s.tar.gz" % (LIBXML_VERSION,))
|
||||
build_dependency("OpenCOLLADA", "cmake", build_tool_args=["-DLIBXML2_INCLUDE_DIR=%s/install/libxml2-%s/include/libxml2" % (DEPS_DIR, LIBXML_VERSION), "-DLIBXML2_LIBRARIES=%s/install/libxml2-%s/lib/libxml2.a" % (DEPS_DIR, LIBXML_VERSION), "-DPCRE_INCLUDE_DIR=%s/install/pcre-%s/include" % (DEPS_DIR, PCRE_VERSION), "-DPCRE_PCREPOSIX_LIBRARY=%s/install/pcre-%s/lib/libpcreposix.a" % (DEPS_DIR, PCRE_VERSION), "-DPCRE_PCRE_LIBRARY=%s/install/pcre-%s/lib/libpcre.a" % (DEPS_DIR, PCRE_VERSION), "-DCMAKE_INSTALL_PREFIX=%s/install/OpenCOLLADA/" % (DEPS_DIR,)], download_url="https://github.com/KhronosGroup/OpenCOLLADA.git", download_name="OpenCOLLADA", download_tool=download_tool_git, revision=OPENCOLLADA_COMMIT)
|
||||
|
||||
# Python should not be built with -fvisibility=hidden, from experience that introduces segfaults
|
||||
|
||||
OLD_CXX_FLAGS=os.environ["CXXFLAGS"]
|
||||
OLD_C_FLAGS=os.environ["CFLAGS"]
|
||||
os.environ["CXXFLAGS"]=CXXFLAGS_MINIMAL
|
||||
os.environ["CFLAGS"]=CFLAGS_MINIMAL
|
||||
|
||||
# On OSX a dynamic python library is built or it would not be compatible
|
||||
# with the system python because of some threading initialization
|
||||
PYTHON_CONFIGURE_ARGS=[]
|
||||
if get_os() == "Darwin":
|
||||
PYTHON_CONFIGURE_ARGS=["--disable-static", "--enable-shared"]
|
||||
|
||||
for PYTHON_VERSION in PYTHON_VERSIONS:
|
||||
build_dependency("python-%s" % (PYTHON_VERSION,), "autoconf", PYTHON_CONFIGURE_ARGS, "http://www.python.org/ftp/python/%s/" % (PYTHON_VERSION,), "Python-%s.tgz" % (PYTHON_VERSION,))
|
||||
|
||||
os.environ["CXXFLAGS"]=OLD_CXX_FLAGS
|
||||
os.environ["CFLAGS"]=OLD_C_FLAGS
|
||||
|
||||
build_dependency("boost-%s" % (BOOST_VERSION,), mode="bjam", build_tool_args=["--stagedir=%s/install/boost-%s" % (DEPS_DIR, BOOST_VERSION), "--with-system", "--with-program_options", "--with-regex", "--with-thread", "--with-date_time", "link=static"]+BOOST_ADDRESS_MODEL+["cxxflags=\"%s\"" % (CXXFLAGS,), "linkflags=\"%s\"" % (LDFLAGS,), "stage"], download_url="http://downloads.sourceforge.net/project/boost/boost/%s/" % (BOOST_VERSION,), download_name="boost_%s.tar.bz2" % (BOOST_VERSION_UNDERSCORE,))
|
||||
|
||||
build_dependency(name="icu-%s" % (ICU_VERSION,), mode="icu", build_tool_args=["--enable-static", "--disable-shared"], download_url="http://download.icu-project.org/files/icu4c/%s/" % (ICU_VERSION,), download_name="icu4c-%s-src.tgz" % (ICU_VERSION_UNDERSCORE,))
|
||||
|
||||
cecho("Building IfcOpenShell:", GREEN)
|
||||
|
||||
IFCOS_DIR=os.path.join(DEPS_DIR, "build", "ifcopenshell")
|
||||
if os.path.exists(IFCOS_DIR):
|
||||
shutil.rmtree(IFCOS_DIR)
|
||||
os.makedirs(IFCOS_DIR)
|
||||
|
||||
executables_dir = os.path.join(IFCOS_DIR, "executables")
|
||||
if not os.path.exists(executables_dir):
|
||||
os.makedirs(executables_dir)
|
||||
|
||||
logger.info("\rConfiguring executables...")
|
||||
|
||||
run_cmake("", cmake_args=["-DBOOST_ROOT=%s/install/boost-%s" % (DEPS_DIR, BOOST_VERSION), "-DOCC_INCLUDE_DIR=%s/install/oce-%s/include/oce" % (DEPS_DIR, OCE_VERSION), "-DOCC_LIBRARY_DIR=%s/install/oce-%s/lib" % (DEPS_DIR, OCE_VERSION), "-DOPENCOLLADA_INCLUDE_DIR=%s/install/OpenCOLLADA/include/opencollada" % (DEPS_DIR,), "-DOPENCOLLADA_LIBRARY_DIR=%s/install/OpenCOLLADA/lib/opencollada" % (DEPS_DIR,), "-DICU_INCLUDE_DIR=%s/install/icu-%s/include" % (DEPS_DIR, ICU_VERSION), "-DICU_LIBRARY_DIR=%s/install/icu-%s/lib" % (DEPS_DIR, ICU_VERSION), "-DPCRE_LIBRARY_DIR=%s/install/pcre-%s/lib" % (DEPS_DIR, PCRE_VERSION), "-DBUILD_IFCPYTHON=OFF"], cmake_dir=CMAKE_DIR, cwd=executables_dir)
|
||||
|
||||
logger.info("\rBuilding executables... ")
|
||||
|
||||
__check_call__([make, "-j%s" % (IFCOS_NUM_BUILD_PROCS,)], cwd=executables_dir)
|
||||
|
||||
if get_os() == "Darwin":
|
||||
STRIP_OPTION="-x"
|
||||
else:
|
||||
STRIP_OPTION="-s"
|
||||
|
||||
__check_call__([strip, STRIP_OPTION, "IfcConvert", "IfcGeomServer"], cwd=executables_dir)
|
||||
|
||||
# On OSX the actual Python library is not linked against.
|
||||
ADDITIONAL_ARGS=""
|
||||
if get_os() == "Darwin":
|
||||
ADDITIONAL_ARGS="-Wl,-flat_namespace,-undefined,suppress"
|
||||
|
||||
os.environ["CXXFLAGS"]="%s %s" % (CXXFLAGS_MINIMAL, ADDITIONAL_ARGS)
|
||||
os.environ["CFLAGS"]="%s %s" % (CFLAGS_MINIMAL, ADDITIONAL_ARGS)
|
||||
os.environ["LDFLAGS"]="%s %s" % (LDFLAGS, ADDITIONAL_ARGS)
|
||||
|
||||
for PYTHON_VERSION in PYTHON_VERSIONS:
|
||||
logger.info("\rConfiguring python %s wrapper..." % (PYTHON_VERSION,))
|
||||
|
||||
python_dir = os.path.join(IFCOS_DIR, "python-%s" % (PYTHON_VERSION,))
|
||||
if not os.path.exists(python_dir):
|
||||
os.makedirs(python_dir)
|
||||
|
||||
PYTHON_LIBRARY=__check_output__([bash, "-c", "ls %s/install/python-%s/lib/libpython*.*" % (DEPS_DIR, PYTHON_VERSION)], cwd=None).strip()
|
||||
PYTHON_INCLUDE=__check_output__([bash, "-c", "ls -d %s/install/python-%s/include/python*" % (DEPS_DIR, PYTHON_VERSION)], cwd=None).strip()
|
||||
PYTHON_EXECUTABLE=os.path.join(DEPS_DIR, "install", "python-%s" % (PYTHON_VERSION,), "bin", "python")
|
||||
os.environ["PYTHON_LIBRARY_BASENAME"]=os.path.basename(PYTHON_LIBRARY)
|
||||
|
||||
run_cmake("", cmake_args=["-DBOOST_ROOT=%s/install/boost-%s" % (DEPS_DIR, BOOST_VERSION),
|
||||
"-DOCC_INCLUDE_DIR=%s/install/oce-%s/include/oce" % (DEPS_DIR, OCE_VERSION),
|
||||
"-DOCC_LIBRARY_DIR=%s/install/oce-%s/lib" % (DEPS_DIR, OCE_VERSION),
|
||||
"-DOPENCOLLADA_INCLUDE_DIR=%s/install/OpenCOLLADA/include/opencollada" % (DEPS_DIR,),
|
||||
"-DOPENCOLLADA_LIBRARY_DIR=%s/install/OpenCOLLADA/lib/opencollada" % (DEPS_DIR,),
|
||||
"-DICU_INCLUDE_DIR=%s/install/icu-%s/include" % (DEPS_DIR, ICU_VERSION),
|
||||
"-DICU_LIBRARY_DIR=%s/install/icu-%s/lib" % (DEPS_DIR, ICU_VERSION),
|
||||
"-DPYTHON_LIBRARY=%s" % (PYTHON_LIBRARY,),
|
||||
"-DPYTHON_EXECUTABLE=%s" % (PYTHON_EXECUTABLE,),
|
||||
"-DPYTHON_INCLUDE_DIR=%s" % (PYTHON_INCLUDE,),
|
||||
"-DSWIG_EXECUTABLE=%s/install/swig/bin/swig" % (DEPS_DIR,),
|
||||
"-DCOLLADA_SUPPORT=OFF"], cmake_dir=CMAKE_DIR, cwd=python_dir)
|
||||
|
||||
logger.info("\rBuilding python %s wrapper... " % (PYTHON_VERSION,))
|
||||
|
||||
__check_call__([make, "-j%s" % (IFCOS_NUM_BUILD_PROCS,), "_ifcopenshell_wrapper"], cwd=python_dir)
|
||||
|
||||
if get_os() != "Darwin":
|
||||
# TODO: This symbol name depends on the Python version?
|
||||
__check_call__([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", "ifcwrap/_ifcopenshell_wrapper.so"], cwd=python_dir)
|
||||
|
||||
logger.info("\rBuilt IfcOpenShell...\n\n")
|
||||
@@ -1,403 +0,0 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# This file is part of IfcOpenShell. #
|
||||
# #
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the Lesser GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3.0 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IfcOpenShell is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# Lesser GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the Lesser GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# #
|
||||
# This script builds IfcOpenShell and its dependencies #
|
||||
# #
|
||||
# Prerequisites for this script to function correctly: #
|
||||
# * git * bzip2 * tar * c(++) compilers * yacc * autoconf #
|
||||
# on debian 7.8 these can be obtained with: #
|
||||
# $ apt-get install git gcc g++ autoconf bison bzip2 #
|
||||
# on ubuntu 14.04: #
|
||||
# $ apt-get install git gcc g++ autoconf bison make #
|
||||
# on OS X El Capitan with homebrew: #
|
||||
# $ brew install git bison autoconf automake #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_NAME=IfcOpenShell
|
||||
OCE_VERSION=0.16
|
||||
PYTHON_VERSIONS=(2.7.10 3.2.6 3.3.6 3.4.4 3.5.1)
|
||||
BOOST_VERSION=1.59.0
|
||||
PCRE_VERSION=8.38
|
||||
LIBXML_VERSION=2.9.3
|
||||
CMAKE_VERSION=3.4.1
|
||||
ICU_VERSION=56.1
|
||||
|
||||
# Helper function for coloured printing
|
||||
|
||||
BLACK_ON_WHITE="\033[0;30;107m"
|
||||
RED="\033[31m"
|
||||
GREEN="\033[32m"
|
||||
YELLOW="\033[33m"
|
||||
MAGENTA="\033[35m"
|
||||
function cecho {
|
||||
printf "$1$2\033[0m\n"
|
||||
}
|
||||
|
||||
function fullpath {
|
||||
python -c "import os, sys; print os.path.realpath(os.path.dirname(sys.argv[1]))" "$1"
|
||||
}
|
||||
|
||||
# Set defaults for missing empty environment variables
|
||||
|
||||
if [ -z "$IFCOS_NUM_BUILD_PROCS" ]; then
|
||||
IFCOS_NUM_BUILD_PROCS=$(expr $(sysctl -n hw.ncpu 2> /dev/null || cat /proc/cpuinfo | grep processor | wc -l) + 1)
|
||||
fi
|
||||
|
||||
if [ -z "$TARGET_ARCH" ]; then
|
||||
TARGET_ARCH="$(uname -m)"
|
||||
fi
|
||||
|
||||
SCRIPT_DIR=`fullpath "$0"`
|
||||
CMAKE_DIR="$SCRIPT_DIR/../cmake/"
|
||||
|
||||
if [ -z "$DEPS_DIR" ]; then
|
||||
DEPS_DIR="$SCRIPT_DIR/../build/$(uname)/$TARGET_ARCH/"
|
||||
[ -d $DEPS_DIR ] || mkdir -p $DEPS_DIR
|
||||
DEPS_DIR=`fullpath $DEPS_DIR`
|
||||
fi
|
||||
|
||||
if [ -z "$BUILD_CFG" ]; then
|
||||
BUILD_CFG="RelWithDebInfo"
|
||||
fi
|
||||
|
||||
if [ -z "$BUILD_TYPE" ]; then
|
||||
BUILD_TYPE=Build
|
||||
fi
|
||||
|
||||
# Print build configuration information
|
||||
|
||||
cecho $BLACK_ON_WHITE "This script fetches and builds $PROJECT_NAME and its dependencies"
|
||||
echo ""
|
||||
cecho $GREEN "Script configuration:"
|
||||
|
||||
cecho $MAGENTA "* Target Architecture = $TARGET_ARCH"
|
||||
echo " - Whether 32-bit (i686) or 64-bit (x86_64) will be built."
|
||||
cecho $MAGENTA "* Dependency Directory = $DEPS_DIR"
|
||||
echo " - The directory where $PROJECT_NAME dependencies are installed."
|
||||
cecho $MAGENTA "* Build Config Type = $BUILD_CFG"
|
||||
echo " - The used build configuration type for the dependencies."
|
||||
echo " Defaults to RelWithDebInfo if not specified."
|
||||
|
||||
if [ "$BUILD_CFG" = "MinSizeRel" ]; then
|
||||
cecho $RED " WARNING: MinSizeRel build can suffer from a significant performance loss."
|
||||
fi
|
||||
|
||||
cecho $MAGENTA "* IFCOS_NUM_BUILD_PROCS = $IFCOS_NUM_BUILD_PROCS"
|
||||
echo " - How many compiler processes may be run in parallel."
|
||||
|
||||
echo ""
|
||||
|
||||
# Check that required tools are in PATH
|
||||
|
||||
for cmd in git bunzip2 tar cc c++ autoconf automake yacc make
|
||||
do
|
||||
which $cmd > /dev/null || { cecho $RED "Required tool '$cmd' not installed or not added to PATH" ; exit 1 ; }
|
||||
done
|
||||
|
||||
which curl > /dev/null && DOWNLOAD="curl -sLO"
|
||||
which wget > /dev/null && DOWNLOAD="wget -q --no-check-certificate"
|
||||
|
||||
if [ -z "$DOWNLOAD" ]; then
|
||||
cecho $RED "No download application found, tried: curl, wget"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create log directory and file
|
||||
|
||||
mkdir -p $DEPS_DIR/logs
|
||||
LOG_FILE=$DEPS_DIR/logs/`date +"%Y%m%d"`.log
|
||||
|
||||
BOOST_VERSION_UNDERSCORE=${BOOST_VERSION//./_}
|
||||
ICU_VERSION_UNDERSCORE=${ICU_VERSION//./_}
|
||||
CMAKE_VERSION_2=${CMAKE_VERSION:0:3}
|
||||
|
||||
OCE_LOCATION=https://github.com/tpaviot/oce/archive/OCE-$OCE_VERSION.tar.gz
|
||||
BOOST_LOCATION=http://downloads.sourceforge.net/project/boost/boost/$BOOST_VERSION/boost_$BOOST_VERSION_UNDERSCORE.tar.bz2
|
||||
OPENCOLLADA_LOCATION=https://github.com/KhronosGroup/OpenCOLLADA.git
|
||||
OPENCOLLADA_COMMIT=f99d59e73e565a41715eaebc00c7664e1ee5e628
|
||||
|
||||
# Helper functions
|
||||
|
||||
function download {
|
||||
[ -f $2 ] || $DOWNLOAD $1$2
|
||||
}
|
||||
|
||||
function run_autoconf {
|
||||
if [ ! -f ../configure ]; then
|
||||
pushd . >>$LOG_FILE 2>&1
|
||||
cd ..
|
||||
./autogen.sh >>$LOG_FILE 2>&1
|
||||
popd >>$LOG_FILE 2>&1
|
||||
fi
|
||||
../configure $2 --prefix=$DEPS_DIR/install/$1 >>$LOG_FILE 2>&1
|
||||
}
|
||||
|
||||
function run_cmake {
|
||||
if [ -z "$3" ]; then
|
||||
P=..
|
||||
else
|
||||
P=$3
|
||||
fi
|
||||
$DEPS_DIR/install/cmake-$CMAKE_VERSION/bin/cmake $P $2 -DCMAKE_BUILD_TYPE=$BUILD_TYPE >>$LOG_FILE 2>&1
|
||||
}
|
||||
|
||||
function run_icu {
|
||||
PLATFORM=`uname -s`
|
||||
if [ $PLATFORM == "Darwin" ]; then
|
||||
PLATFORM=MacOSX
|
||||
fi
|
||||
../source/runConfigureICU $PLATFORM $2 --prefix=$DEPS_DIR/install/$1 >>$LOG_FILE 2>&1
|
||||
}
|
||||
|
||||
function git_clone {
|
||||
[ -d $2 ] || git clone $1 >>$LOG_FILE 2>&1
|
||||
if [ ! -z "$3" ]; then
|
||||
cd $2
|
||||
git checkout $3 >>$LOG_FILE 2>&1
|
||||
cd ..
|
||||
fi
|
||||
}
|
||||
|
||||
function build_dependency {
|
||||
if [ -e $DEPS_DIR/install/$1 ]; then
|
||||
echo "Found existing $1"
|
||||
return
|
||||
fi
|
||||
mkdir -p $DEPS_DIR/build/
|
||||
cd $DEPS_DIR/build/
|
||||
printf "\rFetching $1... "
|
||||
$6 $4 $5 $7
|
||||
if [ -d $5 ]; then
|
||||
DEP_NAME=$5
|
||||
else
|
||||
DEP_NAME=`tar --exclude="*/*" -tf $5`
|
||||
[ -z $DEP_NAME ] && DEP_NAME=`tar -tf $5 2> /dev/null | head -n 1 | cut -f1 -d /`
|
||||
[ -d $DEP_NAME ] || tar -xf $5
|
||||
fi
|
||||
cd $DEP_NAME
|
||||
if [ "$2" != "bjam" ]; then
|
||||
[ -d build ] && rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
printf "\rConfiguring $1..."
|
||||
run_$2 $1 "$3"
|
||||
printf "\rBuilding $1... "
|
||||
make -j$IFCOS_NUM_BUILD_PROCS >>$LOG_FILE 2>&1
|
||||
printf "\rInstalling $1... "
|
||||
make install >>$LOG_FILE 2>&1
|
||||
printf "\rInstalled $1 \n"
|
||||
else
|
||||
printf "\rConfiguring $1..."
|
||||
./bootstrap.sh >>$LOG_FILE 2>&1
|
||||
printf "\rBuilding $1... "
|
||||
eval ./b2 $3 >>$LOG_FILE 2>&1
|
||||
printf "\rInstalling $1... "
|
||||
cp -R boost $DEPS_DIR/install/boost-$BOOST_VERSION/ >>$LOG_FILE 2>&1
|
||||
printf "\rInstalled $1 \n"
|
||||
fi
|
||||
}
|
||||
|
||||
cecho $GREEN "Collecting dependencies:"
|
||||
|
||||
# Set compiler flags for 32bit builds on 64bit system
|
||||
# TODO: This is untested
|
||||
|
||||
if [ "$TARGET_ARCH" == "i686" ] && [ "$(uname -m)" == "x86_64" ]; then
|
||||
ADDITIONAL_ARGS="-m32 -arch i386"
|
||||
BOOST_ADDRESS_MODEL="architecture=x86 address-model=32"
|
||||
fi
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
ADDITIONAL_ARGS="-mmacosx-version-min=10.6 $ADDITIONAL_ARGS"
|
||||
fi
|
||||
|
||||
# If the linker supports GC sections, set it up to reduce binary file size
|
||||
# -fPIC is required for the shared libraries to work
|
||||
|
||||
if man ld 2> /dev/null | grep gc-sections &> /dev/null; then
|
||||
export CXXFLAGS_MINIMAL="$CXXFLAGS -fPIC $ADDITIONAL_ARGS"
|
||||
export CFLAGS_MINIMAL="$CFLAGS -fPIC $ADDITIONAL_ARGS"
|
||||
export CXXFLAGS="$CXXFLAGS -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden $ADDITIONAL_ARGS"
|
||||
export CFLAGS="$CFLAGS -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden $ADDITIONAL_ARGS"
|
||||
export LDFLAGS="$LDFLAGS -Wl,--gc-sections $ADDITIONAL_ARGS"
|
||||
else
|
||||
export CXXFLAGS_MINIMAL="$CXXFLAGS -fPIC $ADDITIONAL_ARGS"
|
||||
export CFLAGS_MINIMAL="$CFLAGS -fPIC $ADDITIONAL_ARGS"
|
||||
export CXXFLAGS="$CXXFLAGS -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $ADDITIONAL_ARGS"
|
||||
export CFLAGS="$CFLAGS -fPIC -fvisibility=hidden -fvisibility-inlines-hidden $ADDITIONAL_ARGS"
|
||||
export LDFLAGS="$LDFLAGS $ADDITIONAL_ARGS"
|
||||
fi
|
||||
|
||||
# Some dependencies need a more recent CMake version than most distros provide
|
||||
build_dependency cmake-$CMAKE_VERSION autoconf "" https://cmake.org/files/v$CMAKE_VERSION_2/ cmake-$CMAKE_VERSION.tar.gz download
|
||||
|
||||
# Extract compiler flags from CMake to harmonize settings with other autoconf dependencies
|
||||
CMAKE_FLAG_EXTRACT_DIR=ifcopenshell_cmake_test_`cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | head -c 32`
|
||||
[ -e $CMAKE_FLAG_EXTRACT_DIR ] && rm -rf $CMAKE_FLAG_EXTRACT_DIR
|
||||
mkdir $CMAKE_FLAG_EXTRACT_DIR
|
||||
cd $CMAKE_FLAG_EXTRACT_DIR
|
||||
BUILD_CFG_UPPER=`echo $BUILD_CFG | awk '{print toupper($0)}'`
|
||||
for FL in C CXX; do
|
||||
echo "
|
||||
message(\"\${CMAKE_${FL}_FLAGS_${BUILD_CFG_UPPER}}\")
|
||||
" > CMakeLists.txt
|
||||
FL=${FL}FLAGS
|
||||
FLM=${FL}FLAGS_MINIMAL
|
||||
declare ${FL}FLAGS="`$DEPS_DIR/install/cmake-$CMAKE_VERSION/bin/cmake . 2>&1 >/dev/null` ${!FL}"
|
||||
declare ${FL}FLAGS_MINIMAL="`$DEPS_DIR/install/cmake-$CMAKE_VERSION/bin/cmake . 2>&1 >/dev/null` ${!FLM}"
|
||||
done
|
||||
cd ..
|
||||
rm -rf $CMAKE_FLAG_EXTRACT_DIR
|
||||
|
||||
build_dependency pcre-$PCRE_VERSION autoconf "--disable-shared" ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ pcre-$PCRE_VERSION.tar.bz2 download
|
||||
|
||||
# An issue exists with swig-1.3 and python >= 3.2
|
||||
# Therefore, build a recent copy from source
|
||||
build_dependency swig autoconf "--with-pcre-prefix=$DEPS_DIR/install/pcre-$PCRE_VERSION" https://github.com/swig/swig.git swig git_clone rel-3.0.8
|
||||
|
||||
build_dependency oce-$OCE_VERSION cmake "-DOCE_DISABLE_TKSERVICE_FONT=ON -DOCE_TESTING=OFF -DOCE_BUILD_SHARED_LIB=OFF -DOCE_DISABLE_X11=ON -DOCE_VISUALISATION=OFF -DOCE_OCAF=OFF -DOCE_INSTALL_PREFIX=$DEPS_DIR/install/oce-$OCE_VERSION/" https://github.com/tpaviot/oce/archive/ OCE-$OCE_VERSION.tar.gz download
|
||||
build_dependency libxml2-$LIBXML_VERSION autoconf "--without-python --disable-shared --without-zlib --without-iconv --without-lzma" ftp://xmlsoft.org/libxml2/ libxml2-$LIBXML_VERSION.tar.gz download
|
||||
build_dependency OpenCOLLADA cmake "
|
||||
-DLIBXML2_INCLUDE_DIR=$DEPS_DIR/install/libxml2-$LIBXML_VERSION/include/libxml2
|
||||
-DLIBXML2_LIBRARIES=$DEPS_DIR/install/libxml2-$LIBXML_VERSION/lib/libxml2.a
|
||||
-DPCRE_INCLUDE_DIR=$DEPS_DIR/install/pcre-$PCRE_VERSION/include
|
||||
-DPCRE_PCREPOSIX_LIBRARY=$DEPS_DIR/install/pcre-$PCRE_VERSION/lib/libpcreposix.a
|
||||
-DPCRE_PCRE_LIBRARY=$DEPS_DIR/install/pcre-$PCRE_VERSION/lib/libpcre.a
|
||||
-DCMAKE_INSTALL_PREFIX=$DEPS_DIR/install/OpenCOLLADA/" https://github.com/KhronosGroup/OpenCOLLADA.git OpenCOLLADA git_clone $OPENCOLLADA_COMMIT
|
||||
|
||||
# Python should not be built with -fvisibility=hidden, from experience that introduces segfaults
|
||||
|
||||
OLD_CXX_FLAGS=$CXXFLAGS
|
||||
OLD_C_FLAGS=$CFLAGS
|
||||
export CXXFLAGS=$CXXFLAGS_MINIMAL
|
||||
export CFLAGS=$CFLAGS_MINIMAL
|
||||
|
||||
# On OSX a dynamic python library is built or it would not be compatible
|
||||
# with the system python because of some threading initialization
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
PYTHON_CONFIGURE_ARGS="--disable-static --enable-shared"
|
||||
fi
|
||||
|
||||
for PYTHON_VERSION in "${PYTHON_VERSIONS[@]}"; do
|
||||
build_dependency python-$PYTHON_VERSION autoconf "$PYTHON_CONFIGURE_ARGS" http://www.python.org/ftp/python/$PYTHON_VERSION/ Python-$PYTHON_VERSION.tgz download
|
||||
done
|
||||
|
||||
export CXXFLAGS=$OLD_CXX_FLAGS
|
||||
export CFLAGS=$OLD_C_FLAGS
|
||||
|
||||
build_dependency boost-$BOOST_VERSION bjam "--stagedir=$DEPS_DIR/install/boost-$BOOST_VERSION --with-system --with-program_options --with-regex --with-thread --with-date_time link=static $BOOST_ADDRESS_MODEL cxxflags=\"$CXXFLAGS\" linkflags=\"$LDFLAGS\" stage" http://downloads.sourceforge.net/project/boost/boost/$BOOST_VERSION/ boost_$BOOST_VERSION_UNDERSCORE.tar.bz2 download
|
||||
|
||||
build_dependency icu-$ICU_VERSION icu "--enable-static --disable-shared" http://download.icu-project.org/files/icu4c/$ICU_VERSION/ icu4c-${ICU_VERSION_UNDERSCORE}-src.tgz download
|
||||
|
||||
cecho $GREEN "Building IfcOpenShell:"
|
||||
|
||||
IFCOS_DIR=$DEPS_DIR/build/ifcopenshell
|
||||
[ -d $IFCOS_DIR ] && rm -rf $IFCOS_DIR
|
||||
mkdir -p $IFCOS_DIR
|
||||
cd $IFCOS_DIR
|
||||
|
||||
mkdir -p executables
|
||||
cd executables
|
||||
|
||||
printf "\rConfiguring executables..."
|
||||
|
||||
run_cmake "" "
|
||||
-DBOOST_ROOT=$DEPS_DIR/install/boost-$BOOST_VERSION
|
||||
-DOCC_INCLUDE_DIR=$DEPS_DIR/install/oce-$OCE_VERSION/include/oce
|
||||
-DOCC_LIBRARY_DIR=$DEPS_DIR/install/oce-$OCE_VERSION/lib
|
||||
-DOPENCOLLADA_INCLUDE_DIR=$DEPS_DIR/install/OpenCOLLADA/include/opencollada
|
||||
-DOPENCOLLADA_LIBRARY_DIR=$DEPS_DIR/install/OpenCOLLADA/lib/opencollada
|
||||
-DICU_INCLUDE_DIR=$DEPS_DIR/install/icu-$ICU_VERSION/include
|
||||
-DICU_LIBRARY_DIR=$DEPS_DIR/install/icu-$ICU_VERSION/lib
|
||||
-DPCRE_LIBRARY_DIR=$DEPS_DIR/install/pcre-$PCRE_VERSION/lib
|
||||
-DBUILD_IFCPYTHON=OFF
|
||||
" $CMAKE_DIR
|
||||
|
||||
printf "\rBuilding executables... "
|
||||
|
||||
make -j$IFCOS_NUM_BUILD_PROCS >>$LOG_FILE 2>&1
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
STRIP_OPTION=-x
|
||||
else
|
||||
STRIP_OPTION=-s
|
||||
fi
|
||||
|
||||
strip $STRIP_OPTION IfcConvert IfcGeomServer
|
||||
|
||||
cd ..
|
||||
|
||||
# On OSX the actual Python library is not linked against.
|
||||
ADDITIONAL_ARGS=
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
ADDITIONAL_ARGS="-Wl,-flat_namespace,-undefined,suppress"
|
||||
fi
|
||||
|
||||
export CXXFLAGS="$CXXFLAGS_MINIMAL $ADDITIONAL_ARGS"
|
||||
export CFLAGS="$CFLAGS_MINIMAL $ADDITIONAL_ARGS"
|
||||
export LDFLAGS="$LDFLAGS $ADDITIONAL_ARGS"
|
||||
|
||||
for PYTHON_VERSION in "${PYTHON_VERSIONS[@]}"; do
|
||||
|
||||
printf "\rConfiguring python $PYTHON_VERSION wrapper..."
|
||||
|
||||
mkdir -p python-$PYTHON_VERSION
|
||||
cd python-$PYTHON_VERSION
|
||||
|
||||
PYTHON_LIBRARY=`ls $DEPS_DIR/install/python-$PYTHON_VERSION/lib/libpython*.*`
|
||||
PYTHON_INCLUDE=`ls -d $DEPS_DIR/install/python-$PYTHON_VERSION/include/python*`
|
||||
PYTHON_EXECUTABLE=$DEPS_DIR/install/python-$PYTHON_VERSION/bin/python
|
||||
export PYTHON_LIBRARY_BASENAME=`basename $PYTHON_LIBRARY`
|
||||
|
||||
run_cmake "" "
|
||||
-DBOOST_ROOT=$DEPS_DIR/install/boost-$BOOST_VERSION
|
||||
-DOCC_INCLUDE_DIR=$DEPS_DIR/install/oce-$OCE_VERSION/include/oce
|
||||
-DOCC_LIBRARY_DIR=$DEPS_DIR/install/oce-$OCE_VERSION/lib
|
||||
-DOPENCOLLADA_INCLUDE_DIR=$DEPS_DIR/install/OpenCOLLADA/include/opencollada
|
||||
-DOPENCOLLADA_LIBRARY_DIR=$DEPS_DIR/install/OpenCOLLADA/lib/opencollada
|
||||
-DICU_INCLUDE_DIR=$DEPS_DIR/install/icu-$ICU_VERSION/include
|
||||
-DICU_LIBRARY_DIR=$DEPS_DIR/install/icu-$ICU_VERSION/lib
|
||||
-DPYTHON_LIBRARY=$PYTHON_LIBRARY
|
||||
-DPYTHON_EXECUTABLE=$PYTHON_EXECUTABLE
|
||||
-DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE
|
||||
-DSWIG_EXECUTABLE=$DEPS_DIR/install/swig/bin/swig
|
||||
-DCOLLADA_SUPPORT=OFF
|
||||
" $CMAKE_DIR
|
||||
|
||||
printf "\rBuilding python $PYTHON_VERSION wrapper... "
|
||||
|
||||
make -j$IFCOS_NUM_BUILD_PROCS _ifcopenshell_wrapper >>$LOG_FILE 2>&1
|
||||
|
||||
if [ "$(uname)" != "Darwin" ]; then
|
||||
# TODO: This symbol name depends on the Python version?
|
||||
strip -s \
|
||||
-K PyInit__ifcopenshell_wrapper \
|
||||
ifcwrap/_ifcopenshell_wrapper.so
|
||||
fi
|
||||
|
||||
cd ..
|
||||
|
||||
done
|
||||
|
||||
printf "\rBuilt IfcOpenShell... \n\n"
|
||||
Reference in New Issue
Block a user