Skip to content

Commit 3f2dbef

Browse files
committed
These are some improvements to SuperLU to try to make it more cross platform and facilitate packaging.
These improvements are: 1) Force the built in blas library to be compiled as static instead of shared. This is so it can linked into the shared library in Windows and probably other Operating Systems. The internal cblas library can NOT be built as a a shared library by itself. 2) Remove the assumption that the SuperLU library shared run-time library will be prefixed with lib and have a “.so” or “.a” file extension. In Windows, the shared run-time library has a .dll extension. In Windows Visual C, a prefix such as “lib” is not used and the extension is “.lib”, not “.a” In Cygwin and MSYS2, the run-time .dll prefix is not “lib” at all. It is “cyg” and “msys-“ respectively. Making this more complicated is that in Windows, you do not link directly with the shared-library run-time file but rather, an import library. In MINGW-W64, CygWin, and MSYS, that has the extension, “.dll.a”. 3) Another issue is that in Windows 64, unlike many Unix-like Operating Systems, the int, uint, and long do not expand to 8 bits in the 64-bit version of Windows, Those types are still 4 bytes wide which is not wide enough for an 8-byte sized pointer. To fix this, I had to change int to ptrdiff_t in ExpHeader and LU_stack_t in slu_util.h. For sizes, the size_t really should be used and for pointers, a pointer should be used. GCC will rightfully warn you about this issue. 4) I implemented building doxygen documentation into the cmake build process and Cmake can also install the documentation. You now have the option of building the SuperLU documentation as .HTML or the traditional man pages as well as both depending upon packaging needs. 5) I tried fixing some doxygen warnings. I use Doxygen 1.8.14 along with Grapviz to generate diagrams. I made a Doxyfile.in that generates a Doxyfile in the build directory if enable_docs is on. I also use Doxygen to create to .HTML and Unix man documentation. 6) The make.inc file generated by cmake is copied to the build directories. The thing is that sometimes, you might be building several different sets of binaries for i686 (32-bit) and (x86_64) 64-bit as well as a static and shared version for inclusion in packages. IOW, I am generating 4 sets of SuperLU binary files. Actually, I think the Makefile build system is not adequate for building stuff on Windows using GCC because you use a command such as “g++ -shared -o example_dll.dll example_dll.o -Wl,--out-implib,libexample_dll.a” 7) In Windows, it’s usually a good idea to embed version information right into the .dll run-time so that if you right click it, you can get information such as the copyright and .DLL version in Windows explorer. 8) I had to fix the library install so that the .dll file is always installed in the bin directory instead of the lib directory. Windows will search first for .dll’s in the same directory as the executable. MINGW, Cygwin, and MSYS packages also place the .DLL’s in the appropriate directory to take advantage of this. 9) When building the interal CBLAS library, Cmake will check for the f2c package and fail if that is not located.
1 parent 52fc55d commit 3f2dbef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+4889
-2199
lines changed

CBLAS/CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
find_library(F2C f2c)
2+
if (NOT F2C)
3+
message(FATAL_ERROR "f2c required. It is available at http://www.netlib.org/f2c/index.html ")
4+
endif()
15
set(headers
26
f2c.h
37
slu_Cnames.h
@@ -79,4 +83,6 @@ set(sources "")
7983
)
8084
#endif()
8185

82-
add_library(blas ${sources} ${HEADERS})
86+
#This must be compiled as a static library
87+
add_library(blas STATIC ${sources} ${HEADERS})
88+
target_link_libraries(blas ${F2C} m)

CMakeLists.txt

+104-8
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,28 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
4949
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
5050
#----
5151

