From 7684ed26c4bab9da2e32330590ea43dc85d5fac2 Mon Sep 17 00:00:00 2001
From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be>
Date: Mon, 5 Jul 2021 10:37:08 +0200
Subject: [PATCH] tentative binary wheels

---
 .gitlab-ci.yml                  | 78 +++++++++++++++++++++++++++++++++
 CMakeLists.txt                  |  4 +-
 api/GenApi.py                   | 16 ++++---
 api/gmsh.py                     | 16 ++++---
 utils/pypi/gmsh/setup-whl.py.in | 77 ++++++++++++++++++++++++++++++++
 5 files changed, 180 insertions(+), 11 deletions(-)
 create mode 100644 utils/pypi/gmsh/setup-whl.py.in

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 30c639f86e..541ec529c7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -385,3 +385,81 @@ pypi_official_release:
     - docker
   only:
     - /^gmsh_.*$/
+
+
+# 
+# JON WIP
+#
+
+linux64-sdk_wheel_tmp:
+  image: onelab/debian.stretch.64bit
+  variables:
+    EXTRA_OPTION: "-DENABLE_BUILD_DYNAMIC=1 -DINSTALL_SDK_README=1 -DCMAKE_EXE_LINKER_FLAGS=-static-libstdc++"
+  script:
+    - mkdir build
+    - cd build
+    - cmake -DGMSH_HOST=gmsh.info -DENABLE_OPENMP=1 -DENABLE_PETSC=1 -DPETSC_ARCH=real_mumps_seq -DPETSC_DIR=/petsc-3.14.4 ${EXTRA_OPTION} ..
+    - make package -j 8
+  artifacts:
+    paths:
+      - build/_CPack_Packages/Linux/TGZ/gmsh-git-Linux64-sdk/
+      - build/setup-whl.py
+    expire_in: 1day
+  tags:
+    - linux64
+    - docker
+
+windows64-sdk_wheel_tmp:
+  variables:
+    EXTRA_OPTION: "-DENABLE_OS_SPECIFIC_INSTALL=0 -DENABLE_BUILD_DYNAMIC=1 -DINSTALL_SDK_README=1"
+  script:
+    - md build
+    - cd build
+    - c:\cygwin64\bin\bash -c "/usr/bin/cmake -DGMSH_HOST=gmsh.info -DENABLE_OPENMP=1 -DCMAKE_PREFIX_PATH='/usr/local;/usr/x86_64-w64-mingw32/sys-root/mingw' -DCMAKE_C_COMPILER=/usr/bin/x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER=/usr/bin/x86_64-w64-mingw32-g++.exe -DCMAKE_Fortran_COMPILER=/usr/bin/x86_64-w64-mingw32-gfortran.exe -DCMAKE_RC_COMPILER=/usr/bin/x86_64-w64-mingw32-windres.exe -DENABLE_OS_SPECIFIC_INSTALL=1 -DENABLE_PETSC=1 -DPETSC_ARCH=real_mumps_seq -DPETSC_DIR=/home/geuzaine/src/petsc ${EXTRA_OPTION} .."
+    - c:\cygwin64\bin\bash -c "/usr/bin/make package -j 4"
+  artifacts:
+    paths:
+      - build/_CPack_Packages/CYGWIN/ZIP/gmsh-git-Windows64-sdk/
+    expire_in: 1day
+  tags:
+    - windows64
+
+macos64-sdk_wheel_tmp:
+  variables:
+    EXTRA_OPTION: "-DENABLE_OS_SPECIFIC_INSTALL=0 -DENABLE_BUILD_DYNAMIC=1 -DINSTALL_SDK_README=1"
+  script:
+    - mkdir build
+    - cd build
+    - /usr/local/bin/cmake -DGMSH_HOST=gmsh.info -DENABLE_OPENMP=1 -DENABLE_CAIRO=0 -DENABLE_OS_SPECIFIC_INSTALL=1 -DENABLE_PETSC=1 -DPETSC_ARCH=real_mumps_seq -DPETSC_DIR=/Users/geuzaine/src/petsc ${EXTRA_OPTION} ..
+    - make package -j 4
+  tags:
+    - macos64
+  artifacts:
+    paths:
+      - build/_CPack_Packages/Darwin/TGZ/gmsh-git-MacOSX-sdk/
+    expire_in: 1day
+
+python_wheels: 
+  stage: .post
+  image : immc/seamsh-build:v0.9
+  dependencies:
+    - linux64-sdk_wheel_tmp
+    - windows64-sdk_wheel_tmp
+    - macos64-sdk_wheel_tmp
+  before_script:
+    - echo "[distutils]" > ~/.pypirc
+    - echo "index-servers = testpypi" >> ~/.pypirc
+    - echo "[testpypi]" >> ~/.pypirc
+    - echo "username = __token__" >> ~/.pypirc
+    - echo "password = $TEST_PYPI_TOKEN" >> ~/.pypirc
+  script:
+    - cd build
+    - GMSH_SETUP_DIR=../utils/pypi/gmsh GMSH_SDK_DIR=_CPack_Packages/Linux/TGZ/gmsh-git-Linux64-sdk/ python3 setup-whl.py build bdist_wheel --plat-name manylinux1_x86_64 --universal
+    - GMSH_SETUP_DIR=../utils/pypi/gmsh GMSH_SDK_DIR=_CPack_Packages/CYGWIN/ZIP/gmsh-git-Windows64-sdk/ python3 setup-whl.py build bdist_wheel --plat-name win_amd64 --universal
+    - cp -R _CPack_Packages/Darwin _CPack_Packages/Darwin2
+    - GMSH_SETUP_DIR=../utils/pypi/gmsh GMSH_SDK_DIR=_CPack_Packages/Darwin2/TGZ/gmsh-git-MacOSX-sdk/ python3 setup-whl.py build bdist_wheel --plat-name macosx_10_9_x86_64 --universal
+    - twine upload --repository testpypi dist/*
+  tags:
+    - linux64
+    - docker
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd06349437..b258697718 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1601,7 +1601,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/texinfo/version.texi.in
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/pypi/gmsh/setup.py.in
                ${CMAKE_CURRENT_SOURCE_DIR}/utils/pypi/gmsh/setup.py)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/pypi/gmsh-dev/setup.py.in
-               ${CMAKE_CURRENT_SOURCE_DIR}/utils/pypi/gmsh-dev/setup.py)
+               ${CMAKE_CURRENT_BINARY_DIR}/utils/pypi/gmsh-dev/setup.py)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/pypi/gmsh/setup-whl.py.in
+               ${CMAKE_CURRENT_BINARY_DIR}/setup-whl.py)
 
 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.txt ${GMSH_SHORT_VERSION})
 
diff --git a/api/GenApi.py b/api/GenApi.py
index b867fab010..c9bc4182b6 100644
--- a/api/GenApi.py
+++ b/api/GenApi.py
@@ -1051,16 +1051,22 @@ from math import pi
 __version__ = {6}_API_VERSION
 
 oldsig = signal.signal(signal.SIGINT, signal.SIG_DFL)
-libdir = os.path.dirname(os.path.realpath(__file__))
+moduledir = os.path.dirname(os.path.realpath(__file__))
 if platform.system() == "Windows":
-    libpath = os.path.join(libdir, "{7}-{3}.{4}.dll")
+    libname = "{7}-{3}.{4}.dll"
+    libdir = os.path.dirname(moduledir)
 elif platform.system() == "Darwin":
-    libpath = os.path.join(libdir, "lib{7}.dylib")
+    libname = "lib{7}.{3}.{4}.dylib"
+    libdir = os.path.dirname(os.path.dirname(moduledir))
 else:
-    libpath = os.path.join(libdir, "lib{7}.so")
+    libname = "lib{7}.so.{3}.{4}"
+    libdir = os.path.dirname(os.path.dirname(moduledir))
 
+libpath = os.path.join(libdir, libname)
 if not os.path.exists(libpath):
-    libpath = find_library("{7}")
+    libpath = os.path.join(moduledir, libname)
+    if not os.path.exists(libpath):
+        libpath = find_library("{7}")
 
 lib = CDLL(libpath)
 
diff --git a/api/gmsh.py b/api/gmsh.py
index 9f504c2480..3ee8320b8b 100644
--- a/api/gmsh.py
+++ b/api/gmsh.py
@@ -26,16 +26,22 @@ GMSH_API_VERSION_PATCH = 0
 __version__ = GMSH_API_VERSION
 
 oldsig = signal.signal(signal.SIGINT, signal.SIG_DFL)
-libdir = os.path.dirname(os.path.realpath(__file__))
+moduledir = os.path.dirname(os.path.realpath(__file__))
 if platform.system() == "Windows":
-    libpath = os.path.join(libdir, "gmsh-4.9.dll")
+    libname = "gmsh-4.9.dll"
+    libdir = os.path.dirname(moduledir)
 elif platform.system() == "Darwin":
-    libpath = os.path.join(libdir, "libgmsh.dylib")
+    libname = "libgmsh.4.9.dylib"
+    libdir = os.path.dirname(os.path.dirname(moduledir))
 else:
-    libpath = os.path.join(libdir, "libgmsh.so")
+    libname = "libgmsh.so.4.9"
+    libdir = os.path.dirname(os.path.dirname(moduledir))
 
+libpath = os.path.join(libdir, libname)
 if not os.path.exists(libpath):
-    libpath = find_library("gmsh")
+    libpath = os.path.join(moduledir, libname)
+    if not os.path.exists(libpath):
+        libpath = find_library("gmsh")
 
 lib = CDLL(libpath)
 
diff --git a/utils/pypi/gmsh/setup-whl.py.in b/utils/pypi/gmsh/setup-whl.py.in
new file mode 100644
index 0000000000..3506b5aed5
--- /dev/null
+++ b/utils/pypi/gmsh/setup-whl.py.in
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+# Gmsh - Copyright (C) 1997-2020 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
+
+import os
+import setuptools
+import sys
+
+setupdir = os.environ["GMSH_SETUP_DIR"]
+sdkdir = os.environ["GMSH_SDK_DIR"]
+
+version = '${GMSH_MAJOR_VERSION}.${GMSH_MINOR_VERSION}.${GMSH_PATCH_VERSION}'
+iversion = version + '-1'  # installer version (+ '-1' will create '.post1')
+
+
+def gen_install_list(subdir):
+    for dirpath, dirs, files in os.walk(subdir):
+        if len(files) != 0:
+            filepaths = [os.path.join(dirpath, f) for f in files]
+            relpath = os.path.relpath(dirpath, sdkdir)
+            data_files.append((relpath, filepaths))
+libversion = ".".join(version.split(".")[:2])
+
+if os.path.isfile(sdkdir+'/lib/gmsh-'+libversion+'.dll'):
+    scripts = [os.path.join(setupdir,'gmsh'),
+               os.path.join(setupdir,'gmsh.bat')]
+    libs = ['gmsh.lib','gmsh-'+libversion+'.dll','gmsh.jl']
+    exe = 'gmsh.exe'
+elif os.path.isfile(sdkdir+'/lib/libgmsh.so.'+libversion):
+    scripts = [os.path.join(setupdir,'gmsh')]
+    libs = ['libgmsh.so.'+libversion,'gmsh.jl']
+    exe  = 'gmsh'
+elif os.path.isfile(sdkdir+'/lib/libgmsh.'+libversion+'.dylib'):
+    scripts = [os.path.join(setupdir,'gmsh')]
+    libs = ['libgmsh.'+libversion+'.dylib']
+    exe  = 'gmsh'
+else :
+    print("library not found")
+    exit(1)
+
+data_files = [('lib', list(os.path.join(sdkdir+'/lib', lib) for lib in libs) +
+                       [os.path.join(sdkdir+'/bin', exe)])]
+gen_install_list(sdkdir+'/share')
+gen_install_list(sdkdir+'/include')
+
+setuptools.setup(
+    name='gmsh',
+    version=iversion,
+    description='Gmsh app and SDK installer. Gmsh is a three-dimensional '
+                'finite element mesh generator with built-in pre- and '
+                'post-processing facilities.',
+    long_description=open(os.path.join(setupdir, 'README.rst'), 'r').read(),
+    long_description_content_type='text/x-rst',
+    maintainer='Christophe Geuzaine',
+    maintainer_email='cgeuzaine@uliege.be',
+    keywords=['fem', 'mesh', 'finite element method', 'cad'],
+    url='https://gmsh.info',
+    license='GPL-2',
+    platforms='Posix, Windows',
+    classifiers=['Development Status :: 5 - Production/Stable',
+                 'Intended Audience :: Education',
+                 'Intended Audience :: Science/Research',
+                 'License :: OSI Approved :: '
+                 'GNU General Public License v2 or later (GPLv2+)',
+                 'Operating System :: POSIX :: Linux',
+                 'Operating System :: Microsoft :: Windows',
+                 'Operating System :: MacOS :: MacOS X',
+                 'Programming Language :: C',
+                 'Programming Language :: C++',
+                 'Programming Language :: Python',
+                 'Topic :: Scientific/Engineering'],
+    scripts=scripts,
+    packages = [''],
+    package_dir={'': os.path.join(sdkdir+'/lib')},
+    data_files=data_files)
-- 
GitLab