Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify and improve wrappers #261

Merged
merged 40 commits into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1ed796f
Update to the latest SWIG
aprokop Jan 30, 2019
9121096
Move generated files into "swig" subdirectory
sethrj Feb 1, 2019
a582813
Refactor SWIG cmake files for new cmake version
sethrj Feb 1, 2019
10bc19d
Converts code to use native Fortran logic type
sethrj Feb 1, 2019
a62ea87
Use F90 instead of f90 to enable C preprocessing
sethrj Feb 1, 2019
309980f
Add native ArrayView type mapping
sethrj Feb 1, 2019
dce87c0
Simplify MultiVector wrapping
sethrj Feb 1, 2019
9cb7149
Clean warnings in unit tests
sethrj Feb 2, 2019
d91a10d
Replace local_ordinal_type with native Fortran int
sethrj Feb 2, 2019
709ce03
Improve Tpetra_Map interface
sethrj Feb 2, 2019
0f09dd8
Switch to typemaps in several classes
sethrj Feb 4, 2019
eb2d742
Improve typemap
sethrj Feb 2, 2019
456e45e
Improve CRS typemaps
sethrj Feb 2, 2019
946af09
Replace "self" with "$self"
sethrj Feb 3, 2019
30a42a8
Wrap constants as Fortran literals
sethrj Feb 4, 2019
b184d60
Use typemaps for Map and CrsMatrix
sethrj Feb 4, 2019
f1af717
Change eigen_handle result to 'int' from 'size_t'
sethrj Feb 4, 2019
e510045
Change interface from std::pair to ArrayView
sethrj Feb 4, 2019
2400ca0
Combine Import and Export headers
sethrj Feb 4, 2019
e7b8129
Combine several "ignore" directives
sethrj Feb 4, 2019
993f275
Remove deprecated tpetra methods
sethrj Feb 4, 2019
8e994ab
Replace MatrixMarket wrappers with simpler class definition
sethrj Feb 4, 2019
4a05f37
Clean unused variables from tests
sethrj Feb 4, 2019
86708c6
Add output-on-failure flag to CTest
sethrj Feb 4, 2019
f5d7659
Fix eigen_handle test and internal check
sethrj Feb 4, 2019
fc13f68
Fix assignment from null array
sethrj Feb 4, 2019
ad811a0
New test for broke TpetraCrsMatrix%getGlobalRowView
tjfulle Feb 12, 2018
cb209b9
Implement getGlobalRowView using array pointers
sethrj Feb 6, 2019
2b04a71
Add typemap for array RCP
sethrj Feb 6, 2019
0fe1f28
Remove debug code
sethrj Feb 6, 2019
4889bd1
Add check for non-null pointer when taking ArrayView&
sethrj Feb 7, 2019
8ae8a94
Fix binding type error noticed by latest swig
sethrj Feb 12, 2019
11b2476
Update for latest SWIG
sethrj Feb 12, 2019
f14c299
Update to latest SWIG master
sethrj Mar 21, 2019
0e10afc
Update to latest SWIG master
sethrj May 9, 2019
6f96b2c
Hide functions that use opaque data types
sethrj May 9, 2019
6323e1f
Silence warnings
sethrj May 9, 2019
7147ce9
Replace manual `%ignore` with autoignore
sethrj May 9, 2019
5f137bc
Fix typos
sethrj May 9, 2019
17ee435
Fix wrapping of NOX return status type
sethrj May 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,27 @@ TRIBITS_PACKAGE_DECL(ForTrilinos)
TRIBITS_ADD_DEBUG_OPTION()
TRIBITS_ADD_SHOW_DEPRECATED_WARNINGS_OPTION()

# Enable unlimited-length lines and C-like preprocessing
SET(CMAKE_Fortran_FLAGS "-ffree-line-length-none -cpp ${CMAKE_Fortran_FLAGS}")
# Enable unlimited-length lines
if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_Fortran_FLAGS "-ffree-line-length-none ${CMAKE_Fortran_FLAGS}")
endif()

