View Issue Details

IDProjectCategoryView StatusLast Update
0002358Slicer4Core: Extensionspublic2012-09-30 04:54
Reporterlassoan Assigned Tocrmullin  
PrioritynormalSeverityblockReproducibilityalways
Status closedResolutionfixed 
Product Version 
Target VersionSlicer 4.2.0Fixed in VersionSlicer 4.2.0 
Summary0002358: Python wrapping in extensions fails on Mac
Description

Python scripts cannot access the wrapped VTK classes that are implemented in extensions on Mac. It works well on Windows and Linux.

This causes problems in the SlicerRT and Faceted visualization extensions.

TagsNo tags attached.

Relationships

related to 0002390 closedjcfr Slicer build directory is hard-coded 
related to 0002391 closedjcfr Python code that is bundled with an extension is not accessible on Macs 
related to 0002660 closedjcfr failure to load annotation libraries from some extensions 

Activities

pieper

pieper

2012-07-26 10:16

administrator   ~0005260

here is the startup error:

Error(s):
The file '/Users/pieper/Desktop/Slicer-2012-07-23.app/Contents/Extensions/SlicerRT/lib/Slicer-4.1/qt-loadable-modules/libqSlicerDicomRtImportModule.dylib' is not a valid Qt plugin.
Error(s):
The file '/Users/pieper/Desktop/Slicer-2012-07-23.app/Contents/Extensions/SlicerRT/lib/Slicer-4.1/qt-loadable-modules/libqSlicerDoseAccumulationModule.dylib' is not a valid Qt plugin.
Number of registered modules: 104

pieper

pieper

2012-07-26 10:17

administrator   ~0005261

Andrey reports that the same happens for the reporting module 7/25/2012

pieper

pieper

2012-07-31 12:09

administrator   ~0005467

Probably Jc won't be able to get to this for another month or so - if the issue is more urgent than that, please send a note to the developers list.

fedorov

fedorov

2012-07-31 12:19

developer   ~0005469

Steve, Slicer extension is a delivery mechanism for our QIN Slicer-AIM project. Since the functionality itself is mostly available for testing, this issue effectively prevents Mac users from being able to try it out for a month. Yes, I can ask Mac users to compile Slicer, build extension separately and point it to the build directory.

This is not a "minor" issue for us, that's for sure.

lassoan

lassoan

2012-08-06 07:22

developer   ~0005505

Is there any update on this? Does the "=> Slicer 4.2.0 - October 1st 2012" note mean that extensions won't work on Mac till October?

This is how we intend to deliver SlicerRT to users, so if it cannot be fixed till October then please suggest a workaround.

pieper

pieper

2012-08-06 09:31

administrator   ~0005507

Andrey and I tried some debugging on this, but we could not determine why the 'not a valid Qt plugin' failure was being triggered.

One thing we decided to try is building a debug-mode installer and extensions to single step through the library loading process.

First attempt at this did not work, with error message reported below. It appears that cpack is looking in the wrong directory, since these file have moved from /Developer to /Applications/Xcode.app with more recent versions of Xcode.

install_name_tool: input file: /Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/Slicer-4.1.0-2012-07-17-macosx-amd64/Slicer.app/Contents/lib/Python/lib/python2.6/distutils/command/wininst-8.0.exe is not a Mach-O file
install_name_tool: input file: /Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/Slicer-4.1.0-2012-07-17-macosx-amd64/Slicer.app/Contents/lib/Python/lib/python2.6/distutils/command/wininst-9.0-amd64.exe is not a Mach-O file
install_name_tool: input file: /Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/Slicer-4.1.0-2012-07-17-macosx-amd64/Slicer.app/Contents/lib/Python/lib/python2.6/distutils/command/wininst-9.0.exe is not a Mach-O file
CPack: Create package
CPack Error: Error executing: /bin/bash -c "/usr/bin/Rez /Developer/Headers/FlatCarbon/*.r '/Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/sla.r' -a -o '/Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/temp-udco.dmg'"
CPack Error: Error adding SLA.

/usr/bin/Rez - SysError 0 during open of "/Developer/Headers/FlatCarbon/*.r".

Fatal Error!

/usr/bin/Rez - Fatal Error, can't recover.

