1#
2#//===----------------------------------------------------------------------===//
3#//
4#//                     The LLVM Compiler Infrastructure
5#//
6#// This file is dual licensed under the MIT and the University of Illinois Open
7#// Source Licenses. See LICENSE.txt for details.
8#//
9#//===----------------------------------------------------------------------===//
10#
11
12# Configure omp.h, kmp_config.h and ompt.h if necessary
13configure_file(${LIBOMP_INC_DIR}/omp.h.var omp.h @ONLY)
14configure_file(kmp_config.h.cmake kmp_config.h @ONLY)
15if(${LIBOMP_OMPT_SUPPORT})
16  configure_file(${LIBOMP_INC_DIR}/ompt.h.var ompt.h @ONLY)
17endif()
18
19# Generate message catalog files: kmp_i18n_id.inc and kmp_i18n_default.inc
20add_custom_command(
21  OUTPUT  kmp_i18n_id.inc
22  COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/message-converter.pl --os=${LIBOMP_PERL_SCRIPT_OS}
23    --prefix=kmp_i18n --enum=kmp_i18n_id.inc ${LIBOMP_SRC_DIR}/i18n/en_US.txt
24  DEPENDS ${LIBOMP_SRC_DIR}/i18n/en_US.txt ${LIBOMP_TOOLS_DIR}/message-converter.pl
25)
26add_custom_command(
27  OUTPUT  kmp_i18n_default.inc
28  COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/message-converter.pl --os=${LIBOMP_PERL_SCRIPT_OS}
29    --prefix=kmp_i18n --default=kmp_i18n_default.inc ${LIBOMP_SRC_DIR}/i18n/en_US.txt
30  DEPENDS ${LIBOMP_SRC_DIR}/i18n/en_US.txt ${LIBOMP_TOOLS_DIR}/message-converter.pl
31)
32
33# Set the -D definitions for all sources
34# UNICODE and _UNICODE are set in LLVM's CMake system.  They affect the
35# ittnotify code and should only be set when compiling ittnotify_static.c
36# on Windows (done below).
37# TODO: Fix the UNICODE usage in ittnotify code for Windows.
38remove_definitions(-DUNICODE -D_UNICODE)
39libomp_get_definitions_flags(LIBOMP_CONFIGURED_DEFINITIONS_FLAGS)
40add_definitions(${LIBOMP_CONFIGURED_DEFINITIONS_FLAGS})
41
42# Set the -I includes for all sources
43include_directories(
44  ${CMAKE_CURRENT_BINARY_DIR}
45  ${LIBOMP_SRC_DIR}
46  ${LIBOMP_SRC_DIR}/i18n
47  ${LIBOMP_INC_DIR}
48  ${LIBOMP_SRC_DIR}/thirdparty/ittnotify
49)
50if(${LIBOMP_USE_HWLOC})
51  include_directories(${LIBOMP_HWLOC_INSTALL_DIR}/include)
52endif()
53
54# Getting correct source files to build library
55set(LIBOMP_CFILES)
56set(LIBOMP_CXXFILES)
57set(LIBOMP_ASMFILES)
58if(${STUBS_LIBRARY})
59  set(LIBOMP_CFILES kmp_stub.cpp)
60else()
61  # Get C++ files
62  set(LIBOMP_CXXFILES
63    kmp_alloc.cpp
64    kmp_atomic.cpp
65    kmp_csupport.cpp
66    kmp_debug.cpp
67    kmp_itt.cpp
68    kmp_environment.cpp
69    kmp_error.cpp
70    kmp_global.cpp
71    kmp_i18n.cpp
72    kmp_io.cpp
73    kmp_runtime.cpp
74    kmp_settings.cpp
75    kmp_str.cpp
76    kmp_tasking.cpp
77    kmp_taskq.cpp
78    kmp_threadprivate.cpp
79    kmp_utility.cpp
80    kmp_barrier.cpp
81    kmp_wait_release.cpp
82    kmp_affinity.cpp
83    kmp_dispatch.cpp
84    kmp_lock.cpp
85    kmp_sched.cpp
86  )
87  if(WIN32)
88    # Windows specific files
89    libomp_append(LIBOMP_CXXFILES z_Windows_NT_util.cpp)
90    libomp_append(LIBOMP_CXXFILES z_Windows_NT-586_util.cpp)
91    libomp_append(LIBOMP_ASMFILES z_Windows_NT-586_asm.asm) # Windows assembly file
92  else()
93    # Unix specific files
94    libomp_append(LIBOMP_CXXFILES z_Linux_util.cpp)
95    libomp_append(LIBOMP_CXXFILES kmp_gsupport.cpp)
96    libomp_append(LIBOMP_ASMFILES z_Linux_asm.s) # Unix assembly file
97  endif()
98  libomp_append(LIBOMP_CFILES thirdparty/ittnotify/ittnotify_static.c LIBOMP_USE_ITT_NOTIFY)
99  libomp_append(LIBOMP_CXXFILES kmp_debugger.cpp LIBOMP_USE_DEBUGGER)
100  libomp_append(LIBOMP_CXXFILES kmp_stats.cpp LIBOMP_STATS)
101  libomp_append(LIBOMP_CXXFILES kmp_stats_timing.cpp LIBOMP_STATS)
102  if(${LIBOMP_OMP_VERSION} GREATER 40 OR ${LIBOMP_OMP_VERSION} EQUAL 40)
103    libomp_append(LIBOMP_CXXFILES kmp_taskdeps.cpp)
104    libomp_append(LIBOMP_CXXFILES kmp_cancel.cpp)
105  endif()
106endif()
107# Files common to stubs and normal library
108libomp_append(LIBOMP_CXXFILES kmp_ftn_cdecl.cpp)
109libomp_append(LIBOMP_CXXFILES kmp_ftn_extra.cpp)
110libomp_append(LIBOMP_CXXFILES kmp_version.cpp)
111libomp_append(LIBOMP_CXXFILES ompt-general.cpp IF_TRUE LIBOMP_OMPT_SUPPORT)
112libomp_append(LIBOMP_CXXFILES tsan_annotations.cpp IF_TRUE LIBOMP_TSAN_SUPPORT)
113
114set(LIBOMP_SOURCE_FILES ${LIBOMP_CFILES} ${LIBOMP_CXXFILES} ${LIBOMP_ASMFILES})
115# For Windows, there is a resource file (.rc -> .res) that is also compiled
116libomp_append(LIBOMP_SOURCE_FILES libomp.rc WIN32)
117
118# Get compiler and assembler flags
119libomp_get_cflags(LIBOMP_CONFIGURED_CFLAGS)
120libomp_get_cxxflags(LIBOMP_CONFIGURED_CXXFLAGS)
121libomp_get_asmflags(LIBOMP_CONFIGURED_ASMFLAGS)
122# Set the compiler flags for each type of source
123set_source_files_properties(${LIBOMP_CFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CFLAGS}")
124set_source_files_properties(${LIBOMP_CXXFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CXXFLAGS}")
125set_source_files_properties(${LIBOMP_ASMFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_ASMFLAGS}")
126# Let the compiler handle the assembly files on Unix-like systems
127if(NOT WIN32)
128  set_source_files_properties(${LIBOMP_ASMFILES} PROPERTIES LANGUAGE C)
129endif()
130
131# Remove any cmake-automatic linking of the standard C++ library.
132# We neither need (nor want) the standard C++ library dependency even though we compile c++ files.
133if(NOT ${LIBOMP_USE_STDCPPLIB})
134  set(LIBOMP_LINKER_LANGUAGE C)
135  set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES)
136else()
137  set(LIBOMP_LINKER_LANGUAGE CXX)
138endif()
139
140# Add the OpenMP library
141libomp_get_ldflags(LIBOMP_CONFIGURED_LDFLAGS)
142
143add_library(omp ${LIBOMP_LIBRARY_KIND} ${LIBOMP_SOURCE_FILES})
144
145set_target_properties(omp PROPERTIES
146  PREFIX "" SUFFIX "" OUTPUT_NAME "${LIBOMP_LIB_FILE}"
147  LINK_FLAGS "${LIBOMP_CONFIGURED_LDFLAGS}"
148  LINKER_LANGUAGE ${LIBOMP_LINKER_LANGUAGE}
149)
150
151# Get the library's location within the build tree for the unit tester
152if(NOT WIN32)
153  get_target_property(LIBOMP_LIBRARY_DIR omp LIBRARY_OUTPUT_DIRECTORY)
154else()
155  get_target_property(LIBOMP_LIBRARY_DIR omp RUNTIME_OUTPUT_DIRECTORY)
156endif()
157if(NOT LIBOMP_LIBRARY_DIR)
158  set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
159  set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
160else()
161  set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE)
162endif()
163
164# Add symbolic links to libomp
165if(NOT WIN32)
166  add_custom_command(TARGET omp POST_BUILD
167    COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
168      libgomp${LIBOMP_LIBRARY_SUFFIX}
169    COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
170      libiomp5${LIBOMP_LIBRARY_SUFFIX}
171    WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR}
172  )
173endif()
174
175# Linking command will include libraries in LIBOMP_CONFIGURED_LIBFLAGS
176libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
177target_link_libraries(omp ${LIBOMP_CONFIGURED_LIBFLAGS} ${CMAKE_DL_LIBS})
178
179# Create *.inc before compiling any sources
180# objects depend on : .inc files
181add_custom_target(libomp-needed-headers DEPENDS kmp_i18n_id.inc kmp_i18n_default.inc)
182add_dependencies(omp libomp-needed-headers)
183
184# Windows specific build rules
185if(WIN32)
186  configure_file(libomp.rc.var libomp.rc @ONLY)
187
188  # Create .def and .rc file before compiling any sources
189  add_custom_target(libomp-needed-windows-files DEPENDS ${LIBOMP_LIB_NAME}.def)
190  add_dependencies(omp libomp-needed-windows-files)
191  # z_Windows_NT-586_asm.asm requires definitions to be sent via command line
192  # It only needs the architecutre macro and OMPT_SUPPORT=0|1
193  libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_IA32" IF_TRUE IA32)
194  libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_AMD64" IF_TRUE INTEL64)
195  libomp_append(LIBOMP_MASM_DEFINITIONS "-DOMPT_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPT_SUPPORT)
196  libomp_list_to_string("${LIBOMP_MASM_DEFINITIONS}" LIBOMP_MASM_DEFINITIONS)
197  set_property(SOURCE z_Windows_NT-586_asm.asm APPEND_STRING PROPERTY COMPILE_FLAGS " ${LIBOMP_MASM_DEFINITIONS}")
198  set_source_files_properties(thirdparty/ittnotify/ittnotify_static.c PROPERTIES COMPILE_DEFINITIONS "UNICODE")
199
200  # Create Windows import library
201  # the import library is "re-linked" to include kmp_import.cpp which prevents
202  # linking of both Visual Studio OpenMP and newly built OpenMP
203  set_source_files_properties(kmp_import.cpp PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CFLAGS}")
204  set(LIBOMP_IMP_LIB_FILE ${LIBOMP_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
205  set(LIBOMP_GENERATED_IMP_LIB_FILENAME ${LIBOMP_LIB_FILE}${CMAKE_STATIC_LIBRARY_SUFFIX})
206  set_target_properties(omp PROPERTIES
207    VERSION ${LIBOMP_VERSION_MAJOR}.${LIBOMP_VERSION_MINOR} # uses /version flag
208    IMPORT_PREFIX "" IMPORT_SUFFIX "" # control generated import library name when building omp
209    ARCHIVE_OUTPUT_NAME ${LIBOMP_GENERATED_IMP_LIB_FILENAME}
210  )
211  # Get generated import library from creating omp
212  get_target_property(LIBOMP_IMPORT_LIB_DIRECTORY omp ARCHIVE_OUTPUT_DIRECTORY)
213  if(LIBOMP_IMPORT_LIB_DIRECTORY)
214    set(LIBOMP_GENERATED_IMP_LIB ${LIBOMP_IMPORT_LIB_DIRECTORY}/${LIBOMP_GENERATED_IMP_LIB_FILENAME})
215  else()
216    set(LIBOMP_GENERATED_IMP_LIB ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_GENERATED_IMP_LIB_FILENAME})
217  endif()
218  set_source_files_properties(${LIBOMP_GENERATED_IMP_LIB} PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
219  # Create new import library that is just the previously created one + kmp_import.cpp
220  add_library(ompimp STATIC ${LIBOMP_GENERATED_IMP_LIB} kmp_import.cpp)
221  set_target_properties(ompimp PROPERTIES
222    PREFIX "" SUFFIX "" OUTPUT_NAME "${LIBOMP_IMP_LIB_FILE}"
223    LINKER_LANGUAGE C
224  )
225  add_dependencies(ompimp omp) # ensure generated import library is created first
226
227  # Create def file to designate exported functions
228  libomp_get_gdflags(LIBOMP_GDFLAGS) # generate-def.pl flags (Windows only)
229  libomp_string_to_list("${LIBOMP_GDFLAGS}" LIBOMP_GDFLAGS)
230  add_custom_command(
231    OUTPUT  ${LIBOMP_LIB_NAME}.def
232    COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/generate-def.pl ${LIBOMP_GDFLAGS}
233      -o ${LIBOMP_LIB_NAME}.def ${CMAKE_CURRENT_SOURCE_DIR}/dllexports
234    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dllexports ${LIBOMP_TOOLS_DIR}/generate-def.pl
235  )
236endif()
237
238# Building the Fortran module files
239# One compilation step creates both omp_lib.mod and omp_lib_kinds.mod
240if(${LIBOMP_FORTRAN_MODULES})
241  configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY)
242  configure_file(${LIBOMP_INC_DIR}/omp_lib.f.var omp_lib.f @ONLY)
243  configure_file(${LIBOMP_INC_DIR}/omp_lib.f90.var omp_lib.f90 @ONLY)
244  add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod)
245  libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS)
246  if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
247    set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f90)
248  else()
249    set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f)
250  endif()
251  add_custom_command(
252    OUTPUT omp_lib.mod omp_lib_kinds.mod
253    COMMAND ${CMAKE_Fortran_COMPILER} -c ${LIBOMP_CONFIGURED_FFLAGS} ${LIBOMP_FORTRAN_SOURCE_FILE}
254    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}
255      ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
256  )
257  set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${CMAKE_C_OUTPUT_EXTENSION})
258endif()
259
260# Move files to exports/ directory if requested
261if(${LIBOMP_COPY_EXPORTS})
262  include(LibompExports)
263endif()
264
265# Micro test rules for after library has been built (cmake/LibompMicroTests.cmake)
266include(LibompMicroTests)
267add_custom_target(libomp-micro-tests)
268if(NOT ${MIC} AND NOT CMAKE_CROSSCOMPILING)
269  add_dependencies(libomp-micro-tests libomp-test-touch)
270endif()
271if(NOT WIN32 AND NOT APPLE)
272  add_dependencies(libomp-micro-tests libomp-test-relo)
273endif()
274if(NOT WIN32 AND NOT APPLE)
275  add_dependencies(libomp-micro-tests libomp-test-execstack)
276endif()
277if(${MIC})
278  add_dependencies(libomp-micro-tests libomp-test-instr)
279endif()
280add_dependencies(libomp-micro-tests libomp-test-deps)
281
282# Install rules
283# We want to install libomp in DESTDIR/CMAKE_INSTALL_PREFIX/lib
284# We want to install headers in DESTDIR/CMAKE_INSTALL_PREFIX/include
285if(${LIBOMP_STANDALONE_BUILD})
286  set(LIBOMP_HEADERS_INSTALL_PATH include)
287else()
288  string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION ${PACKAGE_VERSION})
289  set(LIBOMP_HEADERS_INSTALL_PATH lib${LIBOMP_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
290endif()
291if(WIN32)
292  install(TARGETS omp RUNTIME DESTINATION bin)
293  install(TARGETS ompimp ARCHIVE DESTINATION lib${LIBOMP_LIBDIR_SUFFIX})
294  # Create aliases (regular copies) of the library for backwards compatibility
295  set(LIBOMP_ALIASES "libiomp5md")
296  foreach(alias IN LISTS LIBOMP_ALIASES)
297    install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy \"${LIBOMP_LIB_FILE}\"
298      \"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}/bin)")
299    install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy \"${LIBOMP_IMP_LIB_FILE}\"
300      \"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}/lib${LIBOMP_LIBDIR_SUFFIX})")
301  endforeach()
302else()
303
304  install(TARGETS omp ${LIBOMP_INSTALL_KIND} DESTINATION lib${LIBOMP_LIBDIR_SUFFIX})
305
306  if(${LIBOMP_INSTALL_ALIASES})
307    # Create aliases (symlinks) of the library for backwards compatibility
308    set(LIBOMP_ALIASES "libgomp;libiomp5")
309    foreach(alias IN LISTS LIBOMP_ALIASES)
310      install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink \"${LIBOMP_LIB_FILE}\"
311        \"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY
312        \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib${LIBOMP_LIBDIR_SUFFIX})")
313    endforeach()
314  endif()
315endif()
316install(
317  FILES
318  ${CMAKE_CURRENT_BINARY_DIR}/omp.h
319  DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH}
320)
321if(${LIBOMP_OMPT_SUPPORT})
322  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ompt.h DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH})
323endif()
324if(${LIBOMP_FORTRAN_MODULES})
325  install(FILES
326    ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
327    ${CMAKE_CURRENT_BINARY_DIR}/omp_lib.mod
328    ${CMAKE_CURRENT_BINARY_DIR}/omp_lib_kinds.mod
329    DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH}
330  )
331endif()
332
333