SCons script that builds shared libraries

gunnar
Posts: 18
Joined: Fri Jun 20, 2008 2:01 pm

SCons script that builds shared libraries

Post by gunnar »

Hi,

I discovered that the bullet build scripts (CMake and Jam) do not create shared libraries, so I put together a SCons script that does exactly that. I have only tested this script on Linux, might not work on Windows without modifications.

SConstruct:

Code: Select all

import fnmatch, os, os.path, shutil

env = Environment()

DIST_FOLDER = "./build/"

if not os.path.exists(DIST_FOLDER):
  os.makedirs(DIST_FOLDER)

# === List files/directories ===
def list_recursive(parent, pattern = "*", basedir="", files = None, directories = None):
  
  if files == None:
    files = []
  
  if directories == None:
    directories = []
  
  for entry in os.listdir(parent):
    entrypath = os.path.join(parent, entry)
    if os.path.isfile(entrypath) and fnmatch.fnmatch(entry, pattern):
      files.append(entrypath)
    elif os.path.isdir(entrypath):
      directories.append(entrypath)
      list_recursive(entrypath, pattern, os.path.join(basedir, entry), files, directories)
  
  return {'files': files, 'directories': directories}

# === Copy headers ===
def copy_headers(parent, todir, pattern, basedir="", recursive=True):
  for entry in os.listdir( parent ):
    entrypath = os.path.join( parent, entry )
    if os.path.isfile( entrypath ) and fnmatch.fnmatch(entry, pattern):
      copy_from = entrypath
      copy_to = ""
      if basedir != "":
        copy_to = "%s/%s/%s" % (todir, basedir, entry)
      else:
        copy_to = "%s/%s" % (todir, entry)
      print "%s => %s" % (copy_from, copy_to)
      if not os.path.isdir(os.path.dirname(copy_to)):
        os.makedirs(os.path.dirname(copy_to))
      shutil.copy(copy_from, copy_to)
    elif os.path.isdir( entrypath ) and recursive:
      copy_headers( entrypath, todir, pattern, os.path.join( basedir, entry ), recursive )

# === Build a bullet core library ===
def build_bullet_library(env, source_folders, include_folders, lib_name):
  sources = []
  includedirs = []
  for source in source_folders:
    sources += list_recursive(source, "*.cpp")['files']
  for folder in include_folders:
    includedirs.append(folder)
    includedirs += list_recursive(folder)['directories']
  libs = []
  libdirs = []
  defines = ["-Wall"]
  bullet_library_so = env.SharedLibrary(lib_name, sources, LIBS=libs, CPPPATH=includedirs, CCFLAGS=defines, LIBPATH=libdirs)
  env.Install("%s/lib" % (DIST_FOLDER), bullet_library_so)

# === Build libraries ===
build_bullet_library(env, ["./src/BulletCollision"], ["./src"], "bulletcollision")
build_bullet_library(env, ["./src/BulletDynamics"], ["./src"], "bulletdynamics")
build_bullet_library(env, ["./src/LinearMath"], ["./src"], "bulletmath")
build_bullet_library(env, ["./src/BulletSoftBody"], ["./src"], "bulletsoftbody")

gimpact_src = ["./Extras/GIMPACT", "./Extras/GIMPACTUtils", "Extras/ConvexDecomposition"]
build_bullet_library(env, gimpact_src, (gimpact_src + ["./src"]), "GIMPACT")

colladaconv_src = ["./Extras/BulletColladaConverter"]
build_bullet_library(env, colladaconv_src, (colladaconv_src + ["./src", "./Extras/COLLADA_DOM/include"]), 
  "bulletcolladaconverter")
# ======================

# === Copy headers ===
copy_headers("./src", ("%sinclude/bullet" % (DIST_FOLDER)), "*.h")
copy_headers("./Extras/GIMPACT/include", ("%sinclude/bullet" % (DIST_FOLDER)), "*.h")
copy_headers("./Extras/GIMPACTUtils", ("%sinclude/bullet/GIMPACTUtils" % (DIST_FOLDER)), "*.h")
copy_headers("./Extras/BulletColladaConverter", ("%sinclude/bullet/BulletColladaConverter" % (DIST_FOLDER)), "*.h")
# ====================

How to use:
1: install scons
2: download bullet + the attached SConstruct
3: copy the SConstruct file to the bullet-2.xx folder (i.e. bullet-2.69)
4: in the bullet-2.xx folder, run "scons"

The script creates the *.so files in bullet-2.xx/build/ folder, and copies the required headers to bullet-2.xx/build/include/bullet

PS: I created this script because I could not figure out how to build shared libraries with Jam, and CMake wouldn't create the "make install" command.