/Developer/Headers/FlatCarbon/.r: ### /usr/bin/Rez - Since errors occurred, /Users/pieper/slicer4/latest/Slicer-superbuild/Slicer-build/_CPack_Packages/macosx-amd64/DragNDrop/temp-udco.dmg's resource fork was not completely updated.
/Developer/Headers/FlatCarbon/
.r: ### /usr/bin/Rez - SysError -43 during set file info.

CPack Error: Problem compressing the directory
CPack Error: Error when generating package: Slicer
make: *** [package] Error 1

fedorov

fedorov

2012-08-06 09:36

developer   ~0005508

Steve, Andras: on Snow Leopard, I was successful in compiling Qt 4.7.4 in debug mode (with the following flags -debug-and-release -opensource -confirm-license -no-qt3support -webkit -arch x86_64 -nomake examples -nomake demos -sdk /Developer/SDKs/MacOSX10.5.sdk), compiling Slicer in Debug mode, packaging it, and reproducing the problem with the packaged extension.

I did not have time to investigate the actual cause problem yet. Steve, are you around today/tomorrow to look at this together? I am not sure I will be able to figure out the XCode debugger tricks.

pieper

pieper

2012-08-06 09:58

administrator   ~0005509

I know of no workaround at this point - the issue is deep inside cpack and only Jc has been working on this part of the build/install process and on extensions. Andrey and I will have a look but so far things have not looked promising.