IF (${PACKAGE_NAME}_ENABLE_DeveloperMode)
# SWIG setup
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(SwigModules)
# SWIG is requested and available; make sure it's the Fortran fork.
INCLUDE(CheckSWIGFortran)
IF (CMAKE_VERSION VERSION_LESS 3.10)
# TODO: Old version of cmake modules
include(SwigModulesOld)
ELSE()
include(SwigModules)
ENDIF()

# Ignore some SWIG warnings:
# 401: "Nothing known about base class"
SET(CMAKE_SWIG_FLAGS "-w401 ${CMAKE_SWIG_FLAGS}")
LIST(APPEND CMAKE_SWIG_FLAGS "-w401" "-fext" "F90")
set(SWIG_FORTRAN_EXTRA_FILE_EXTENSIONS ".F90")

IF (NOT TPL_ENABLE_MPI)
# Warn if MPI is disabled since not all wrapper functions will be
Expand Down
23 changes: 23 additions & 0 deletions cmake/CheckSWIGFortran.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
include(UseSWIG)

set(SWIG_FORTRAN_EXTRA_FILE_EXTENSIONS ".f90")

# Check that SWIG has been found
if (NOT SWIG_EXECUTABLE)
message(FATAL_ERROR "SWIG is not available.")
endif()

# Make sure it's the branch that actually supports Fortran
if (NOT SWIG_CHECKED_FORTRAN)
execute_process(COMMAND ${SWIG_EXECUTABLE} -help
OUTPUT_VARIABLE SWIG_help_output
ERROR_VARIABLE SWIG_help_output
RESULT_VARIABLE SWIG_help_result)
if (NOT SWIG_help_output MATCHES "Fortran")
message(FATAL_ERROR "This version of SWIG does not support Fortran "
"wrapping. Please install the version from "
"https://github.com/sethrj/swig")
endif()
set(SWIG_CHECKED_FORTRAN TRUE CACHE INTERNAL "")
endif()

273 changes: 69 additions & 204 deletions cmake/SwigModules.cmake
Original file line number Diff line number Diff line change
@@ -1,68 +1,19 @@
##############################################################################
# File : SwigModules.cmake
# Author: Seth Johnson
# Date : Wednesday July 18 17:5:36 2012
#----------------------------------------------------------------------------#
# Copyright (C) 2012 Oak Ridge National Laboratory, UT-Battelle, LLC.
##############################################################################

IF (NOT DEFINED SWIG_DIR)
MESSAGE(FATAL_ERROR "SWIG not loaded.")
ENDIF()

# Load SWIG and other modules we need
INCLUDE(UseSWIG)
INCLUDE(CMakeParseArguments)
INCLUDE(CheckCXXCompilerFlag)

# Tell SWIG to use modern Python code
LIST(APPEND CMAKE_SWIG_PYTHON_FLAGS "-modern" "-noproxydel")

# If python version is high enough, add -py3 flag
IF(PYTHON_VERSION_STRING VERSION_GREATER 3.0)
LIST(APPEND CMAKE_SWIG_PYTHON_FLAGS "-py3")
ENDIF()

# Define extra output files
set(SWIG_FORTRAN_EXTRA_FILE_EXTENSIONS ".f90")# new CMake

##---------------------------------------------------------------------------##
# Look through a header/SWIG file and find dependencies

MACRO(get_swig_dependencies _RESULT_VAR _SOURCE)
# Search for dependencies in the SWIG file
FILE(STRINGS ${_SOURCE} HEADER_FILES
REGEX "^[ \t]*%include *\""
)
LIST(REMOVE_DUPLICATES HEADER_FILES)

# Set up test directories
SET(TEST_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
)

# Get just the file names inside each "include"
SET(${_RESULT_VAR})
FOREACH(THEFILE ${HEADER_FILES})
STRING(REGEX REPLACE "^.*\"([^\"]+)\".*$" "\\1" THEFILE ${THEFILE})
IF( THEFILE )
FOREACH(TESTDIR ${TEST_DIRS})
IF(EXISTS ${TESTDIR}/${THEFILE})
LIST(APPEND ${_RESULT_VAR} ${TESTDIR}/${THEFILE})
BREAK()
ENDIF()
ENDFOREACH()
ENDIF()
ENDFOREACH()
ENDMACRO()
set(UseSWIG_MODULE_VERSION 2)
if (CMAKE_VERSION VERSION_LESS 3.20)
# TODO: This is until Fortran support gets added to the upstream cmake script
include(UseSWIGFortran)
else()
cmake_policy(SET CMP0078 "NEW")
cmake_policy(SET CMP0086 "NEW")
include(UseSWIG)
endif()

