2 ## Author: Hank Anderson <hank@statease.com>
5 cmake_minimum_required(VERSION 2.8.5)
6 project(OpenBLAS C ASM)
7 set(OpenBLAS_MAJOR_VERSION 0)
8 set(OpenBLAS_MINOR_VERSION 3)
9 set(OpenBLAS_PATCH_VERSION 3.dev)
10 set(OpenBLAS_VERSION "${OpenBLAS_MAJOR_VERSION}.${OpenBLAS_MINOR_VERSION}.${OpenBLAS_PATCH_VERSION}")
12 # Adhere to GNU filesystem layout conventions
13 include(GNUInstallDirs)
15 include(CMakePackageConfigHelpers)
18 set(OpenBLAS_LIBNAME openblas)
22 option(BUILD_WITHOUT_LAPACK "Without LAPACK and LAPACKE (Only BLAS or CBLAS)" ON)
24 option(BUILD_WITHOUT_CBLAS "Without CBLAS" OFF)
25 option(DYNAMIC_ARCH "Build with DYNAMIC_ARCH" OFF)
26 option(DYNAMIC_OLDER "Support older cpus with DYNAMIC_ARCH" OFF)
27 option(BUILD_RELAPACK "Build with ReLAPACK (recursive LAPACK" OFF)
29 if(BUILD_WITHOUT_LAPACK)
34 if(BUILD_WITHOUT_CBLAS)
41 message(WARNING "CMake support is experimental. This will not produce the same Makefiles that OpenBLAS ships with. Only x86 support is currently available.")
43 include("${PROJECT_SOURCE_DIR}/cmake/utils.cmake")
44 include("${PROJECT_SOURCE_DIR}/cmake/system.cmake")
46 set(BLASDIRS interface driver/level2 driver/level3 driver/others)
49 list(APPEND BLASDIRS kernel)
52 if (DEFINED SANITY_CHECK)
53 list(APPEND BLASDIRS reference)
56 set(SUBDIRS ${BLASDIRS})
58 list(APPEND SUBDIRS lapack)
60 list(APPEND SUBDIRS relapack/src)
64 # set which float types we want to build for
65 if (NOT DEFINED BUILD_SINGLE AND NOT DEFINED BUILD_DOUBLE AND NOT DEFINED BUILD_COMPLEX AND NOT DEFINED BUILD_COMPLEX16)
66 # if none are defined, build for all
67 set(BUILD_SINGLE true)
68 set(BUILD_DOUBLE true)
69 set(BUILD_COMPLEX true)
70 set(BUILD_COMPLEX16 true)
73 if (NOT DEFINED BUILD_MATGEN)
74 set(BUILD_MATGEN true)
79 message(STATUS "Building Single Precision")
80 list(APPEND FLOAT_TYPES "SINGLE") # defines nothing
84 message(STATUS "Building Double Precision")
85 list(APPEND FLOAT_TYPES "DOUBLE") # defines DOUBLE
89 message(STATUS "Building Complex Precision")
90 list(APPEND FLOAT_TYPES "COMPLEX") # defines COMPLEX
94 message(STATUS "Building Double Complex Precision")
95 list(APPEND FLOAT_TYPES "ZCOMPLEX") # defines COMPLEX and DOUBLE
98 if (NOT DEFINED CORE OR "${CORE}" STREQUAL "UNKNOWN")
99 message(FATAL_ERROR "Detecting CPU failed. Please set TARGET explicitly, e.g. make TARGET=your_cpu_target. Please read README for details.")
102 #Set default output directory
103 set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
104 set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
106 set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/lib/Debug)
107 set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/lib/Release)
109 # get obj vars into format that add_library likes: $<TARGET_OBJS:objlib> (see http://www.cmake.org/cmake/help/v3.0/command/add_library.html)
111 foreach (SUBDIR ${SUBDIRS})
112 add_subdirectory(${SUBDIR})
113 string(REPLACE "/" "_" subdir_obj ${SUBDIR})
114 list(APPEND TARGET_OBJS "$<TARGET_OBJECTS:${subdir_obj}>")
119 # Can't just use lapack-netlib's CMake files, since they are set up to search for BLAS, build and install a binary. We just want to build a couple of lib files out of lapack and lapacke.
120 # Not using add_subdirectory here because lapack-netlib already has its own CMakeLists.txt. Instead include a cmake script with the sources we want.
121 if (NOT NOFORTRAN AND NOT NO_LAPACK)
122 include("${PROJECT_SOURCE_DIR}/cmake/lapack.cmake")
124 include("${PROJECT_SOURCE_DIR}/cmake/lapacke.cmake")
128 # Only generate .def for dll on MSVC and always produce pdb files for debug and release
130 if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.4)
131 set(OpenBLAS_DEF_FILE "${PROJECT_BINARY_DIR}/openblas.def")
133 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
134 set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
138 add_subdirectory(kernel)
139 foreach(TARGET_CORE ${DYNAMIC_CORE})
140 message("${TARGET_CORE}")
141 list(APPEND TARGET_OBJS "$<TARGET_OBJECTS:kernel_${TARGET_CORE}>")
145 # Only build shared libs for MSVC
147 set(BUILD_SHARED_LIBS ON)
151 # add objects to the openblas lib
152 add_library(${OpenBLAS_LIBNAME} ${LA_SOURCES} ${LAPACKE_SOURCES} ${RELA_SOURCES} ${TARGET_OBJS} ${OpenBLAS_DEF_FILE})
153 target_include_directories(${OpenBLAS_LIBNAME} INTERFACE $<INSTALL_INTERFACE:include>)
155 # Android needs to explicitly link against libm
157 target_link_libraries(${OpenBLAS_LIBNAME} m)
160 # Handle MSVC exports
161 if(MSVC AND BUILD_SHARED_LIBS)
162 if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.4)
163 include("${PROJECT_SOURCE_DIR}/cmake/export.cmake")
165 # Creates verbose .def file (51KB vs 18KB)
166 set_target_properties(${OpenBLAS_LIBNAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS true)
170 # Set output for libopenblas
171 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
172 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES LIBRARY_OUTPUT_NAME_DEBUG "${OpenBLAS_LIBNAME}_d")
173 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES EXPORT_NAME "OpenBLAS")
175 foreach (OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
176 string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
178 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_BINARY_DIR}/lib/${OUTPUTCONFIG} )
179 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_BINARY_DIR}/lib/${OUTPUTCONFIG} )
180 set_target_properties( ${OpenBLAS_LIBNAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_BINARY_DIR}/lib/${OUTPUTCONFIG} )
186 # Add threading library to linker
187 find_package(Threads)
188 if (THREADS_HAVE_PTHREAD_ARG)
189 set_property(TARGET ${OpenBLAS_LIBNAME} PROPERTY COMPILE_OPTIONS "-pthread")
190 set_property(TARGET ${OpenBLAS_LIBNAME} PROPERTY INTERFACE_COMPILE_OPTIONS "-pthread")
192 target_link_libraries(${OpenBLAS_LIBNAME} ${CMAKE_THREAD_LIBS_INIT})
195 if (MSVC OR NOT NOFORTRAN)
196 # Broken without fortran on unix
197 add_subdirectory(utest)
200 if (NOT MSVC AND NOT NOFORTRAN)
201 # Build test and ctest
202 add_subdirectory(test)
204 add_subdirectory(ctest)
208 set_target_properties(${OpenBLAS_LIBNAME} PROPERTIES
209 VERSION ${OpenBLAS_MAJOR_VERSION}.${OpenBLAS_MINOR_VERSION}
210 SOVERSION ${OpenBLAS_MAJOR_VERSION}
216 install(TARGETS ${OpenBLAS_LIBNAME}
217 EXPORT "OpenBLASTargets"
218 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
219 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
220 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
222 message(STATUS "Generating openblas_config.h in ${CMAKE_INSTALL_INCLUDEDIR}")
224 set(OPENBLAS_CONFIG_H ${CMAKE_BINARY_DIR}/openblas_config.h)
225 file(WRITE ${OPENBLAS_CONFIG_H} "#ifndef OPENBLAS_CONFIG_H\n")
226 file(APPEND ${OPENBLAS_CONFIG_H} "#define OPENBLAS_CONFIG_H\n")
227 file(STRINGS ${PROJECT_BINARY_DIR}/config.h __lines)
228 foreach(line ${__lines})
229 string(REPLACE "#define " "" line ${line})
230 file(APPEND ${OPENBLAS_CONFIG_H} "#define OPENBLAS_${line}\n")
232 file(APPEND ${OPENBLAS_CONFIG_H} "#define OPENBLAS_VERSION \"OpenBLAS ${OpenBLAS_VERSION}\"\n")
233 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/openblas_config_template.h OPENBLAS_CONFIG_TEMPLATE_H_CONTENTS)
234 file(APPEND ${OPENBLAS_CONFIG_H} "${OPENBLAS_CONFIG_TEMPLATE_H_CONTENTS}\n")
235 file(APPEND ${OPENBLAS_CONFIG_H} "#endif /* OPENBLAS_CONFIG_H */\n")
236 install (FILES ${OPENBLAS_CONFIG_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
239 message(STATUS "Generating f77blas.h in ${CMAKE_INSTALL_INCLUDEDIR}")
241 set(F77BLAS_H ${CMAKE_BINARY_DIR}/f77blas.h)
242 file(WRITE ${F77BLAS_H} "#ifndef OPENBLAS_F77BLAS_H\n")
243 file(APPEND ${F77BLAS_H} "#define OPENBLAS_F77BLAS_H\n")
244 file(APPEND ${F77BLAS_H} "#include \"openblas_config.h\"\n")
245 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/common_interface.h COMMON_INTERFACE_H_CONTENTS)
246 file(APPEND ${F77BLAS_H} "${COMMON_INTERFACE_H_CONTENTS}\n")
247 file(APPEND ${F77BLAS_H} "#endif")
248 install (FILES ${F77BLAS_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
252 message (STATUS "Generating cblas.h in ${CMAKE_INSTALL_INCLUDEDIR}")
254 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cblas.h CBLAS_H_CONTENTS)
255 string(REPLACE "common" "openblas_config" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
256 file(WRITE ${CMAKE_BINARY_DIR}/cblas.tmp "${CBLAS_H_CONTENTS_NEW}")
257 install (FILES ${CMAKE_BINARY_DIR}/cblas.tmp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} RENAME cblas.h)
261 message (STATUS "Copying LAPACKE header files to ${CMAKE_INSTALL_INCLUDEDIR}")
262 add_dependencies( ${OpenBLAS_LIBNAME} genlapacke)
263 FILE(GLOB_RECURSE INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/lapack-netlib/LAPACKE/*.h")
264 install (FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
266 ADD_CUSTOM_TARGET(genlapacke
267 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/lapack-netlib/LAPACKE/include/lapacke_mangling_with_flags.h.in "${CMAKE_BINARY_DIR}/lapacke_mangling.h"
269 install (FILES ${CMAKE_BINARY_DIR}/lapacke_mangling.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
272 include(FindPkgConfig QUIET)
274 configure_file(${PROJECT_SOURCE_DIR}/cmake/openblas.pc.in ${PROJECT_BINARY_DIR}/openblas.pc @ONLY)
275 install (FILES ${PROJECT_BINARY_DIR}/openblas.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/)
279 # GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share".
281 set(CMAKECONFIG_INSTALL_DIR "share/cmake/${PN}")
282 configure_package_config_file(cmake/${PN}Config.cmake.in
283 "${CMAKE_CURRENT_BINARY_DIR}/${PN}Config.cmake"
284 INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR})
285 write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PN}ConfigVersion.cmake
286 VERSION ${${PN}_VERSION}
287 COMPATIBILITY AnyNewerVersion)
288 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PN}Config.cmake
289 ${CMAKE_CURRENT_BINARY_DIR}/${PN}ConfigVersion.cmake
290 DESTINATION ${CMAKECONFIG_INSTALL_DIR})
291 install(EXPORT "${PN}Targets"
293 DESTINATION ${CMAKECONFIG_INSTALL_DIR})