Jc told me he has zero connectivity until August 19th (he's in Central America)

pieper

pieper

2012-08-06 12:39

administrator   ~0005510

Thanks to a hint from Demian who remembered a similar error message in the designer plugins, I was able to track down an issue in the .dylib files of the Reporting extension.

In particular, running otool -L on the dylibs shows they contain entries like this:

@executable_path/../Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/libvtkSlicerAnnotationsModuleMRML.dylib

That is, they are looking for the Annotations dylib inside the Reporting extension file, when those are actually in the base slicer lib directory.

By way of a workaround, the following command will fix all the reporting dylib files to point to the correct location of the annotations:

for f in ls Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/*.dylib; do echo $f; install_name_tool -change @executable_path/../Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/libvtkSlicerAnnotationsModuleMRML.dylib @executable_path/../lib/Slicer-4.1/qt-loadable-modules/libvtkSlicerAnnotationsModuleMRML.dylib $f; done

this change allows the Reporting module to be detected and to load (hooray!) and it should provide all the needed info for this to be fixed in the extension build scripts.

Now that the module is loaded, the next issue is that the python code is not importing so no GUI is built. This should be easier to track down and may be due to the same issue.

Traceback (most recent call last):
File "/Users/pieper/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py", line 3, in <module>
from SlicerReportingModuleWidgetHelper import SlicerReportingModuleWidgetHelper as Helper
ImportError: No module named SlicerReportingModuleWidgetHelper
RuntimeError: qSlicerScriptedLoadableModuleWidget::setPythonSource - Failed to load scripted pythonqt module class definition qSlicerReportingModuleWidget from /Users/pieper/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py
Warning, the module "Reporting" has no widget representation
Warning, there is no UI for the module "Reporting"

pieper

pieper

2012-08-06 12:57

administrator   ~0005511

Apparently the python helper code that is bundled with the extension is not accessible because it is not in a place accessible to the python search path. Adding the following to the top of Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py allows the python helper code to be imported:

WORKAROUND: until launcher correctly sets paths for module python files

import sys,os
p = os.path.dirname(slicer.modules.reporting.path)
reportingPython = p + "/Python"
if not sys.path.contains(reportingPython):
sys.path.append(reportingPython)

After adding this, the new error is pasted below. This is probably because the module's logic library is not being initialized correctly:

Show module (name): "Reporting"
Traceback (most recent call last):
File "/Users/pieper/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py", line 44, in init
if self.logic.InitializeDICOMDatabase(self.dbFileName):
AttributeError: InitializeDICOMDatabase
qSlicerScriptedLoadableModuleWidget::setPythonSource "/Users/pieper/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py" - Failed to instantiate scripted pythonqt class "qSlicerReportingModuleWidget" 0x120b12830
Warning, the module "Reporting" has no widget representation
Warning, there is no UI for the module "Reporting"

Note that when accessing the reporting logic it appears as the generic module superclass, not as a reporting logic:

slicer.modules.reporting.logic()
(vtkSlicerModuleLogic)0x11838d838

fedorov

fedorov

2012-08-06 12:57

developer   ~0005512

Steve, I still have "not a valid Qt plugin" after running the workaround you suggested.

pieper

pieper

2012-08-06 13:02

administrator   ~0005513

Note that the same path replacement needs to be done on the .so files as well as the .dylib

This is the same command as above but with .so replacing .dylib

for f in ls Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/*.so; do echo $f; install_name_tool -change @executable_path/../Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/libvtkSlicerAnnotationsModuleMRML.dylib @executable_path/../lib/Slicer-4.1/qt-loadable-modules/libvtkSlicerAnnotationsModuleMRML.dylib $f; done

pieper

pieper

2012-08-06 13:35

administrator   ~0005514

Now I'm able to load the entire extension module into the mac release build (!!!).

Note that I needed to add a second workaround to the start of Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py as shown below.

Now that the issues have been identified it should be a doable project to work these into the extension packaging scripts - ideally, a cpack expert can be recruited to help with this.

WORKAROUND: until launcher correctly sets paths for module python files

import sys,os
reporting = os.path.dirname(slicer.modules.reporting.path)
reportingPython = reporting + "/Python"
for newpath in (reporting, reportingPython):
if not sys.path.contains(newpath):
sys.path.append(newpath)

WORKAROUND: make sure logic is imported before first use so that

logic instance will have the correct subclass (not generic vtkSlicerModuleLogic)

import vtkSlicerReportingModuleLogic

pieper

pieper

2012-08-07 14:25

administrator   ~0005521

Andrey and I got things working after changes to the import mechanisms (more workarounds). I paste the diffs here for documentation (again the real fix should be done in the extensions packaging code).

These are also included in this branch:
https://github.com/fedorov/Reporting/tree/extensionWorkarounds

[6] Reporting ((b357741...))$ diff Py/DICOMSegmentationPlugin.py ~/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-scripted-modules/DICOMSegmentationPlugin.py
6a7,15

WORKAROUND: make sure logic is imported before first use so that

logic instance will have the correct subclass (not generic vtkSlicerModuleLogic)

import sys,os
pluginPath = slicer.app.extensionsInstallPath + '/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python'
if not sys.path.contains(pluginPath):
sys.path.append(pluginPath)
import vtkSlicerReportingModuleLogic
#slicer.modules.reporting.logic = vtkSlicerReportingModuleLogic.vtkSlicerReportingModuleLogic

76c85,86
< reportingLogic = slicer.modules.reporting.logic()

    #reportingLogic = slicer.modules.reporting.logic()
    reportingLogic = vtkSlicerReportingModuleLogic.vtkSlicerReportingModuleLogic()

103c113,114
< reportingLogic = slicer.modules.reporting.logic()

  #reportingLogic = slicer.modules.reporting.logic()
  reportingLogic = vtkSlicerReportingModuleLogic.vtkSlicerReportingModuleLogic()

[7] Reporting ((b357741...))$ diff Py/qSlicerReportingModuleWidget.py ~/Desktop/Slicer-2012-08-02.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py
2a3,19

WORKAROUND: until launcher correctly sets paths for module python files

import sys,os
reporting = os.path.dirname(slicer.modules.reporting.path)
reportingPython = reporting + "/Python"
for newpath in (reporting, reportingPython):
if not sys.path.contains(newpath):
sys.path.append(newpath)

WORKAROUND: make sure logic is imported before first use so that

logic instance will have the correct subclass (not generic vtkSlicerModuleLogic)

import vtkSlicerReportingModuleLogic
import vtkSlicerReportingModuleMRML
import qSlicerReportingModuleWidgetsPythonQt

slicer.modulewidget.qMRMLReportingTreeView = qSlicerReportingModuleWidgetsPythonQt.qMRMLReportingTreeView
slicer.modulemrml.vtkMRMLReportingReportNode = vtkSlicerReportingModuleMRML.vtkMRMLReportingReportNode

26c43,44
< self.__logic = slicer.modulelogic.vtkSlicerReportingModuleLogic()

  #self.__logic = slicer.modulelogic.vtkSlicerReportingModuleLogic()
  self.__logic = vtkSlicerReportingModuleLogic.vtkSlicerReportingModuleLogic()
lassoan

lassoan

2012-08-07 14:40

developer   ~0005522

Very good news! When do you think you can have the fix in the extension packaging code? Just asking so that we can decide if we should apply this workaround on our modules or wait for the packaging update.

finetjul

finetjul

2012-08-08 06:53

administrator   ~0005524

Last edited: 2012-08-08 08:28

Do I understand correctly that there are 2 issues to fix :
a) fixup the path of the shared libraries the extension depends on ( -> otools)
b) add extension python path to environment at Slicer startup

I believe for b), qSlicerExtensionsManagerModelPrivate::addExtensionPathToLauncherSettings() is the place where the python paths are set.
Unfortunately, it applies only when using the Slicer launcher. And there is no launcher (nor a launcher ini file) with an install of Slicer on Mac.

Concerning a), CMake/SlicerExtensionCPackBundleFixup.cmake.in should be investigated. Looks like the matching pattern if(item MATCHES "@Slicer_QTLOADABLEMODULES_LIB_DIR@/[^/]+\.(so|dylib)$") at line
https://github.com/Slicer/Slicer/blob/master/CMake/SlicerExtensionCPackBundleFixup.cmake.in#L115
is used for both the: loadable dylib of the extension AND the loadable dependencies.
Maybe there is a need to split both dylibs. (by adding the path to Slicer for the 2nd type of dylibs)
Something hackish like that might work:
set(Slicer_BUILD_QTLOADABLEMODULES "@Slicer_BUILD_QTLOADABLEMODULES@")
if(Slicer_BUILD_QTLOADABLEMODULES)
if(item MATCHES "Slicer-build/@Slicer_QTLOADABLEMODULES_LIB_DIR@/[^/]+\.(so|dylib)$")
set(path "@executable_path@/../@Slicer_QTLOADABLEMODULES_LIB_DIR@")
elseif(item MATCHES "@Slicer_QTLOADABLEMODULES_LIB_DIR@/[^/]+\.(so|dylib)$")
set(path "@executable_path@/../@Slicer_BUNDLE_EXTENSIONS_LOCATION@@Slicer_QTLOADABLEMODULES_LIB_DIR@")
endif()
endif()

pieper

pieper

2012-08-08 08:56

administrator   ~0005525

Yes Julien, I agree - there are two issues.

finetjul

finetjul

2012-08-08 10:25

administrator   ~0005527

Concerning a),
Maybe a hack could be for qSlicerCorePythonManager::pythonPaths() to add settings.value("Modules/AdditionalPaths").toStringList() (with a "/Python" suffix) in the list of paths to add in PYTHONPATH.

crmullin

crmullin

2012-08-10 14:16

developer   ~0005538

Last edited: 2012-08-10 14:59

Here is a partial fix for the incorrect loading of dependencies located in the base slicer lib:

https://github.com/chrismullins/Slicer/commit/d33771aa9893523b20fb003521a9ea96c21b14e3

jcfr

jcfr

2012-08-23 15:07

administrator   ~0005771

Fixed in r20852
See http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&amp;revision=20852

fedorov

fedorov

2012-08-25 05:07

developer   ~0005787

There is no error about the shared libraries, but python error is still there. The extension is still not usable.

File "/Applications/Slicer.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py", line 76, in init
self.__logic.SetActiveParameterNodeID(paramID)
AttributeError: SetActiveParameterNodeID
qSlicerScriptedLoadableModuleWidget::setPythonSource "/Applications/Slicer.app/Contents/Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/Python/qSlicerReportingModuleWidget.py" - Failed to instantiate scripted pythonqt class "qSlicerReportingModuleWidget" 0x1306c8350

jcfr

jcfr

2012-08-29 13:57

administrator   ~0005865

Chris> Could you investigate ? It is now possible to load the python module directly given its name ? What the value of the "sys.path", are the path associated with the extensions displayed ?

Thanks

crmullin

crmullin

2012-09-17 09:35

developer   ~0006112

Last edited: 2012-09-17 09:37

On today's nightly, the following problem presents:

The "Extensions" directory is not created when Slicer is installed on Mac.

Example: otool -L /Applications/Slicer.app/Contents/Reporting/lib/Slicer-4.1/qt-loadable-modules/ libqSlicerReportingModule.dylib
has entries like this:
@executable_path/../Extensions/Reporting/lib/Slicer-4.1/qt-loadable-modules/libqSlicerReportingModule.dylib

But since the Contents/Extensions is not created, the Reporting directory is installed directly into Contents. So Contents/Reporting/<everything> exists, but the extension is trying to look for Contents/Extensions/Reporting/<everything>

I didn't recall this being the case before. Simply creating the Extensions directory in the right place will cause Slicer to see it and install the extensions in the correct place.

EDIT: Is this note in the wrong place? It seems like a separate issue, but maybe related to one of the recent fixes.

jcfr

jcfr

2012-09-17 09:52

administrator   ~0006113

Good catch. I guess there are multiple option to solve that issue:

1) Add some code to check such directory exist if Slicer is executed from a packaged/installed tree. See https://github.com/Slicer/Slicer/blob/master/Base/QTCore/qSlicerCoreApplication.cxx#L268

2) Update the CPack/packaging code so that the directory is created.

I guess option 2) will avoid some minimal overhead when Slicer is started. the advantage of option 1) is that Slicer will check that the expected folder exists each time Slicer is started.

May be both option could be implemented.

jcfr

jcfr

2012-09-28 14:12

administrator   ~0006269

Fixed in r21075
See http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&amp;revision=21075

Issue History

Date Modified Username Field Change
2012-07-26 05:54 lassoan New Issue
2012-07-26 05:54 lassoan Status new => assigned
2012-07-26 05:54 lassoan Assigned To => jcfr
2012-07-26 10:16 pieper Note Added: 0005260
2012-07-26 10:17 pieper Note Added: 0005261
2012-07-29 20:34 fedorov Severity minor => block
2012-07-31 12:09 pieper Note Added: 0005467
2012-07-31 12:19 fedorov Note Added: 0005469
2012-08-03 15:25 pieper Reproducibility have not tried => always
2012-08-03 15:25 pieper Target Version => Slicer 4.2.0 - October 1st 2012
2012-08-06 07:22 lassoan Note Added: 0005505
2012-08-06 09:31 pieper Note Added: 0005507
2012-08-06 09:36 fedorov Note Added: 0005508
2012-08-06 09:58 pieper Note Added: 0005509
2012-08-06 12:39 pieper Note Added: 0005510
2012-08-06 12:57 pieper Note Added: 0005511
2012-08-06 12:57 fedorov Note Added: 0005512
2012-08-06 13:02 pieper Note Added: 0005513
2012-08-06 13:35 pieper Note Added: 0005514
2012-08-07 14:25 pieper Note Added: 0005521
2012-08-07 14:40 lassoan Note Added: 0005522
2012-08-08 06:53 finetjul Note Added: 0005524
2012-08-08 07:00 finetjul Note Edited: 0005524
2012-08-08 08:28 finetjul Note Edited: 0005524
2012-08-08 08:56 pieper Note Added: 0005525
2012-08-08 10:25 finetjul Note Added: 0005527
2012-08-10 14:16 crmullin Note Added: 0005538
2012-08-10 14:36 crmullin Relationship added related to 0002390
2012-08-10 14:48 crmullin Relationship added related to 0002391
2012-08-10 14:59 crmullin Note Edited: 0005538
2012-08-23 15:07 jcfr Note Added: 0005771
2012-08-23 15:07 jcfr Status assigned => resolved
2012-08-23 15:07 jcfr Fixed in Version => Slicer 4.2.0 - Feature freeze Sept 1st 2012
2012-08-23 15:07 jcfr Resolution open => fixed
2012-08-25 05:07 fedorov Note Added: 0005787
2012-08-25 05:07 fedorov Status resolved => feedback
2012-08-25 05:07 fedorov Resolution fixed => reopened
2012-08-29 13:52 jcfr Status feedback => assigned
2012-08-29 13:52 jcfr Assigned To jcfr => crmullin
2012-08-29 13:57 jcfr Note Added: 0005865
2012-09-17 09:35 crmullin Note Added: 0006112
2012-09-17 09:36 crmullin Note Edited: 0006112
2012-09-17 09:37 crmullin Note Edited: 0006112
2012-09-17 09:52 jcfr Note Added: 0006113
2012-09-28 14:12 jcfr Note Added: 0006269
2012-09-28 14:12 jcfr Status assigned => resolved
2012-09-28 14:12 jcfr Resolution reopened => fixed
2012-09-30 04:54 fedorov Status resolved => closed
2012-10-17 14:40 fedorov Relationship added related to 0002660