##---------------------------------------------------------------------------##
## ADDING SWIG MODULES
##---------------------------------------------------------------------------##
# MAKE_SWIG(
# MAKE_SWIG_FORTRAN(
# MODULE module
# [C]
# [LANGUAGE fortran]
# [SOURCE src.i]
# [DEPLIBS lib1 [lib2 ...]]
# [DEPMODULES module1 [module2 ...]]
Expand All @@ -86,31 +37,21 @@ ENDMACRO()
# The EXTRASRC argument allows additional sources to be compiled into the SWIG
# module target.

function(MAKE_SWIG)
function(MAKE_SWIG_FORTRAN)
cmake_parse_arguments(PARSE "C" "MODULE;LANGUAGE;SOURCE"
"DEPLIBS;DEPMODULES;EXTRASRC" ${ARGN})

if(NOT PARSE_MODULE)
if (NOT PARSE_MODULE)
message(SEND_ERROR "Cannot call MAKE_SWIG without MODULE")
endif()
set(PARSE_MODULE ${PARSE_MODULE})

if(NOT PARSE_LANGUAGE)
SET(PARSE_LANGUAGE FORTRAN)
endif()
string(TOUPPER "${PARSE_LANGUAGE}" PARSE_LANGUAGE)

if(PARSE_SOURCE)
if (PARSE_SOURCE)
set(SRC_FILE "${PARSE_SOURCE}")
else()
set(SRC_FILE "${PARSE_MODULE}.i")
endif()

if(NOT CMAKE_SWIG_OUTDIR)
# XXX: turn this into an option passed into the function
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()

# Let SWIG know that we're compiling C++ files, and what the module is
set_source_files_properties(${SRC_FILE} PROPERTIES
SWIG_MODULE_NAME ${PARSE_MODULE})
Expand All @@ -120,145 +61,69 @@ function(MAKE_SWIG)
CPLUSPLUS TRUE)
endif()

IF ("${CMAKE_VERSION}" VERSION_LESS "3.11.0")
# Get dependencies of main SWIG source file and the files it includes.
# A similar feature was integrated into SWIG:
# https://gitlab.kitware.com/cmake/cmake/merge_requests/354
set(SUBDEPS ${SRC_FILE})
set(DEPENDENCIES)
foreach(RECURSION 0 1 2)
set(OLD_SUBDEPS ${SUBDEPS})
set(SUBDEPS)
foreach(DEPENDENCY ${OLD_SUBDEPS})
if(DEPENDENCY MATCHES "\\.i$")
get_swig_dependencies(SUBSUBDEPS ${DEPENDENCY})
list(APPEND SUBDEPS ${SUBSUBDEPS})
endif()
endforeach()
list(APPEND DEPENDENCIES ${SUBDEPS})
endforeach()

message("Extra dependencies for ${SRC_FILE}:\n ${DEPENDENCIES}" )
set(SWIG_MODULE_${PARSE_MODULE}_EXTRA_DEPS ${DEPENDENCIES} )
ENDIF()

if (PARSE_LANGUAGE STREQUAL "FORTRAN")
set(SWIG_FORTRAN_GENERATED_SRC "${CMAKE_SWIG_OUTDIR}/${PARSE_MODULE}.f90")
# Usually SWIG wrapper libraries need to be built as shared libraries that
# are never linked into the CMake dependencies themselves (the "MODULE"
# type); not the case with fortran. This relies on the patched UseSWIG.
if(BUILD_SHARED_LIBS)
set(SWIG_LIBRARY_TYPE SHARED)
else()
set(SWIG_LIBRARY_TYPE STATIC)
endif()
else()
set(SWIG_LIBRARY_TYPE MODULE)
endif()

# Set up compiler flags
set(_ORIG_CMAKE_SWIG_FLAGS ${CMAKE_SWIG_FLAGS})
list(APPEND CMAKE_SWIG_FLAGS "${CMAKE_SWIG_${PARSE_LANGUAGE}_FLAGS}")

