Skip to content

Commit 99d1127

Browse files
committed
Merge branch 'master' into add_MessageHandler
2 parents a9ffee5 + 6d1bd9f commit 99d1127

36 files changed

+523
-80
lines changed

.github/workflows/macos.yml

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
name: CI
2+
3+
on: pull_request
4+
5+
jobs:
6+
build:
7+
name: Building on ${{ matrix.os }}
8+
runs-on: ${{ matrix.os }}
9+
strategy:
10+
matrix:
11+
os: [macos-10.15]
12+
env:
13+
TOKEN: ${{ secrets.SOFA_REPO_READ_TOKEN }}
14+
SOFA_ROOT: /opt/sofa
15+
16+
steps:
17+
- name: Checkout source code
18+
uses: actions/checkout@v2
19+
20+
- name: Set up Python 3.7
21+
uses: actions/setup-python@v2
22+
with:
23+
python-version: '3.7'
24+
25+
- name: Install requirements
26+
run: |
27+
brew install ccache ninja boost eigen pybind11
28+
python3 -m pip install numpy
29+
30+
- name: Get SOFA nightly build link
31+
id: sofa_nightly_link
32+
shell: python
33+
run: |
34+
import urllib.request, json, sys, re
35+
url = 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts'
36+
req = urllib.request.Request(url)
37+
req.add_header('authorization', 'Bearer ${{ secrets.GITHUB_TOKEN }}')
38+
r = urllib.request.urlopen(req).read()
39+
artifacts = json.loads(r.decode('utf-8'))['artifacts']
40+
os_artifacts = filter(lambda a:re.search('${{ matrix.os }}', a['name'], re.I), artifacts)
41+
last_artifact_url = sorted(os_artifacts, reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url']
42+
print(f"::set-output name=link::{last_artifact_url}")
43+
44+
- name: Cache SOFA
45+
uses: actions/cache@v2
46+
id: sofa_cache
47+
with:
48+
path: /opt/sofa
49+
key: ${{ steps.sofa_nightly_link.outputs.link }}
50+
51+
- name: Download SOFA nightly build
52+
if: steps.sofa_cache.outputs.cache-hit != 'true'
53+
run: |
54+
curl --output sofa.zip \
55+
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
56+
-u jnbrunet:$TOKEN -L -o sofa.zip / \
57+
${{ steps.sofa_nightly_link.outputs.link }}
58+
59+
- name: Install SOFA nightly build
60+
if: steps.sofa_cache.outputs.cache-hit != 'true'
61+
run: sudo unzip sofa.zip -d $SOFA_ROOT
62+
63+
- name: Get Time
64+
id: time
65+
uses: nanzm/[email protected]
66+
with:
67+
timeZone: 8
68+
format: 'YYYY-MM-DD-HH-mm-ss'
69+
70+
- name: ccache cache files
71+
uses: actions/cache@v2
72+
with:
73+
path: .ccache
74+
key: ${{ matrix.os }}-ccache-${{ steps.time.outputs.time }}
75+
restore-keys: |
76+
${{ matrix.os }}-ccache-
77+
78+
- name: Build
79+
env:
80+
CCACHE_COMPRESS: true
81+
CCACHE_COMPRESSLEVEL: 6
82+
CCACHE_MAXSIZE: "500M"
83+
run:
84+
export CCACHE_BASEDIR=$GITHUB_WORKSPACE &&
85+
export CCACHE_DIR=$GITHUB_WORKSPACE/.ccache &&
86+
ccache -z &&
87+
cmake
88+
-GNinja
89+
-DCMAKE_C_COMPILER_LAUNCHER=ccache
90+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
91+
-DCMAKE_PREFIX_PATH=$SOFA_ROOT/lib/cmake
92+
.
93+
&& ninja && ninja install
94+
&& echo ${CCACHE_BASEDIR}
95+
&& ccache -s
96+
97+
- name: Archive production
98+
uses: actions/upload-artifact@v2
99+
with:
100+
name: sp3-${{ matrix.os }}
101+
path: install
102+
103+
tests:
104+
name: Testing on ${{ matrix.os }}
105+
needs: [build]
106+
runs-on: ${{ matrix.os }}
107+
strategy:
108+
matrix:
109+
os: [macos-10.15]
110+
env:
111+
TOKEN: ${{ secrets.SOFA_REPO_READ_TOKEN }}
112+
SOFA_ROOT: /opt/sofa
113+
114+
steps:
115+
116+
- name: Set up Python 3.7
117+
uses: actions/setup-python@v2
118+
with:
119+
python-version: '3.7'
120+
121+
- name: Install requirements
122+
run: |
123+
brew install boost
124+
python3 -m pip install numpy
125+
126+
127+
128+
- name: Get SOFA nightly build link
129+
id: sofa_nightly_link
130+
shell: python
131+
run: |
132+
import urllib.request, json, sys, re
133+
url = 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts'
134+
req = urllib.request.Request(url)
135+
req.add_header('authorization', 'Bearer ${{ secrets.GITHUB_TOKEN }}')
136+
r = urllib.request.urlopen(req).read()
137+
artifacts = json.loads(r.decode('utf-8'))['artifacts']
138+
os_artifacts = filter(lambda a:re.search('${{ matrix.os }}', a['name'], re.I), artifacts)
139+
last_artifact_url = sorted(os_artifacts, reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url']
140+
print(f"::set-output name=link::{last_artifact_url}")
141+
142+
- name: Cache SOFA
143+
uses: actions/cache@v2
144+
id: sofa_cache
145+
with:
146+
path: /opt/sofa
147+
key: ${{ steps.sofa_nightly_link.outputs.link }}
148+
149+
- name: Download SOFA nightly build
150+
if: steps.sofa_cache.outputs.cache-hit != 'true'
151+
run: |
152+
curl --output sofa.zip \
153+
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
154+
-u jnbrunet:$TOKEN -L -o sofa.zip / \
155+
${{ steps.sofa_nightly_link.outputs.link }}
156+
157+
- name: Install SOFA nightly build
158+
if: steps.sofa_cache.outputs.cache-hit != 'true'
159+
run: sudo unzip sofa.zip -d $SOFA_ROOT && rm sofa.zip
160+
161+
- name: Install SP3
162+
uses: actions/download-artifact@v2
163+
with:
164+
name: sp3-${{ matrix.os }}
165+
path: SofaPython3
166+
167+
- name: Binding.Sofa.Tests
168+
if: ${{ always() }}
169+
run: |
170+
export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$SOFA_ROOT/plugins/SofaValidation/lib:$SOFA_ROOT/plugins/SofaNonUniformFem/lib:$SOFA_ROOT/plugins/SofaDenseSolver/lib:$LD_LIBRARY_PATH
171+
export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/site-packages:$PYTHONPATH
172+
export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins/SofaSparseSolver/lib
173+
chmod +x SofaPython3/bin/Bindings.Sofa.Tests
174+
./SofaPython3/bin/Bindings.Sofa.Tests
175+
- name: Bindings.SofaRuntime.Tests
176+
if: ${{ always() }}
177+
run: |
178+
export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$SOFA_ROOT/plugins/SofaValidation/lib:$SOFA_ROOT/plugins/SofaNonUniformFem/lib:$SOFA_ROOT/plugins/SofaDenseSolver/lib:$LD_LIBRARY_PATH
179+
export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/site-packages:$PYTHONPATH
180+
export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins/SofaSparseSolver/lib
181+
chmod +x SofaPython3/bin/Bindings.SofaRuntime.Tests
182+
./SofaPython3/bin/Bindings.SofaRuntime.Tests
183+
- name: Bindings.SofaTypes.Tests
184+
if: ${{ always() }}
185+
run: |
186+
export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$SOFA_ROOT/plugins/SofaValidation/lib:$SOFA_ROOT/plugins/SofaNonUniformFem/lib:$SOFA_ROOT/plugins/SofaDenseSolver/lib:$LD_LIBRARY_PATH
187+
export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/site-packages:$PYTHONPATH
188+
export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins/SofaSparseSolver/lib
189+
chmod +x SofaPython3/bin/Bindings.SofaTypes.Tests
190+
./SofaPython3/bin/Bindings.SofaTypes.Tests
191+

.github/workflows/ubuntu.yml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,17 @@ jobs:
4444

4545
- name: Get SOFA nightly build link
4646
id: sofa_nightly_link
47-
run: echo "::set-output name=link::$(curl -s 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts' | python3 -c "import sys,json,re;print(sorted(filter(lambda a:re.search('${{ matrix.os }}', a['name'], re.I),json.load(sys.stdin)['artifacts']), reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url'])")"
48-
shell: bash
47+
shell: python
48+
run: |
49+
import urllib.request, json, sys, re
50+
url = 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts'
51+
req = urllib.request.Request(url)
52+
req.add_header('authorization', 'Bearer ${{ secrets.GITHUB_TOKEN }}')
53+
r = urllib.request.urlopen(req).read()
54+
artifacts = json.loads(r.decode('utf-8'))['artifacts']
55+
os_artifacts = filter(lambda a:re.search('${{ matrix.os }}', a['name'], re.I), artifacts)
56+
last_artifact_url = sorted(os_artifacts, reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url']
57+
print(f"::set-output name=link::{last_artifact_url}")
4958
5059
- name: Cache SOFA
5160
uses: actions/cache@v2
@@ -56,8 +65,10 @@ jobs:
5665

5766
- name: Download SOFA nightly build
5867
if: steps.sofa_cache.outputs.cache-hit != 'true'
59-
run: curl --output sofa.zip
60-
-u jnbrunet:$TOKEN -L -o sofa.zip /
68+
run: |
69+
curl --output sofa.zip \
70+
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
71+
-u jnbrunet:$TOKEN -L -o sofa.zip / \
6172
${{ steps.sofa_nightly_link.outputs.link }}
6273
6374
- name: Install SOFA nightly build
@@ -125,10 +136,20 @@ jobs:
125136
- name: Install requirements
126137
run: |
127138
python3 -m pip install numpy
139+
128140
- name: Get SOFA nightly build link
129141
id: sofa_nightly_link
130-
run: echo "::set-output name=link::$(curl -s 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts' | python3 -c "import sys,json,re;print(sorted(filter(lambda a:re.search('ubuntu-18\.04', a['name'], re.I),json.load(sys.stdin)['artifacts']), reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url'])")"
131-
shell: bash
142+
shell: python
143+
run: |
144+
import urllib.request, json, sys, re
145+
url = 'https://api.github.com/repos/jnbrunet/sofa/actions/artifacts'
146+
req = urllib.request.Request(url)
147+
req.add_header('authorization', 'Bearer ${{ secrets.GITHUB_TOKEN }}')
148+
r = urllib.request.urlopen(req).read()
149+
artifacts = json.loads(r.decode('utf-8'))['artifacts']
150+
os_artifacts = filter(lambda a:re.search('${{ matrix.os }}', a['name'], re.I), artifacts)
151+
last_artifact_url = sorted(os_artifacts, reverse=False, key=lambda a:a['created_at'])[-1]['archive_download_url']
152+
print(f"::set-output name=link::{last_artifact_url}")
132153
133154
- name: Cache SOFA
134155
uses: actions/cache@v2
@@ -139,8 +160,10 @@ jobs:
139160

140161
- name: Download SOFA nightly build
141162
if: steps.sofa_cache.outputs.cache-hit != 'true'
142-
run: curl --output sofa.zip
143-
-u jnbrunet:$TOKEN -L -o sofa.zip /
163+
run: |
164+
curl --output sofa.zip \
165+
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
166+
-u jnbrunet:$TOKEN -L -o sofa.zip / \
144167
${{ steps.sofa_nightly_link.outputs.link }}
145168
146169
- name: Install SOFA nightly build

CMake/SofaPython3Tools.cmake

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,57 @@ function(SP3_add_python_module)
141141
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${DESTINATION}"
142142
)
143143

144-
# Note: This should be disabled if/when we will want to create packages
144+
# Compute the installation RPATHs from the target's SP3 dependencies since they are not installed in a same directory
145+
# and are not automatically added from the cmake option INSTALL_RPATH_USE_LINK_PATH.
146+
# 1. Get all dependencies that are
147+
# (a) a target in this project, and
148+
# (b) built in CMAKE_LIBRARY_OUTPUT_DIRECTORY
149+
# 2. Here we are sure that the dependency is a SP3 target and not an imported target from an external dependency.
150+
# We compute its path relative to this target output file
151+
# Ex: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/site-packages/Sofa --> $ORIGIN/../Sofa
152+
# 3. Add the relative path computed in 2 to the list of RPATHS
153+
set(${A_TARGET}_DEPENDECIES_RPATH "${CMAKE_INSTALL_PREFIX}/${LIBRARY_OUTPUT_DIRECTORY}")
154+
foreach(DEPENDENCY ${A_DEPENDS})
155+
if (TARGET ${DEPENDENCY})
156+
get_target_property(DEPENDENCY_LIBRARY_OUTPUT_DIRECTORY "${DEPENDENCY}" LIBRARY_OUTPUT_DIRECTORY)
157+
if (DEPENDENCY_LIBRARY_OUTPUT_DIRECTORY)
158+
file(RELATIVE_PATH dependency_path_from_packages "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}" "${DEPENDENCY_LIBRARY_OUTPUT_DIRECTORY}")
159+
if (NOT "${dependency_path_from_packages}" STREQUAL "" AND NOT "${dependency_path_from_packages}" STREQUAL "../")
160+
list(APPEND ${A_TARGET}_DEPENDECIES_RPATH "$ORIGIN/../${dependency_path_from_packages}")
161+
endif()
162+
endif()
163+
endif()
164+
endforeach()
165+
166+
if (APPLE)
167+
# In MacOS, the target dependency name is RPATH/site-packages/PackageName, so we need to add
168+
# an RPATH to the directory that contains "site-paclages"
169+
list(APPEND ${A_TARGET}_DEPENDECIES_RPATH "$ORIGIN/../..")
170+
endif()
171+
145172
set_target_properties(
146173
${A_TARGET}
147174
PROPERTIES
175+
176+
# This option only works for target that are not defined by the SP3 project
177+
# see https://stackoverflow.com/a/30400628 for details
148178
INSTALL_RPATH_USE_LINK_PATH TRUE
149-
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIBRARY_OUTPUT_DIRECTORY}"
179+
180+
# This will set the remaining RPATHs from our Bindings targets dependencies (install/lib/site-packages/*)
181+
INSTALL_RPATH "${${A_TARGET}_DEPENDECIES_RPATH}"
182+
183+
# Don't use the installation RPATH for built files
184+
BUILD_WITH_INSTALL_RPATH FALSE
150185
)
151186

187+
if (APPLE)
188+
set_target_properties(
189+
${PROJECT_NAME}
190+
PROPERTIES
191+
INSTALL_NAME_DIR "@rpath/${SP3_PYTHON_PACKAGES_DIRECTORY}/${DESTINATION}"
192+
)
193+
endif()
194+
152195
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
153196
set_target_properties(
154197
${A_TARGET}

CMakeLists.txt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ find_package(pybind11 2.3 CONFIG QUIET REQUIRED)
7272

7373
set(SP3_PYTHON_PACKAGES_DIRECTORY
7474
"site-packages"
75-
CACHE PATH
76-
"Path to the directory where the python packages will be built and installed. (default to site-packages)"
75+
CACHE STRING
76+
"Directory name where the python packages will be built and installed.
77+
This will be prepend to LIBRARY_OUTPUT_DIRECTORY (default to site-packages)"
7778
)
7879

7980
# Get the Python's user site packages directory, or FASLE if not found
@@ -98,6 +99,22 @@ message("-- Python user site: ${PYTHON_USER_SITE}")
9899
message("-- pybind11 version: ${pybind11_VERSION}")
99100
message("-- pybind11 config: ${pybind11_CONFIG}")
100101

102+
# When using python3 from XCode on MacOS, the RPath is wrongly set to XCode frameworks directory:
103+
# LC_LOAD_DYLIB @rpath/Python3.framework/Versions/3.7/Python3
104+
# LC_RPATH /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/lib
105+
# Hence LC_RPATH/LC_LOAD_DYLIB does not exists.
106+
# Until this is fixed (not sure if it comes from pybind11, cmake or XCode), we can add another path to RPATH:
107+
# LC_LOAD_DYLIB @rpath/Python3.framework/Versions/3.7/Python3
108+
# LC_RPATH /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/lib
109+
# /Applications/Xcode.app/Contents/Developer/Library/Frameworks <----- ADDED
110+
# And now one combination of LC_RPATH/LC_LOAD_DYLIB will be valid.
111+
# This should't change anything for those that use other python libs than XCode (homebrew for example) since the
112+
# LC_LOAD_DYLIB from XCode is quite unique.
113+
if (APPLE)
114+
set(CMAKE_INSTALL_RPATH "/Applications/Xcode.app/Contents/Developer/Library/Frameworks")
115+
set(CMAKE_BUILD_RPATH "/Applications/Xcode.app/Contents/Developer/Library/Frameworks")
116+
endif()
117+
101118
add_subdirectory(Plugin)
102119
add_subdirectory(bindings)
103120
add_subdirectory(examples)

0 commit comments

Comments
 (0)