[Bug] UseSWIG.cmake SWIG_COMPILE_OPTIONS not properly parsed.
Context
For a project having few C++ libraries but providing one .Net Core wrapping library, I need to generate few swig wrapper OBJECT library which will be merge in a SHARED library.
So I use the -dllimport
option of swig to force the name of the will be shared library by setting it using the property SWIG_COMPILE_OPTIONS
of my .i
swig files...
Then, when using swig_add_library if this option is present the function should use it https://gitlab.kitware.com/cmake/cmake/blob/ab2d170c746d7cb68c39e9577cdaabc66668c0aa/Modules/UseSWIG.cmake#L420-424 instead of generating one by introspecting the library target property https://gitlab.kitware.com/cmake/cmake/blob/ab2d170c746d7cb68c39e9577cdaabc66668c0aa/Modules/UseSWIG.cmake#L483-489
But it seems the current implementation simply ignore it (i.e. bug implementation) !!!
note: TARGET_FILE_PREFIX
does not exist for OBJECT
library that's why the cmake configure fail...
Test
Using CMake 3.16.4 on gLinux (kind of custom Debian for googlers) (installed using https://cmake.org/files/v3.16/cmake-3.16.4-Linux-x86_64.sh)
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
# SWIG: use standard target name.
if(POLICY CMP0078)
cmake_policy(SET CMP0078 NEW)
endif()
# SWIG: use SWIG_MODULE_NAME property.
if(POLICY CMP0086)
cmake_policy(SET CMP0086 NEW)
endif()
project(FooBar VERSION 1.0 LANGUAGES CXX)
find_package(SWIG)
include(UseSWIG)
file(GENERATE OUTPUT foo.i CONTENT "")
set_property(SOURCE foo.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE foo.i PROPERTY SWIG_MODULE_NAME google_foo)
set_property(SOURCE foo.i PROPERTY SWIG_COMPILE_OPTIONS
-namespace Google.FooBar.Foo
-dllimport google-native
)
# Use TYPE OBJECT since TARGET_FILE_PREFIX does not exist which is fine since we
# use `-dllimport` compile option
swig_add_library(google_foo
TYPE OBJECT
LANGUAGE csharp
OUTPUT_DIR ${PROJECT_BINARY_DIR}/dotnet/${PROJECT_NAME}/foo
SOURCES foo.i)
file(GENERATE OUTPUT bar.i CONTENT "")
set_property(SOURCE bar.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE bar.i PROPERTY SWIG_MODULE_NAME google_bar)
set_property(SOURCE bar.i PROPERTY SWIG_COMPILE_OPTIONS
-namespace Google.FooBar.Bar
-dllimport google-native
)
swig_add_library(google_bar
TYPE OBJECT
LANGUAGE csharp
OUTPUT_DIR ${PROJECT_BINARY_DIR}/dotnet/${PROJECT_NAME}/bar
SOURCES bar.i)
#add_library(google-native SHARED google_foo google_bar)
#...
Observed
cmake -S. -Bbuild
-- The CXX compiler identification is GNU 9.2.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found SWIG: /usr/bin/swig3.0 (found version "3.0.12")
-- Configuring done
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_foo>
Target "google_foo" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:29 (swig_add_library)
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_bar>
Target "google_bar" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:44 (swig_add_library)
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_foo>
Target "google_foo" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:29 (swig_add_library)
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_foo>
Target "google_foo" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:29 (swig_add_library)
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_bar>
Target "google_bar" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:44 (swig_add_library)
CMake Error at /usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:517 (add_custom_command):
Error evaluating generator expression:
$<TARGET_FILE_PREFIX:google_bar>
Target "google_bar" is not an executable or library.
Call Stack (most recent call first):
/usr/local/google/home/corentinl/.local/share/cmake-3.16/Modules/UseSWIG.cmake:702 (SWIG_ADD_SOURCE_TO_MODULE)
CMakeLists.txt:44 (swig_add_library)
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
Expected
The above code should pass the configuration step...
Workaround
Use the CMAKE_SWIG_FLAGS
instead
list(APPEND CMAKE_SWIG_FLAGS -dllimport google-native)
Patch
Modify line: https://gitlab.kitware.com/cmake/cmake/blob/ab2d170c746d7cb68c39e9577cdaabc66668c0aa/Modules/UseSWIG.cmake#L484
by
--- UseSWIG.cmake.bckp 2020-02-26 15:02:36.599207028 +0100
+++ UseSWIG.cmake 2020-02-26 15:24:52.134500176 +0100
@@ -463,7 +463,18 @@
set (swig_extra_flags)
if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "CSHARP")
- if(NOT ("-dllimport" IN_LIST swig_source_file_flags OR "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
+
+ # Get list of SWIG_COMPILE_OPTIONS at configure time
+ foreach(swig_src IN LISTS _SAM_SOURCES)
+ get_property(options_flags SOURCE ${swig_src} PROPERTY SWIG_COMPILE_OPTIONS)
+ list(APPEND swig_source_compile_options ${options_flags})
+ endforeach()
+
+ if(
+ NOT (
+ "-dllimport" IN_LIST swig_source_file_flags OR
+ "-dllimport" IN_LIST swig_source_compile_options OR
+ "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
# This makes sure that the name used in the generated DllImport
# matches the library name created by CMake
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
note: tested on my machine by hacking my local CMake install file...