# Create the SWIG module
if (DEFINED TRIBITS_CMAKE_MINIMUM_REQUIRED AND PARSE_LANGUAGE STREQUAL "FORTRAN")
# Special case for Tribits build systems is needed to propagate includes,
# rpaths, etc.

# XXX hack to set up link/include directories BEFORE the call to
# TRIBITS_ADD_LIBRARY
TRIBITS_SORT_AND_APPEND_PACKAGE_INCLUDE_AND_LINK_DIRS_AND_LIBS(
${PACKAGE_NAME} LIB LINK_LIBS)

TRIBITS_SORT_AND_APPEND_TPL_INCLUDE_AND_LINK_DIRS_AND_LIBS(
${PACKAGE_NAME} LIB LINK_LIBS)

PRINT_VAR(${PACKAGE_NAME}_INCLUDE_DIRS)
# # Add TriBITS include directories to the SWIG commands (because the
# # add_library call comes after the SWIG creation, the "include_directories"
# # command hasn't been called at this point.)
# FOREACH(dir ${${PACKAGE_NAME}_INCLUDE_DIRS})
# LIST(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
# ENDFOREACH()

# Generate the SWIG commands and targets
SWIG_MODULE_INITIALIZE(${PARSE_MODULE} ${PARSE_LANGUAGE})
SWIG_ADD_SOURCE_TO_MODULE(${PARSE_MODULE} swig_wrapper_src ${SRC_FILE})
get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
list(APPEND swig_extra_clean_files "${swig_wrapper_src}"
"${SWIG_FORTRAN_GENERATED_SRC}")
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
"${swig_extra_clean_files}")

# Add as a TriBITS library
TRIBITS_ADD_LIBRARY(${PARSE_MODULE}
SOURCES ${PARSE_EXTRASRC}
${SWIG_FORTRAN_GENERATED_SRC}
${swig_wrapper_src})
else()
swig_add_library(${PARSE_MODULE}
LANGUAGE ${PARSE_LANGUAGE}
TYPE ${SWIG_LIBRARY_TYPE}
SOURCES ${SRC_FILE} ${SWIG_FORTRAN_GENERATED_SRC} ${PARSE_EXTRASRC})
endif()

# Restore original SWIG flags
SET(CMAKE_SWIG_FLAGS _ORIG_CMAKE_SWIG_FLAGS)

# Mangled name of the SWIG target (export to parent)
set(BUILT_LIBRARY ${SWIG_MODULE_${PARSE_MODULE}_REAL_NAME})
set(SWIG_MODULE_${PARSE_MODULE}_REAL_NAME ${BUILT_LIBRARY} PARENT_SCOPE)

