UseSWIG: Duplicate OUTPUT_NAME values for different targets conflict
I have a project built with CMake (3.15) that builds a SWIG target for Python. It was building just for Python 2, I am upgrading to work with Python 3 as well. I am doing this by taking the existing target name (myTarget
) and creating duplicate versions for both py2 and py3 (myTarget_py2
and myTarget_py3
). They both need to output the same filename (_myTarget.pyd
) in different locations, and therefore I am setting the OUTPUT_NAME property to the same value for both. I was assuming this would be fine because the targets are built in different directories, but it turns out that they must overlap somewhere, because the py2 target gets linked against Python 3. If I change the OUTPUT_NAME property of the py3 target, this does not occur. I believe this must be a bug because the different targets should be entirely separate.
Steps to reproduce (every time):
- Detect both Python 2 and Python 3 libraries using
find_package (Python[2|3] COMPONENTS Interpreter Development)
- Create two targets using
swig_add_library
- Set OUTPUT_NAME property for both to the same value (
set_property(TARGET myTarget_py[2|3] PROPERTY OUTPUT_NAME myTarget)
) - Include correct python library in each target (
target_include_directories(myTarget_py[2|3] PUBLIC ${Python[2|3]_INCLUDE_DIRS})
- Install resulting output files to different directories (
install(TARGETS myTarget_py[2|3] DESTINATION "./python[2|3]")
)
Expected results:
- Importing python2 output succeeds in a python 2 interpreter, Importing python3 output succeeds in a python 3 interpreter
Actual results:
- Importing at least one of the files fails with "ImportError: DLL load failed: The specified module could not be found. "
- Inspection of dependency tree of python 2 pyd file using Dependency Walker shows (failed) Python 3 DLL dependency
Environment:
- Windows Server 2008
- CMake 3.15
- Python 2.7.8 & 3.7
- SWIG 3.0.10
I have given this example using SWIG and python 2/3 because that's where I've encountered it so that's how I know to reproduce it, but the problem cannot be with SWIG because SWIG doesn't know or care about CMake's OUTPUT_NAME value, so changing that would have had no effect. Presumably therefore the problem would be reproducible without SWIG or Python as long as you knew what you were looking for.
The OUTPUT_NAME value needs to be the same because the file is imported by python code that is version-agnostic. The same file will be running under python 2 and under python 3, and I don't want to change all the places it's imported (there are quite a few) to do version detection and import a different name. So that's why I was setting OUTPUT_NAME to be the same.