52+
enable_language(C)
53+
message("CMAKE_SHARED_LIBRARY_PREFIX - ${CMAKE_SHARED_LIBRARY_PREFIX}")
54+
message("CMAKE_SHARED_LIBRARY_SUFFIX - ${CMAKE_SHARED_LIBRARY_SUFFIX}")
55+
message("CMAKE_IMPORT_LIBRARY_PREFIX - ${CMAKE_IMPORT_LIBRARY_PREFIX}")
56+
message("CMAKE_IMPORT_LIBRARY_SUFFIX - ${CMAKE_IMPORT_LIBRARY_SUFFIX}")
57+
message("CMAKE_STATIC_LIBRARY_PREFIX - ${CMAKE_STATIC_LIBRARY_PREFIX}")
58+
message("CMAKE_STATIC_LIBRARY_SUFFIX - ${CMAKE_STATIC_LIBRARY_SUFFIX}")
59+
5260
if (BUILD_SHARED_LIBS)
5361
message("-- SuperLU will be built as a shared library.")
54-
set(PROJECT_NAME_LIB_EXPORT libsuperlu.so)
62+
if (WIN32 OR CYGWIN OR MSYS)
63+
# In Windows, you link to an associated import library, not directly to the shared library runtime (.dll)
64+
set(PROJECT_NAME_LIB_EXPORT ${CMAKE_IMPORT_LIBRARY_PREFIX}superlu${CMAKE_IMPORT_LIBRARY_SUFFIX})
65+
else()
66+
set(PROJECT_NAME_LIB_EXPORT ${CMAKE_SHARED_LIBRARY_PREFIX}superlu${CMAKE_SHARED_LIBRARY_SUFFIX})
67+
endif()
5568
else()
5669
message("-- SuperLU will be built as a static library.")
57-
set(PROJECT_NAME_LIB_EXPORT libsuperlu.a)
70+
set(PROJECT_NAME_LIB_EXPORT ${CMAKE_STATIC_LIBRARY_PREFIX}superlu${CMAKE_STATIC_LIBRARY_SUFFIX})
5871
endif()
5972

60-
enable_language(C)
73+
6174
if (XSDK_ENABLE_Fortran)
6275
enable_language (Fortran)
6376
set(NOFORTRAN FALSE)
@@ -77,10 +90,12 @@ if (NOT CMAKE_INSTALL_PREFIX)
7790
endif()
7891

7992
# setup options
80-
option(enable_blaslib "Build the CBLAS library" ${enable_blaslib_DEFAULT})
93+
option(enable_blaslib "Build the CBLAS library (requires f2c)" ${enable_blaslib_DEFAULT})
8194
option(enable_matlabmex "Build the Matlab mex library" OFF)
8295
option(enable_tests "Build tests" ON)
8396
option(enable_doc "Build doxygen documentation" OFF)
97+
option(enable_doc_html "Build HTML documentation" OFF)
98+
option(enable_doc_man "Build Unix man pages" OFF)
8499
option(enable_single "Enable single precision library" ON)
85100
option(enable_double "Enable double precision library" ON)
86101
option(enable_complex "Enable complex precision library" ON)
@@ -124,12 +139,26 @@ else()
124139
add_subdirectory(CBLAS)
125140
set(BLAS_LIB blas)
126141
if (BUILD_SHARED_LIBS) # export to be referenced by downstream makefile
127-
set(BLAS_LIB_EXPORT ${CMAKE_INSTALL_PREFIX}/CBLAS/libblas.so)
128-
else()
129-
set(BLAS_LIB_EXPORT ${CMAKE_INSTALL_PREFIX}/CBLAS/libblas.a)
142+
#This must always be a static library.
143+
set(BLAS_LIB_EXPORT ${CMAKE_INSTALL_PREFIX}/CBLAS/${CMAKE_STATIC_LIBRARY_PREFIX}blas${CMAKE_STATIC_LIBRARY_SUFFIX})
130144
endif()
131145
endif()
132146

147+
######################################################################
148+
#
149+
# TMGLIB_EXPORT value
150+
#
151+
######################################################################
152+
if (BUILD_SHARED_LIBS) # export to be referenced by downstream makefile
153+
if (WIN32 OR CYGWIN OR MSYS)
154+
# In Windows, you link to an associated import library, not directly to the shared library runtime (.dll)
155+
set(TMGLIB_EXPORT ${CMAKE_IMPORT_LIBRARY_PREFIX}tmglib${CMAKE_IMPORT_LIBRARY_SUFFIX})
156+
else()
157+
set(TMGLIB_EXPORT ${CMAKE_SHARED_LIBRARY_PREFIX}tmglib${CMAKE_SHARED_LIBRARY_SUFFIX})
158+
endif()
159+
else()
160+
set(TMGLIB_EXPORT ${CMAKE_STATIC_LIBRARY_PREFIX}tmglib${CMAKE_STATIC_LIBRARY_SUFFIX})
161+
endif()
133162