# It's not always necessary to link against python libraries, but doing so
# can turn unfortunate run-time errors (dlopen) into link-time errors.
if(PARSE_LANGUAGE STREQUAL "PYTHON" AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if(NOT ${PYTHON_LIBRARIES} MATCHES ".framework")
# Turn off undefined symbol errors on Mac systems where
# Python is not installed as a framework
# see http://bugs.python.org/issue1602133 about _initposix issues
set_target_properties(${BUILT_LIBRARY}
PROPERTIES LINK_FLAGS "-undefined suppress -flat_namespace")
else()
# Otherwise, link against Python libraries
swig_link_libraries(${PARSE_MODULE} ${PYTHON_LIBRARIES})
endif()
endif()
# UseSWIG with "NEW" policy creates a target with the same name as the first
# argument to swig_add_library.
set(LIBRARY_NAME ${PARSE_MODULE})
swig_add_library(${LIBRARY_NAME}
LANGUAGE Fortran
TYPE USE_BUILD_SHARED_LIBS
SOURCES ${SRC_FILE} ${PARSE_EXTRASRC})

# Link against other dependent libraries
IF (PARSE_DEPLIBS)
target_link_libraries(${BUILT_LIBRARY} ${PARSE_DEPLIBS})
ENDIF()

# Add intra-module dependencies
if (PARSE_DEPLIBS)
target_link_libraries(${LIBRARY_NAME} ${PARSE_DEPLIBS})
endif()
foreach(DEPMODULE ${PARSE_DEPMODULES})
add_dependencies(${BUILT_LIBRARY} _${DEPMODULE})
add_dependencies(${LIBRARY_NAME} ${DEPMODULE})
endforeach()

# Include the Python directory and current source directory for the SWIG
# targets (SWIG processor and compilation of the resulting CXX file.) We don't
# use the INCLUDE_DIRECTORIES command because because TriBITS will
# propagate the path if we use INCLUDE_DIRECTORIES.
# Apply SWIG_CXX_FLAGS to hide warnings and such.
get_target_property(INCL_DIR ${BUILT_LIBRARY} INCLUDE_DIRECTORIES)
IF(NOT INCL_DIR)
SET(INCL_DIR "")
ENDIF()
list(APPEND INCL_DIR ${CMAKE_CURRENT_SOURCE_DIR})
if (PARSE_LANGUAGE STREQUAL "PYTHON")
list(APPEND INCL_DIR ${PYTHON_INCLUDE_DIRS})
set(LINK_LIBS)
# XXX From TribitsLibraryMacros
TRIBITS_SORT_AND_APPEND_PACKAGE_INCLUDE_AND_LINK_DIRS_AND_LIBS(
${PACKAGE_NAME} LIB LINK_LIBS)

TRIBITS_SORT_AND_APPEND_TPL_INCLUDE_AND_LINK_DIRS_AND_LIBS(
${PACKAGE_NAME} LIB LINK_LIBS)
# XXX END

# Set properties on the target.
get_target_property(INCL_DIR ${LIBRARY_NAME} INCLUDE_DIRECTORIES)
if (NOT INCL_DIR)
set(INCL_DIR)
endif()
list(APPEND INCL_DIR ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
list(REMOVE_DUPLICATES INCL_DIR)
set_target_properties(${BUILT_LIBRARY} PROPERTIES
INCLUDE_DIRECTORIES "${INCL_DIR}"
set_target_properties(${LIBRARY_NAME} PROPERTIES
SWIG_INCLUDE_DIRECTORIES "${INCL_DIR}"
COMPILE_FLAGS "${SWIG_CXX_FLAGS}")
target_link_libraries(${LIBRARY_NAME} ${LINK_LIBS})

# XXX From TribitsLibraryMacros
# Add to tribits library list
SET_PROPERTY(
TARGET ${LIBRARY_NAME}
APPEND PROPERTY
LABELS ${PACKAGE_NAME}Libs ${PARENT_PACKAGE_NAME}Libs
)
PREPEND_GLOBAL_SET(${PARENT_PACKAGE_NAME}_LIB_TARGETS ${LIBRARY_NAME})
PREPEND_GLOBAL_SET(${PARENT_PACKAGE_NAME}_ALL_TARGETS ${LIBRARY_NAME})
INSTALL(
TARGETS ${LIBRARY_NAME}
EXPORT ${PACKAGE_NAME}
RUNTIME DESTINATION "${${PROJECT_NAME}_INSTALL_RUNTIME_DIR}"
LIBRARY DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}"
ARCHIVE DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}"
COMPONENT ${PACKAGE_NAME}
)
PREPEND_GLOBAL_SET(${PACKAGE_NAME}_INCLUDE_DIRS ${INCL_DIR})
PREPEND_GLOBAL_SET(${PACKAGE_NAME}_LIBRARY_DIRS ${INCL_DIR})
PREPEND_GLOBAL_SET(${PACKAGE_NAME}_LIBRARIES ${LIBRARY_NAME})

# message(STATUS "Include directories on target ${PARSE_MODULE}: ${INCL_DIR}")
GLOBAL_SET(${PACKAGE_NAME}_HAS_NATIVE_LIBRARIES TRUE)
# XXX END TriBits

# define the install targets
if (PARSE_LANGUAGE STREQUAL "PYTHON")
install(TARGETS ${BUILT_LIBRARY}
DESTINATION python)
install(FILES ${CMAKE_SWIG_OUTDIR}/${PARSE_MODULE}.py
DESTINATION python)
endif ()
# Install the built target module
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PARSE_MODULE}.mod
DESTINATION include)
endfunction()


Loading