Rewrite the CMake build to use explicit dependencies between libraries,
[oota-llvm.git] / cmake / modules / LLVM-Config.cmake
1 function(get_system_libs return_var)
2   # Returns in `return_var' a list of system libraries used by LLVM.
3   if( NOT MSVC )
4     if( MINGW )
5       set(system_libs ${system_libs} imagehlp psapi)
6     elseif( CMAKE_HOST_UNIX )
7       if( HAVE_LIBDL )
8         set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
9       endif()
10       if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
11         set(system_libs ${system_libs} pthread)
12       endif()
13     endif( MINGW )
14   endif( NOT MSVC )
15   set(${return_var} ${system_libs} PARENT_SCOPE)
16 endfunction(get_system_libs)
17
18
19 function(link_system_libs target)
20   get_system_libs(llvm_system_libs)
21   target_link_libraries(${target} ${llvm_system_libs})
22 endfunction(link_system_libs)
23
24
25 function(is_llvm_target_library library return_var)
26   # Sets variable `return_var' to ON if `library' corresponds to a
27   # LLVM supported target. To OFF if it doesn't.
28   set(${return_var} OFF PARENT_SCOPE)
29   string(TOUPPER "${library}" capitalized_lib)
30   string(TOUPPER "${LLVM_ALL_TARGETS}" targets)
31   foreach(t ${targets})
32     if( capitalized_lib STREQUAL t OR
33         capitalized_lib STREQUAL "LLVM${t}" OR
34         capitalized_lib STREQUAL "LLVM${t}CODEGEN" OR
35         capitalized_lib STREQUAL "LLVM${t}ASMPARSER" OR
36         capitalized_lib STREQUAL "LLVM${t}ASMPRINTER" OR
37         capitalized_lib STREQUAL "LLVM${t}DISASSEMBLER" OR
38         capitalized_lib STREQUAL "LLVM${t}INFO" )
39       set(${return_var} ON PARENT_SCOPE)
40       break()
41     endif()
42   endforeach()
43 endfunction(is_llvm_target_library)
44
45
46 macro(llvm_config executable)
47   explicit_llvm_config(${executable} ${ARGN})
48 endmacro(llvm_config)
49
50
51 function(explicit_llvm_config executable)
52   set( link_components ${ARGN} )
53
54   explicit_map_components_to_libraries(LIBRARIES ${link_components})
55   target_link_libraries(${executable} ${LIBRARIES})
56 endfunction(explicit_llvm_config)
57
58
59 # This is a variant intended for the final user:
60 function(llvm_map_components_to_libraries OUT_VAR)
61   explicit_map_components_to_libraries(result ${ARGN})
62   get_system_libs(sys_result)
63   set( ${OUT_VAR} ${result} ${sys_result} PARENT_SCOPE )
64 endfunction(llvm_map_components_to_libraries)
65
66
67 function(explicit_map_components_to_libraries out_libs)
68   set( link_components ${ARGN} )
69   get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS)
70   string(TOUPPER "${llvm_libs}" capitalized_libs)
71
72   # Expand some keywords:
73   list(FIND LLVM_TARGETS_TO_BUILD "${LLVM_NATIVE_ARCH}" have_native_backend)
74   list(FIND link_components "engine" engine_required)
75   if( NOT engine_required EQUAL -1 )
76     list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" have_jit)
77     if( NOT have_native_backend EQUAL -1 AND NOT have_jit EQUAL -1 )
78       list(APPEND link_components "jit")
79       list(APPEND link_components "native")
80     else()
81       list(APPEND link_components "interpreter")
82     endif()
83   endif()
84   list(FIND link_components "native" native_required)
85   if( NOT native_required EQUAL -1 )
86     if( NOT have_native_backend EQUAL -1 )
87       list(APPEND link_components ${LLVM_NATIVE_ARCH})
88     endif()
89   endif()
90
91   # Translate symbolic component names to real libraries:
92   foreach(c ${link_components})
93     # add codegen, asmprinter, asmparser, disassembler
94     list(FIND LLVM_TARGETS_TO_BUILD ${c} idx)
95     if( NOT idx LESS 0 )
96       list(FIND llvm_libs "LLVM${c}CodeGen" idx)
97       if( NOT idx LESS 0 )
98         list(APPEND expanded_components "LLVM${c}CodeGen")
99       else()
100         list(FIND llvm_libs "LLVM${c}" idx)
101         if( NOT idx LESS 0 )
102           list(APPEND expanded_components "LLVM${c}")
103         else()
104           message(FATAL_ERROR "Target ${c} is not in the set of libraries.")
105         endif()
106       endif()
107       list(FIND llvm_libs "LLVM${c}AsmPrinter" asmidx)
108       if( NOT asmidx LESS 0 )
109         list(APPEND expanded_components "LLVM${c}AsmPrinter")
110       endif()
111       list(FIND llvm_libs "LLVM${c}AsmParser" asmidx)
112       if( NOT asmidx LESS 0 )
113         list(APPEND expanded_components "LLVM${c}AsmParser")
114       endif()
115       list(FIND llvm_libs "LLVM${c}Info" asmidx)
116       if( NOT asmidx LESS 0 )
117         list(APPEND expanded_components "LLVM${c}Info")
118       endif()
119       list(FIND llvm_libs "LLVM${c}Disassembler" asmidx)
120       if( NOT asmidx LESS 0 )
121         list(APPEND expanded_components "LLVM${c}Disassembler")
122       endif()
123     elseif( c STREQUAL "native" )
124       # already processed
125     elseif( c STREQUAL "nativecodegen" )
126       list(APPEND expanded_components "LLVM${LLVM_NATIVE_ARCH}CodeGen")
127     elseif( c STREQUAL "backend" )
128       # same case as in `native'.
129     elseif( c STREQUAL "engine" )
130       # already processed
131     elseif( c STREQUAL "all" )
132       list(APPEND expanded_components ${llvm_libs})
133     else( NOT idx LESS 0 )
134       # Canonize the component name:
135       string(TOUPPER "${c}" capitalized)
136       list(FIND capitalized_libs LLVM${capitalized} lib_idx)
137       if( lib_idx LESS 0 )
138         # The component is unknown. Maybe is an omitted target?
139         is_llvm_target_library(${c} iltl_result)
140         if( NOT iltl_result )
141           message(FATAL_ERROR "Library `${c}' not found in list of llvm libraries.")
142         endif()
143       else( lib_idx LESS 0 )
144         list(GET llvm_libs ${lib_idx} canonical_lib)
145         list(APPEND expanded_components ${canonical_lib})
146       endif( lib_idx LESS 0 )
147     endif( NOT idx LESS 0 )
148   endforeach(c)
149   # Expand dependencies while topologically sorting the list of libraries:
150   list(LENGTH expanded_components lst_size)
151   set(cursor 0)
152   set(processed)
153   while( cursor LESS lst_size )
154     list(GET expanded_components ${cursor} lib)
155     list(APPEND expanded_components ${LLVM_LIB_DEPS_${lib}})
156     # Remove duplicates at the front:
157     list(REVERSE expanded_components)
158     list(REMOVE_DUPLICATES expanded_components)
159     list(REVERSE expanded_components)
160     list(APPEND processed ${lib})
161     # Find the maximum index that doesn't have to be re-processed:
162     while(NOT "${expanded_components}" MATCHES "^${processed}.*" )
163       list(REMOVE_AT processed -1)
164     endwhile()
165     list(LENGTH processed cursor)
166     list(LENGTH expanded_components lst_size)
167   endwhile( cursor LESS lst_size )
168   # Return just the libraries included in this build:
169   set(result)
170   foreach(c ${expanded_components})
171     list(FIND llvm_libs ${c} lib_idx)
172     if( NOT lib_idx LESS 0 )
173       set(result ${result} ${c})
174     endif()
175   endforeach(c)
176   set(${out_libs} ${result} PARENT_SCOPE)
177 endfunction(explicit_map_components_to_libraries)