134163
######################################################################
135164
#
@@ -157,14 +186,81 @@ if(enable_tests)
157186
endif()
158187

159188
if(enable_doc)
160-
message(FATAL_ERROR "Documentation build requested but not implemented.")
189+
# message(FATAL_ERROR "Documentation build requested but not implemented.")
161190
#implement doxygen
191+
192+
# check if Doxygen is installed
193+
find_package(Doxygen)
194+
if (DOXYGEN_FOUND)
195+
include(GNUInstallDirs)
196+
message(STATUS "doxygen ${DOXYGEN_EXECUTABLE}")
197+
message(STATUS "doxygen version ${DOXYGEN_VERSION}")
198+
#based from: https://vicrucann.github.io/tutorials/quick-cmake-doxygen/
199+
# set input and output files
200+
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
201+
if(DOXYGEN_DOT_FOUND)
202+
set(HAVE_DOT "YES")
203+
set(DOT_EXECUTABLE ${DOXYGEN_DOT_EXECUTABLE})
204+
message(STATUS "Graphviz (dot) ${DOXYGEN_DOT_EXECUTABLE}")
205+
else()
206+
set(HAVE_DOT "NO")
207+
unset(DOT_EXECUTABLE)
208+
message(STATUS "Graphviz (dot) Not Found")
209+
endif(DOXYGEN_DOT_FOUND)
210+
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
211+
212+
# Optional - use mscgen
213+
find_program(MSCGEN mscgen)
214+
if(MSCGEN)
215+
message(STATUS "mscgen ${MSCGEN}")
216+
# Doxygen will use this dir to find mscgen
217+
get_filename_component(MSCGEN_PATH ${MSCGEN} DIRECTORY)
218+
else()
219+
message(STATUS "mscgen Not Found")
220+
unset(MSCGEN_PATH)
221+
endif(MSCGEN)
222+
# Optional - use dia
223+
find_program(DIA dia)
224+
if(DIA)
225+
message(STATUS "dia ${DIA}")
226+
# Doxygen will use this dir to find mscgen
227+
get_filename_component(DIA_PATH ${DIA} DIRECTORY)
228+
else()
229+
message(STATUS "dia Not Found")
230+
unset(DIA_PATH)
231+
endif(DIA)
232+
# note the option ALL which allows to build the docs together with the application
233+
# We want to set up the docs in HTML format and the option for it in these conditionals
234+
if(enable_doc_html)
235+
set(d_enable_doc_html "YES")
236+
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc_doxygen/html DESTINATION ${CMAKE_INSTALL_DOCDIR})
237+
else()
238+
set(d_enable_doc_html "NO")
239+
endif(enable_doc_html)
240+
if(enable_doc_man)
241+
set(d_enable_doc_man "YES")
242+
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc_doxygen/man/ DESTINATION ${CMAKE_INSTALL_MANDIR})
243+
else()
244+
set(d_enable_doc_man "NO")
245+
endif(enable_doc_man)
246+
# request to configure the file
247+
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
248+
add_custom_target( doc_doxygen ALL
249+
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
250+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
251+
COMMENT "Generating API documentation with Doxygen"
252+
VERBATIM )
253+
else (DOXYGEN_FOUND)
254+
message("Doxygen need to be installed to generate the doxygen documentation")
255+
endif (DOXYGEN_FOUND)
162256
endif()
163257

164258
# file(WRITE "make.defs" "# can be exposed to users"
165259
# ${CMAKE_C_COMPILER} )
166260
# configure_file(${CMAKE_SOURCE_DIR}/make.inc.in ${CMAKE_SOURCE_DIR}/make.inc)
167261
configure_file(${SuperLU_SOURCE_DIR}/make.inc.in ${SuperLU_SOURCE_DIR}/make.inc)
262+
# This is just here in case people compile the same code for different sitatuions.
263+
file(COPY ${SuperLU_SOURCE_DIR}/make.inc DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
168264

169265
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/superlu.pc.in ${CMAKE_CURRENT_BINARY_DIR}/superlu.pc @ONLY)
170266
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/superlu.pc

0 commit comments

Comments
 (0)