[Python] Create Python bindings when Python package has different name to dune module
I'm trying and struggling currently to create working python bindings for python bindings, where the pypi package should have a different name to the dune module and to the actual python package. I'm using all 2.9 branches
I.e. my dune-module is called "ikarus" which is not available at pypi. Thus, as a workaround I want to name the pypi package pyikarus
.
Thus I want the behaviour to be pip install pyikarus
and in the python code import ikarus
and my cpp folder structure should also be with ikarus
.
I investigated, and my current setup is:
In the top-level setup.py
I have
...
metadata["name"] = "pyikarus"
setup(**metadata)
In python/ikarus/setup.py.in
I have
REQUIRED_PACKAGES = '${RequiredPythonModules}'.replace(';',' ').split(' ')
setup(
name="pyikarus",
description="${ProjectDescription}",
version="${ProjectVersionString}",
author="${ProjectAuthor}",
author_email="${ProjectMaintainerEmail}",
packages=find_packages(exclude=["docs/*"]),
zip_safe=0,
package_data={"": ["*.so"], "pyikarus": ["data/*.cmake"]},
install_requires=REQUIRED_PACKAGES,
include_package_data=True,
)
and in python/ikarus/CMakeLists.txt
add_subdirectory(ikarus)
set(CXX_MAX_STANDARD 20)
set(PYPI_PACKAGE_NAME "pyikarus")
dune_python_configure_bindings(
PATH
"."
PACKAGENAME
${PYPI_PACKAGE_NAME}
CMAKE_METADATA_FLAGS
DUNE_OPTS_FILE
CXX_MAX_STANDARD
)
if(POLICY CMP0087)
cmake_policy(SET CMP0087 NEW)
endif()
There are several points where I have to state ikarus
or pyikarus
. Brute forcing some variants of these options always returns errors.
Thus, if I install my uploaded package from pypi and try to compile my code with dune-py
, I get two different error messages.
If I pass to dune_python_configure_bindings
above the name pyikarus
, I get errors like
pyikarus error message
---------------------------------------------------------------------------
CompileError Traceback (most recent call last)
Cell In[35], line 1
----> 1 svk = iks.StVenantKirchhoff(emodul=1000,nu=0.3)
3 svkPS = svk.asPlainStress()
File /dune/dune-common/build-cmake/dune-env/lib/python3.10/site-packages/ikarus/materials.py:33, in materialConstructorDecorator..wrapper(emodul, nu)
31 includes += ["ikarus/python/finiteElements/materials/material.hh"]
32 moduleName = func.__name__+"_" + hashIt(element_type)
---> 33 module = generator.load(
34 includes=includes,
35 typeName=element_type,
36 moduleName=moduleName
37 )
39 # dispatcher = { 'NeoHooke' : NeoHooke, 'StVenantKirchhoff' : StVenantKirchhoff}
42 return eval("module."+func.__name__+"(emodul,nu)")
File /dune/dune-common/build-cmake/python/dune/generator/generator.py:172, in SimpleGenerator.load(self, includes, typeName, moduleName, extraCMake, defines, preamble, postscript, options, bufferProtocol, dynamicAttr, baseClasses, holder, *args)
168 for nr, (tn, a, o, b, d, bc, h) in enumerate( zip(typeName, args, options, bufferProtocol, dynamicAttr, baseClasses, holder) ):
169 source += self.main(nr, includes, tn, *a, options=o,
170 bufferProtocol=b, dynamicAttr=d,
171 baseClasses=bc, holder=h)
--> 172 return self.post(moduleName, source, postscript, extraCMake)
File /dune/dune-common/build-cmake/python/dune/generator/generator.py:124, in SimpleGenerator.post(self, moduleName, source, postscript, extraCMake)
122 # make sure to reload the builder here in case it got updated
123 from . import builder
--> 124 module = builder.load(moduleName, source, self.typeName[0], extraCMake)
126 return module
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:382, in Builder.load(self, moduleName, source, pythonName, extraCMake)
380 module = sys.modules.get("dune.generated." + moduleName)
381 if module is None:
--> 382 self._buildModule( moduleName, source, pythonName, extraCMake )
384 ## TODO remove barrier here
385 comm.barrier()
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:732, in MakefileBuilder._buildModule(self, moduleName, source, pythonName, extraCMake)
729 # check return code
730 if exit_code > 0:
731 # retrieve stderr output
--> 732 raise CompileError(buffer_to_str(stderr))
CompileError: /dune/dune-common/build-cmake/dune-env/.cache/dune-py/python/dune/generated/StVenantKirchhoff_de7f96cf2f383220c197a4a670079062.cc:10:10: fatal error: ikarus/finiteElements/mechanics/materials.hh: No such file or directory
10 | #include
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
If I pass to dune_python_configure_bindings
above the name ikarus
I get errors like
pyikarus error message
---------------------------------------------------------------------------
CompileError Traceback (most recent call last)
Cell In[4], line 1
----> 1 svk = iks.StVenantKirchhoff(emodul=1000,nu=0.3)
3 svkPS = svk.asPlainStress()
File /dune/dune-common/build-cmake/dune-env/lib/python3.10/site-packages/ikarus/materials.py:33, in materialConstructorDecorator..wrapper(emodul, nu)
31 includes += ["ikarus/python/finiteElements/materials/material.hh"]
32 moduleName = func.__name__+"_" + hashIt(element_type)
---> 33 module = generator.load(
34 includes=includes,
35 typeName=element_type,
36 moduleName=moduleName
37 )
39 # dispatcher = { 'NeoHooke' : NeoHooke, 'StVenantKirchhoff' : StVenantKirchhoff}
42 return eval("module."+func.__name__+"(emodul,nu)")
File /dune/dune-common/build-cmake/python/dune/generator/generator.py:172, in SimpleGenerator.load(self, includes, typeName, moduleName, extraCMake, defines, preamble, postscript, options, bufferProtocol, dynamicAttr, baseClasses, holder, *args)
168 for nr, (tn, a, o, b, d, bc, h) in enumerate( zip(typeName, args, options, bufferProtocol, dynamicAttr, baseClasses, holder) ):
169 source += self.main(nr, includes, tn, *a, options=o,
170 bufferProtocol=b, dynamicAttr=d,
171 baseClasses=bc, holder=h)
--> 172 return self.post(moduleName, source, postscript, extraCMake)
File /dune/dune-common/build-cmake/python/dune/generator/generator.py:124, in SimpleGenerator.post(self, moduleName, source, postscript, extraCMake)
122 # make sure to reload the builder here in case it got updated
123 from . import builder
--> 124 module = builder.load(moduleName, source, self.typeName[0], extraCMake)
126 return module
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:374, in Builder.load(self, moduleName, source, pythonName, extraCMake)
370 def load(self, moduleName, source, pythonName, extraCMake=None):
371 # check if we need to initialize dune-py either because
372 # this is the first call to load or because an external module with metadata has been registered
373 if not self.initialized or not self.externalPythonModules == getExternalPythonModules():
--> 374 self.initialize()
376 # check whether module is already compiled and build it if necessary
377 # (only try to build module on rank 0!)
378 # TODO replace if rank with something better and remove barrier further down
379 if comm.rank == 0:
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:616, in MakefileBuilder.initialize(self)
615 def initialize(self):
--> 616 super().initialize()
617 # check that the compile script is available
618 script = os.path.join(self.generated_dir,"buildScript.sh")
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:213, in Builder.initialize(self)
211 self.cacheExternalModules()
212 # create dune-py module
--> 213 self.build_dunepy_from_template(self.dune_py_dir)
214 # create tag file so that dune-py is not rebuilt on the next build
215 open(tagfile, 'a').close()
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:472, in MakefileBuilder.build_dunepy_from_template(dunepy_dir, force)
468 if not useNinja:
469 # call base class dunepy_from_template (re-initialize)
470 force = Builder.generate_dunepy_from_template(dunepy_dir, force=True)
--> 472 Builder.callCMake(["cmake"] + defaultCMakeFlags() + ["."],
473 cwd=dunepy_dir,
474 infoTxt="Configuring dune-py with CMake (make)",
475 active=True, # print details anyway
476 )
478 # obtain bash and make command generated by cmake
479 # when ninja is used makeCmd is the ninja command
480 try:
File /dune/dune-common/build-cmake/python/dune/generator/cmakebuilder.py:263, in Builder.callCMake(cmake_args, cwd, infoTxt, verbose, active, logLevel, env)
260 if cmake.returncode > 0:
261 # retrieve stderr output
262 print(stderr,stdout)
--> 263 raise CompileError(buffer_to_str(stderr))
265 return stdout, stderr
CompileError: ---- LOCK
---- ACQUIRED
-- Generating CXX compiler script for CXXFLAGS overloading on command line
---- RELEASE
---- DONE
CMake Error at /dune/dune-common/build-cmake/dune-env/lib/cmake/ikarus/ikarus-targets.cmake:61 (set_target_properties):
The link interface of target "ikarus" contains:
autodiff::autodiff
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
/dune/dune-common/build-cmake/dune-env/lib/cmake/ikarus/ikarus-config.cmake:55 (include)
/dune/dune-common/cmake/modules/DuneModuleDependencies.cmake:170 (find_package)
/dune/dune-common/cmake/modules/DuneModuleDependencies.cmake:289 (find_dune_package)
/dune/dune-common/cmake/modules/DuneModuleDependencies.cmake:336 (dune_process_dependency_leafs)
/dune/dune-common/cmake/modules/DuneModuleDependencies.cmake:46 (dune_create_dependency_leafs)
/dune/dune-common/cmake/modules/DuneProject.cmake:90 (dune_create_dependency_tree)
CMakeLists.txt:106 (dune_project)
which indicates by the linking error, that in some cmake file the linking is not done correctly, thus indicating the first version with pyikarus
is better? But anyway the headers are not findable in this first case. Changes in the files in python/ikarus/
does not change the error messages.
Can someone please point me to the correct changes. I'm willing to create then a proper MR to enable this functionality, if this is of interest. Otherwise, if this should already work can someone correct my mistakes?
The current folder structure can be found at https://github.com/ikarus-project/ikarus/tree/feature/pythonBindingsV3.
Thanks, and any help is very much appreciated.