From 440f57d591ceba866f4915e8df6f89e88ebadc5b Mon Sep 17 00:00:00 2001 From: Pebaz Date: Mon, 13 Jan 2020 19:32:54 -0500 Subject: [PATCH 1/4] Windows Build Script and Associated Documentation Per Platform --- README.md | 58 +++++++++++++--- example/example.py | 100 +++++++++++++-------------- requirements/build_win32.ps1 | 129 +++++++++++++++++++++++++++++++++++ setup.py | 126 ++++++++++++++++++++-------------- 4 files changed, 303 insertions(+), 110 deletions(-) create mode 100644 requirements/build_win32.ps1 diff --git a/README.md b/README.md index 9297ebe..887647a 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,58 @@ This package also supports most of FCL's object shapes, including: ## Installation -First, install [octomap](https://github.com/OctoMap/octomap), which is necessary using OcTree. For Ubuntu, using `sudo apt-get install liboctomap-dev` -Second, install FCL using the instructions provided [here](https://github.com/flexible-collision-library/fcl). -If you're on Ubuntu 17.04 or newer, you can install FCL using `sudo apt-get install libfcl-dev`. -Otherwise, just compile FCL from source -- it's quick and easy, and its dependencies are all easily installed via `apt` or `brew`. - -In order to install the Python wrappers for FCL, simply run -```shell -pip install python-fcl +### Linux + +First install needed dependencies: + +```bash +sudo apt-get install liboctomap-dev libfcl-dev +``` + +Then install for your particular Python version: + +```bash +pip3 install python-fcl ``` +### MacOS + +First install needed dependencies: + +```bash +brew install fcl eigen octomap libccd +``` + +Then install for your particular Python version: + +```bash +pip3 install python-fcl +``` + +### Windows + +Building on Windows requires: + +* Python3 (e.g. Not tested using Python2) +* Cython +* CMake +* MSVC (Visual Studio 16 2019) + +> Since the build script places artifacts in `C:\Program Files (x86)`, it is +necessary to run it using an "Administrator PowerShell" prompt. + +```bash +# Run using Administrator PowerShell prompt. WILL FAIL WITHOUT PROPER ACCESS + +git clone https://github.com/BerkeleyAutomation/python-fcl +cd python-fcl + +# Use CMake to compile/install all dependencies along with installing python-fcl +requirements/build_win32.ps1 +``` + +# Usage Examples + ## Objects ### Collision Objects diff --git a/example/example.py b/example/example.py index 4c42710..a233389 100644 --- a/example/example.py +++ b/example/example.py @@ -1,28 +1,29 @@ +from __future__ import print_function import numpy as np import fcl def print_collision_result(o1_name, o2_name, result): - print 'Collision between {} and {}:'.format(o1_name, o2_name) - print '-'*30 - print 'Collision?: {}'.format(result.is_collision) - print 'Number of contacts: {}'.format(len(result.contacts)) - print '' + print('Collision between {} and {}:'.format(o1_name, o2_name)) + print('-'*30) + print('Collision?: {}'.format(result.is_collision)) + print('Number of contacts: {}'.format(len(result.contacts))) + print() def print_continuous_collision_result(o1_name, o2_name, result): - print 'Continuous collision between {} and {}:'.format(o1_name, o2_name) - print '-'*30 - print 'Collision?: {}'.format(result.is_collide) - print 'Time of collision: {}'.format(result.time_of_contact) - print '' + print('Continuous collision between {} and {}:'.format(o1_name, o2_name)) + print('-'*30) + print('Collision?: {}'.format(result.is_collide)) + print('Time of collision: {}'.format(result.time_of_contact)) + print() def print_distance_result(o1_name, o2_name, result): - print 'Distance between {} and {}:'.format(o1_name, o2_name) - print '-'*30 - print 'Distance: {}'.format(result.min_distance) - print 'Closest Points:' - print result.nearest_points[0] - print result.nearest_points[1] - print '' + print('Distance between {} and {}:'.format(o1_name, o2_name)) + print('-'*30) + print('Distance: {}'.format(result.min_distance)) + print('Closest Points:') + print(result.nearest_points[0]) + print(result.nearest_points[1]) + print() # Create simple geometries box = fcl.Box(1.0, 2.0, 3.0) @@ -48,10 +49,10 @@ def print_distance_result(o1_name, o2_name, result): #===================================================================== # Pairwise collision checking #===================================================================== -print '='*60 -print 'Testing Pairwise Collision Checking' -print '='*60 -print '' +print('='*60) +print('Testing Pairwise Collision Checking') +print('='*60) +print() req = fcl.CollisionRequest(enable_contact=True) res = fcl.CollisionResult() @@ -74,10 +75,10 @@ def print_distance_result(o1_name, o2_name, result): #===================================================================== # Pairwise distance checking #===================================================================== -print '='*60 -print 'Testing Pairwise Distance Checking' -print '='*60 -print '' +print('='*60) +print('Testing Pairwise Distance Checking') +print('='*60) +print() req = fcl.DistanceRequest(enable_nearest_points=True) res = fcl.DistanceResult() @@ -100,10 +101,10 @@ def print_distance_result(o1_name, o2_name, result): #===================================================================== # Pairwise continuous collision checking #===================================================================== -print '='*60 -print 'Testing Pairwise Continuous Collision Checking' -print '='*60 -print '' +print('='*60) +print('Testing Pairwise Continuous Collision Checking') +print('='*60) +print() req = fcl.ContinuousCollisionRequest() res = fcl.ContinuousCollisionResult() @@ -118,10 +119,10 @@ def print_distance_result(o1_name, o2_name, result): #===================================================================== # Managed collision checking #===================================================================== -print '='*60 -print 'Testing Managed Collision and Distance Checking' -print '='*60 -print '' +print('='*60) +print('Testing Managed Collision and Distance Checking') +print('='*60) +print('') objs1 = [fcl.CollisionObject(box, fcl.Transform(np.array([20,0,0]))), fcl.CollisionObject(sphere)] objs2 = [fcl.CollisionObject(cone), fcl.CollisionObject(mesh)] objs3 = [fcl.CollisionObject(box), fcl.CollisionObject(sphere)] @@ -143,26 +144,26 @@ def print_distance_result(o1_name, o2_name, result): #===================================================================== cdata = fcl.CollisionData() manager1.collide(cdata, fcl.defaultCollisionCallback) -print 'Collision within manager 1?: {}'.format(cdata.result.is_collision) -print '' +print('Collision within manager 1?: {}'.format(cdata.result.is_collision)) +print() cdata = fcl.CollisionData() manager2.collide(cdata, fcl.defaultCollisionCallback) -print 'Collision within manager 2?: {}'.format(cdata.result.is_collision) -print '' +print('Collision within manager 2?: {}'.format(cdata.result.is_collision)) +print() ##===================================================================== ## Managed internal (n^2) distance checking ##===================================================================== ddata = fcl.DistanceData() manager1.distance(ddata, fcl.defaultDistanceCallback) -print 'Closest distance within manager 1?: {}'.format(ddata.result.min_distance) -print '' +print('Closest distance within manager 1?: {}'.format(ddata.result.min_distance)) +print() ddata = fcl.DistanceData() manager2.distance(ddata, fcl.defaultDistanceCallback) -print 'Closest distance within manager 2?: {}'.format(ddata.result.min_distance) -print '' +print('Closest distance within manager 2?: {}'.format(ddata.result.min_distance)) +print() #===================================================================== # Managed one to many collision checking @@ -171,20 +172,19 @@ def print_distance_result(o1_name, o2_name, result): rdata = fcl.CollisionData(request = req) manager1.collide(fcl.CollisionObject(mesh), rdata, fcl.defaultCollisionCallback) -print 'Collision between manager 1 and Mesh?: {}'.format(rdata.result.is_collision) -print 'Contacts:' +print('Collision between manager 1 and Mesh?: {}'.format(rdata.result.is_collision)) +print('Contacts:') for c in rdata.result.contacts: - print '\tO1: {}, O2: {}'.format(c.o1, c.o2) -print '' + print('\tO1: {}, O2: {}'.format(c.o1, c.o2)) +print() #===================================================================== # Managed many to many collision checking #===================================================================== rdata = fcl.CollisionData(request = req) manager3.collide(manager2, rdata, fcl.defaultCollisionCallback) -print 'Collision between manager 2 and manager 3?: {}'.format(rdata.result.is_collision) -print 'Contacts:' +print('Collision between manager 2 and manager 3?: {}'.format(rdata.result.is_collision)) +print('Contacts:') for c in rdata.result.contacts: - print '\tO1: {}, O2: {}'.format(c.o1, c.o2) -print '' - + print('\tO1: {}, O2: {}'.format(c.o1, c.o2)) +print() diff --git a/requirements/build_win32.ps1 b/requirements/build_win32.ps1 new file mode 100644 index 0000000..a57b3c0 --- /dev/null +++ b/requirements/build_win32.ps1 @@ -0,0 +1,129 @@ +<# +This script builds fcl and it's dependencies for python-fcl on Windows. + +It downloads, builds, installs, and then deletes: + * fcl + * libccd + * eigen + * octomap +#> + +# Ensure that paths are constant between runs +pushd $PSScriptRoot + +# Create a directory that encapsulates all Git repos +mkdir fcl; cd fcl + + +#------------------------------------------------------------------------------ +# Eigen +Write-Host "Building Eigen" +git clone https://gitlab.com/libeigen/eigen.git +cd eigen +mkdir build; cd build +cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 16 2019" -DBUILD_SHARED_LIBS=ON .. +cmake --build . --config Release --target install +Write-Host "Done" +cd ../.. + + +# ------------------------------------------------------------------------------ +# LibCCD +Write-Host "Building LibCCD" +git clone https://github.com/danfis/libccd +cd libccd +mkdir build; cd build +cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 16 2019" -DBUILD_SHARED_LIBS=ON .. +cmake --build . --config Release --target install +Write-Host "Done" +cd ../.. + +# FCL won't be able to find libccd unless it is named "ccd" exactly +Rename-Item "C:\Program Files (x86)\libccd" ccd + + +# ------------------------------------------------------------------------------ +# Octomap +Write-Host "Building Octomap" +git clone https://github.com/OctoMap/octomap +cd octomap +mkdir build; cd build +cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 16 2019" -DBUILD_SHARED_LIBS=ON .. + +# Build Octomap (won't install for some reason) +cmake --build . --config Release --target install + +# Now rebuild, which installs correctly +cmake --build . --config Release --target install +Write-Host "Done" +cd ../../ + +# FCL won't be able to find octomap unless it is named "octomap" exactly +Rename-Item "C:\Program Files (x86)\octomap-distribution" octomap + + +# ------------------------------------------------------------------------------ +# FCL +Write-Host "Building FCL" +git clone https://github.com/flexible-collision-library/fcl +cd fcl + +# Checkout specific version 0.5.0 (only one compatible with python-fcl) +git checkout 7075caf32ddcd5825ff67303902e3db7664a407a +mkdir build; cd build + +# Fiddle with build file to help fcl find LibCCD and Octomap +# Also tells compiler to dynamically link with C runtime (matches Cython) +$build_script_modification = @" +find_package(ccd QUIET) +find_package(octomap QUIET) +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL$<$:Debug>") +"@ +$filePath = "../CMakeLists.txt" +$lineNumber = 11 +$fileContent = Get-Content $filePath +$fileContent[$lineNumber-1] = $build_script_modification +$fileContent | Set-Content $filePath + +# Now perform actual build +cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 16 2019" .. +cmake --build . --config Release --target install +Write-Host "Done" +cd ../../ + + +# ------------------------------------------------------------------------------ +# Python-FCL +cd ../ + +# Delete compilation directory since it is no longer needed +del -Force -Recurse fcl + +cd ../ + +# Now build Cython extension +python setup.py install +Write-Host "Successfully built python-fcl" + +# At this point, you cannot import fcl directly in Python because it will fail. +# This is because it doesn't have the required DLLs. Let's fix that: +# NOTE: The default SourceFileLoader will find python-fcl's `fcl` package. So +# let's create a tmp directory and use that to force it to find the one in the +# `site-packages`'s directory. +mkdir tmp; cd tmp +$fcl_dir = $(python -c "import pathlib as p, pkgutil as pk; print(p.Path(pk.get_loader('fcl').get_filename()).parent)") +Write-Host "Installed into: $fcl_dir. Copying dependent DLLs" +ls "C:/Program Files (x86)/octomap/bin/*.dll" | cp -destination $fcl_dir +cp "C:/Program Files (x86)/ccd/bin/ccd.dll" $fcl_dir + +# Now delete all of the installed dependencies (after building python-fcl) +Write-Host "Removing build directories for Eigen, LibCCD, FCL, and Octomap" +rmdir -r 'C:\Program Files (x86)\Eigen3' +rmdir -r 'C:\Program Files (x86)\ccd' +rmdir -r 'C:\Program Files (x86)\fcl' +rmdir -r 'C:\Program Files (x86)\octomap' + +Write-Host "All done!" + +# Make sure to return the cwd to wherever it was before the build +popd diff --git a/setup.py b/setup.py index 4dedd51..697fd7d 100644 --- a/setup.py +++ b/setup.py @@ -1,48 +1,69 @@ -import os -import sys -import inspect - +import sys, os +from pathlib import Path from setuptools import Extension, setup +import numpy + + +# Load __version__ +exec((Path(__file__).parent / 'fcl/version.py').read_text()) + +# Libraries needed during compilation of extension +libraries = ['fcl', 'octomap'] + +# Customize build options per platform +supported_platforms = 'darwin', 'linux', 'bsd', 'win32' +current_platform = sys.platform + +if current_platform in supported_platforms: + + # Extra compile args needed per platform + compile_args = [] + + # Windows include and library search paths + if current_platform == 'win32': + # Run build script to download and build libraries. + + include_dirs = [] + library_dirs = [] + include_dir = r'C:\Program Files (x86)\{}\include' + library_dir = r'C:\Program Files (x86)\{}\lib' + deps = 'ccd', 'octomap', 'fcl' + for dep in deps: + include_dirs.append(include_dir.format(dep)) + library_dirs.append(library_dir.format(dep)) -# get current directory of file in case someone -# called setup.py from elsewhere -cwd = os.path.dirname(os.path.abspath( - inspect.getfile(inspect.currentframe()))) - -# load __version__ -exec(open(os.path.join(cwd, - 'fcl/version.py'), 'r').read()) - -platform_supported = False -for prefix in ['darwin', 'linux', 'bsd']: - if prefix in sys.platform: - platform_supported = True - include_dirs = ['/usr/include', - '/usr/local/include', - '/usr/include/eigen3'] - lib_dirs = ['/usr/lib', - '/usr/local/lib'] - - if 'CPATH' in os.environ: - include_dirs += os.environ['CPATH'].split(':') - if 'LD_LIBRARY_PATH' in os.environ: - lib_dirs += os.environ['LD_LIBRARY_PATH'].split(':') - - try: - # get the numpy include path from numpy - import numpy - include_dirs.append(numpy.get_include()) - except: - pass - - break - -if sys.platform == "win32": - platform_supported = False - -if not platform_supported: - raise NotImplementedError(sys.platform) + # Add necessary Windows-specific dependencies + libraries.extend(['octomath', 'ccd', 'vcruntime']) + + # Extra args for MSVC + compile_args.extend(['/std:c++latest', '/MD', '/w']) + + # Unix include and library search paths + else: + include_dirs = [ + '/usr/include', + '/usr/local/include', + '/usr/include/eigen3' + ] + library_dirs = [ + '/usr/lib', + '/usr/local/lib' + ] + + # Extra args for CC + compile_args.append('-std=c++11') + + # Optionally support additional search paths + sep = os.path.pathsep + include_dirs.extend(os.environ.get('CPATH', '').split(sep)) + include_dirs.extend(os.environ.get('LD_LIBRARY_PATH', '').split(sep)) + + # Add Numpy include directories + include_dirs.append(numpy.get_include()) + +else: + raise NotImplementedError(current_platform) setup( name='python-fcl', @@ -52,7 +73,7 @@ url='https://github.com/BerkeleyAutomation/python-fcl', author='Matthew Matl', author_email='mmatl@eecs.berkeley.edu', - license = "BSD", + license = 'BSD', classifiers=[ 'Development Status :: 3 - Alpha', 'License :: OSI Approved :: BSD License', @@ -73,14 +94,15 @@ setup_requires=['cython'], install_requires=['numpy', 'cython'], ext_modules=[Extension( - "fcl.fcl", - ["fcl/fcl.pyx"], - include_dirs = include_dirs, - library_dirs = lib_dirs, - libraries=[ - "fcl","octomap" - ], - language="c++", - extra_compile_args = ["-std=c++11"] + 'fcl.fcl', + ['fcl/fcl.pyx'], + include_dirs=include_dirs, + library_dirs=library_dirs, + libraries=libraries, + language='c++', + extra_compile_args=compile_args )] ) + +# On Windows, DLL dependencies must be copied over to the installation directory + From baf829bb4f5d13e8f8aa0809a1c51e8563292189 Mon Sep 17 00:00:00 2001 From: Pebaz Date: Sat, 16 May 2020 15:02:38 -0400 Subject: [PATCH 2/4] updated documentation for win32 --- README.md | 10 +++- requirements/build_win32.ps1 | 9 ++- setup-win32.py | 110 +++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 setup-win32.py diff --git a/README.md b/README.md index 887647a..cbbe388 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,14 @@ pip3 install python-fcl ### Windows +**Using Prebuilt Wheel** + +```bash +pip install python-fcl-win32 +``` + +**Building From Source** + Building on Windows requires: * Python3 (e.g. Not tested using Python2) @@ -65,7 +73,7 @@ Building on Windows requires: * MSVC (Visual Studio 16 2019) > Since the build script places artifacts in `C:\Program Files (x86)`, it is -necessary to run it using an "Administrator PowerShell" prompt. +***required*** to run it using an "Administrator PowerShell" prompt. ```bash # Run using Administrator PowerShell prompt. WILL FAIL WITHOUT PROPER ACCESS diff --git a/requirements/build_win32.ps1 b/requirements/build_win32.ps1 index a57b3c0..5aa388b 100644 --- a/requirements/build_win32.ps1 +++ b/requirements/build_win32.ps1 @@ -1,4 +1,9 @@ <# +*************************************************************************** +Run using Administrator PowerShell prompt. WILL FAIL WITHOUT PROPER ACCESS +This is because the script places build artifacts in C:\Program Files (x86) +*************************************************************************** + This script builds fcl and it's dependencies for python-fcl on Windows. It downloads, builds, installs, and then deletes: @@ -110,12 +115,14 @@ Write-Host "Successfully built python-fcl" # NOTE: The default SourceFileLoader will find python-fcl's `fcl` package. So # let's create a tmp directory and use that to force it to find the one in the # `site-packages`'s directory. -mkdir tmp; cd tmp +mkdir -Force tmp; cd tmp $fcl_dir = $(python -c "import pathlib as p, pkgutil as pk; print(p.Path(pk.get_loader('fcl').get_filename()).parent)") Write-Host "Installed into: $fcl_dir. Copying dependent DLLs" ls "C:/Program Files (x86)/octomap/bin/*.dll" | cp -destination $fcl_dir cp "C:/Program Files (x86)/ccd/bin/ccd.dll" $fcl_dir +Start-Sleep -s 5 + # Now delete all of the installed dependencies (after building python-fcl) Write-Host "Removing build directories for Eigen, LibCCD, FCL, and Octomap" rmdir -r 'C:\Program Files (x86)\Eigen3' diff --git a/setup-win32.py b/setup-win32.py new file mode 100644 index 0000000..3e8bb42 --- /dev/null +++ b/setup-win32.py @@ -0,0 +1,110 @@ +import sys, os +from pathlib import Path +from setuptools import Extension, setup +import numpy + + +# Load __version__ +exec((Path(__file__).parent / 'fcl/version.py').read_text()) + +# Libraries needed during compilation of extension +libraries = ['fcl', 'octomap'] + +# Customize build options per platform +supported_platforms = 'darwin', 'linux', 'bsd', 'win32' +current_platform = sys.platform + +if current_platform in supported_platforms: + + # Extra compile args needed per platform + compile_args = [] + + # Windows include and library search paths + if current_platform == 'win32': + # Run build script to download and build libraries. + + include_dirs = [] + library_dirs = [] + include_dir = r'C:\Program Files (x86)\{}\include' + library_dir = r'C:\Program Files (x86)\{}\lib' + deps = 'ccd', 'octomap', 'fcl' + + for dep in deps: + include_dirs.append(include_dir.format(dep)) + library_dirs.append(library_dir.format(dep)) + + # Add necessary Windows-specific dependencies + libraries.extend(['octomath', 'ccd', 'vcruntime']) + + # Extra args for MSVC + compile_args.extend(['/std:c++latest', '/MD', '/w']) + + # Unix include and library search paths + else: + include_dirs = [ + '/usr/include', + '/usr/local/include', + '/usr/include/eigen3' + ] + library_dirs = [ + '/usr/lib', + '/usr/local/lib' + ] + + # Extra args for CC + compile_args.append('-std=c++11') + + # Optionally support additional search paths + sep = os.path.pathsep + include_dirs.extend(os.environ.get('CPATH', '').split(sep)) + include_dirs.extend(os.environ.get('LD_LIBRARY_PATH', '').split(sep)) + + # Add Numpy include directories + include_dirs.append(numpy.get_include()) + +else: + raise NotImplementedError(current_platform) + +setup( + name='python-fcl-win32', + version=__version__, + description='Python bindings for the Flexible Collision Library', + long_description='Python bindings for the Flexible Collision Library', + url='https://github.com/BerkeleyAutomation/python-fcl', + author='Matthew Matl', + author_email='mmatl@eecs.berkeley.edu', + license = 'BSD', + classifiers=[ + 'Development Status :: 3 - Alpha', + 'License :: OSI Approved :: BSD License', + 'Operating System :: POSIX :: Linux', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.0', + 'Programming Language :: Python :: 3.1', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + ], + keywords='fcl collision distance', + packages=['fcl'], + setup_requires=['cython'], + install_requires=['numpy', 'cython'], + ext_modules=[Extension( + 'fcl.fcl', + ['fcl/fcl.pyx'], + include_dirs=include_dirs, + library_dirs=library_dirs, + libraries=libraries, + language='c++', + extra_compile_args=compile_args + )] +) + +# On Windows, DLL dependencies must be copied over to the installation directory + From 1018f18518f74d21a508abd859e807d067054bf8 Mon Sep 17 00:00:00 2001 From: Pebaz Date: Sat, 16 May 2020 15:04:09 -0400 Subject: [PATCH 3/4] updated docs --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index cbbe388..891bb65 100644 --- a/README.md +++ b/README.md @@ -57,12 +57,6 @@ pip3 install python-fcl ### Windows -**Using Prebuilt Wheel** - -```bash -pip install python-fcl-win32 -``` - **Building From Source** Building on Windows requires: From 5d89dbef28cf1c06c4f118b65c0368939e194e24 Mon Sep 17 00:00:00 2001 From: Pebaz Date: Sat, 16 May 2020 15:59:43 -0400 Subject: [PATCH 4/4] fixed build script to move dlls into source dir and setup-win32.py will use them correctly --- README.md | 9 +++++++++ requirements/build_win32.ps1 | 19 +++++++------------ setup-win32.py | 2 ++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 891bb65..85b40aa 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,12 @@ pip3 install python-fcl ### Windows +**Using Prebuilt Wheel** + +```bash +pip install python-fcl-win32 +``` + **Building From Source** Building on Windows requires: @@ -79,6 +85,9 @@ cd python-fcl requirements/build_win32.ps1 ``` +Running the above script will download, build, and install FCL and any needed +dependencies. + # Usage Examples ## Objects diff --git a/requirements/build_win32.ps1 b/requirements/build_win32.ps1 index 5aa388b..e244061 100644 --- a/requirements/build_win32.ps1 +++ b/requirements/build_win32.ps1 @@ -106,23 +106,18 @@ del -Force -Recurse fcl cd ../ -# Now build Cython extension -python setup.py install -Write-Host "Successfully built python-fcl" - -# At this point, you cannot import fcl directly in Python because it will fail. -# This is because it doesn't have the required DLLs. Let's fix that: -# NOTE: The default SourceFileLoader will find python-fcl's `fcl` package. So -# let's create a tmp directory and use that to force it to find the one in the -# `site-packages`'s directory. -mkdir -Force tmp; cd tmp -$fcl_dir = $(python -c "import pathlib as p, pkgutil as pk; print(p.Path(pk.get_loader('fcl').get_filename()).parent)") -Write-Host "Installed into: $fcl_dir. Copying dependent DLLs" +$fcl_dir = './fcl' +Write-Host "Copying dependent DLLs" ls "C:/Program Files (x86)/octomap/bin/*.dll" | cp -destination $fcl_dir cp "C:/Program Files (x86)/ccd/bin/ccd.dll" $fcl_dir Start-Sleep -s 5 +# Now build Cython extension +python setup-win32.py install +Write-Host "Successfully built python-fcl" + + # Now delete all of the installed dependencies (after building python-fcl) Write-Host "Removing build directories for Eigen, LibCCD, FCL, and Octomap" rmdir -r 'C:\Program Files (x86)\Eigen3' diff --git a/setup-win32.py b/setup-win32.py index 3e8bb42..93f3061 100644 --- a/setup-win32.py +++ b/setup-win32.py @@ -95,6 +95,8 @@ packages=['fcl'], setup_requires=['cython'], install_requires=['numpy', 'cython'], + package_data={'' : ['*.dll']}, + include_package_data=True, ext_modules=[Extension( 'fcl.fcl', ['fcl/fcl.pyx'],