Merge branch 'upstream' into tizen
[platform/upstream/harfbuzz.git] / CMakeLists.txt
1 cmake_minimum_required(VERSION 2.8.0)
2 project(harfbuzz)
3
4 ## Disallow in-source builds
5 if ("${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
6   message(FATAL_ERROR
7     "
8 In-source builds are not permitted!  Make a separate folder for"
9     " building, e.g.,"
10     "
11   mkdir build; cd build; cmake .."
12     "
13 Before that, remove the files created by this failed run with"
14     "
15   rm -rf CMakeCache.txt CMakeFiles")
16 endif ()
17 ##
18
19 ## HarfBuzz build configurations
20 option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
21 option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
22 option(HB_BUILTIN_UCDN "Use HarfBuzz provided UCDN" ON)
23 option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
24 option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
25 if (APPLE)
26   option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
27 endif ()
28 if (WIN32)
29   option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
30   option(HB_HAVE_DIRECWRITE "Enable DirectWrite shaper backend on Windows" OFF)
31 endif ()
32 option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
33 if (HB_BUILD_UTILS)
34   set(HB_HAVE_GLIB ON)
35   set(HB_HAVE_FREETYPE ON)
36 endif ()
37
38 include_directories(AFTER
39   ${PROJECT_SOURCE_DIR}/src
40   ${PROJECT_BINARY_DIR}/src
41   )
42
43 add_definitions(-DHAVE_OT)
44
45 if (BUILD_SHARED_LIBS)
46   add_definitions(-DHAVE_ATEXIT)
47 endif ()
48
49 if (MSVC)
50   add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
51 endif ()
52
53 if (WIN32 AND NOT MINGW AND BUILD_SHARED_LIBS)
54   add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
55 endif ()
56 ##
57
58 set(IN_HB_DIST FALSE)
59 if (EXISTS "${PROJECT_SOURCE_DIR}/src/hb-version.h")
60   # perhaps we are on dist directory
61   set(IN_HB_DIST TRUE)
62   set(HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
63 endif ()
64
65 ## Extract variables from Makefile files
66 # http://stackoverflow.com/a/27630120/1414809
67 function (prepend var prefix)
68   set(listVar "")
69   foreach (f ${ARGN})
70     list(APPEND listVar "${prefix}${f}")
71   endforeach ()
72   set(${var} "${listVar}" PARENT_SCOPE)
73 endfunction ()
74
75 function (extract_make_variable variable file prefix)
76   string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${file})
77   string(REGEX MATCHALL "[^ \n\t\\]+" list ${CMAKE_MATCH_1})
78   prepend(list ${prefix} ${list})
79   set(${variable} ${list} PARENT_SCOPE)
80 endfunction ()
81
82 file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
83 file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
84 file(READ ${PROJECT_SOURCE_DIR}/src/hb-ucdn/Makefile.sources UCDNSOURCES)
85
86 extract_make_variable(HB_BASE_sources ${SRCSOURCES} "${PROJECT_SOURCE_DIR}/src/")
87 extract_make_variable(HB_BASE_headers ${SRCSOURCES} "${PROJECT_SOURCE_DIR}/src/")
88 extract_make_variable(HB_OT_sources ${SRCSOURCES} "${PROJECT_SOURCE_DIR}/src/")
89 extract_make_variable(HB_OT_headers ${SRCSOURCES} "${PROJECT_SOURCE_DIR}/src/")
90
91 if (IN_HB_DIST)
92   set(RAGEL_GENERATED_DIR "${PROJECT_SOURCE_DIR}/src/")
93 else ()
94   set(RAGEL_GENERATED_DIR "${PROJECT_BINARY_DIR}/src/")
95 endif ()
96 extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES} ${RAGEL_GENERATED_DIR})
97 extract_make_variable(HB_OT_RAGEL_GENERATED_sources ${SRCSOURCES} ${RAGEL_GENERATED_DIR})
98
99 extract_make_variable(HB_VIEW_sources ${UTILSOURCES} "${PROJECT_SOURCE_DIR}/util/")
100 extract_make_variable(HB_SHAPE_sources ${UTILSOURCES} "${PROJECT_SOURCE_DIR}/util/")
101 extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES} "${PROJECT_SOURCE_DIR}/util/")
102
103 extract_make_variable(LIBHB_UCDN_sources ${UCDNSOURCES} "${PROJECT_SOURCE_DIR}/src/hb-ucdn/")
104
105 file(READ configure.ac CONFIGUREAC)
106 string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
107 set(HB_VERSION ${CMAKE_MATCH_1})
108 set(HB_VERSION_MAJOR ${CMAKE_MATCH_2})
109 set(HB_VERSION_MINOR ${CMAKE_MATCH_3})
110 set(HB_VERSION_MICRO ${CMAKE_MATCH_4})
111 ##
112
113 if (NOT IN_HB_DIST)
114   ## Define ragel tasks
115   find_program(RAGEL "ragel")
116
117   if (RAGEL)
118     message(STATUS "ragel found at: ${RAGEL}")
119   else ()
120     message(FATAL_ERROR "ragel not found, get it here -- http://www.complang.org/ragel/ or, use harfbuzz releases https://github.com/behdad/harfbuzz/releases")
121   endif ()
122
123   foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources} ${HB_OT_RAGEL_GENERATED_sources})
124     string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
125     set(target_name ${CMAKE_MATCH_1})
126     add_custom_command(OUTPUT ${ragel_output}
127       COMMAND ${RAGEL} -G2 -o ${ragel_output} ${PROJECT_SOURCE_DIR}/src/${target_name}.rl -I ${PROJECT_SOURCE_DIR} ${ARGN}
128       DEPENDS ${PROJECT_SOURCE_DIR}/src/${target_name}.rl
129       )
130     add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
131   endforeach ()
132
133   mark_as_advanced(RAGEL)
134   ##
135
136   ## Generate hb-version.h
137   set(HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
138   set(HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
139   set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
140   configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
141   execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
142     "${HB_VERSION_H}.tmp"
143     "${HB_VERSION_H}")
144   file(REMOVE "${HB_VERSION_H}.tmp")
145   ##
146 endif ()
147
148 ## Define sources and headers of the project
149 set(project_sources
150   ${HB_BASE_sources}
151   ${HB_BASE_RAGEL_GENERATED_sources}
152
153   ${HB_OT_sources}
154   ${HB_OT_RAGEL_GENERATED_sources}
155   )
156
157 set(project_headers
158   ${HB_VERSION_H}
159
160   ${HB_BASE_headers}
161   ${HB_OT_headers}
162   )
163
164 if (HB_HAVE_FREETYPE)
165   add_definitions(-DHAVE_FREETYPE=1 -DHAVE_FT_FACE_GETCHARVARIANTINDEX=1)
166
167   # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindFreetype2.cmake
168   find_package(PkgConfig)
169   pkg_check_modules(PC_FREETYPE2 QUIET freetype2)
170
171   find_path(FREETYPE2_HEADER_DIR NAMES freetype.h HINTS ${PC_FREETYPE2_INCLUDE_DIRS} ${PC_FREETYPE2_INCLUDEDIR} $ENV{FREETYPE_DIR}/include PATH_SUFFIXES freetype)
172   find_path(FREETYPE2_ROOT_INCLUDE_DIR NAMES freetype/freetype.h HINTS ${PC_FREETYPE2_INCLUDE_DIRS} ${PC_FREETYPE2_INCLUDEDIR} $ENV{FREETYPE_DIR}/include)
173   if (CMAKE_BUILD_TYPE MATCHES Debug)
174     set(FREETYPE2_LIBRARY_NAME freetyped)
175   else ()
176     set(FREETYPE2_LIBRARY_NAME freetype)
177   endif ()
178   find_library(FREETYPE2_LIBRARIES ${FREETYPE2_LIBRARY_NAME} HINTS ${PC_FREETYPE2_LIBDIR} ${PC_FREETYPE2_LIBRARY_DIRS} $ENV{FREETYPE_DIR}/lib)
179
180   include_directories(AFTER ${FREETYPE2_HEADER_DIR} ${FREETYPE2_ROOT_INCLUDE_DIR})
181
182   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
183   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
184
185   list(APPEND THIRD_PARTY_LIBS ${FREETYPE2_LIBRARIES})
186
187   mark_as_advanced(FREETYPE2_HEADER_DIR FREETYPE2_ROOT_INCLUDE_DIR FREETYPE2_LIBRARIES)
188 endif ()
189
190 if (HB_HAVE_GRAPHITE2)
191   add_definitions(-DHAVE_GRAPHITE2)
192
193   find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h)
194   find_library(GRAPHITE2_LIBRARY graphite2)
195
196   include_directories(${GRAPHITE2_INCLUDE_DIR})
197
198   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-graphite2.cc)
199   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
200
201   list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
202
203   mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
204 endif ()
205
206 if (HB_BUILTIN_UCDN)
207   include_directories(src/hb-ucdn)
208   add_definitions(-DHAVE_UCDN)
209
210   list(APPEND project_sources
211     ${PROJECT_SOURCE_DIR}/src/hb-ucdn.cc
212     ${LIBHB_UCDN_sources})
213 endif ()
214
215 if (HB_HAVE_GLIB)
216   add_definitions(-DHAVE_GLIB)
217
218   # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake
219   find_package(PkgConfig)
220   pkg_check_modules(PC_GLIB QUIET glib-2.0)
221
222   find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
223   find_path(GLIBCONFIG_INCLUDE_DIR NAMES glibconfig.h HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0/include)
224   find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
225
226   include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
227
228   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-glib.cc)
229   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
230
231   list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
232
233   mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
234 endif ()
235
236 if (HB_HAVE_ICU)
237   add_definitions(-DHAVE_ICU)
238
239   # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindICU.cmake
240   find_package(PkgConfig)
241   pkg_check_modules(PC_ICU QUIET icu-uc)
242
243   find_path(ICU_INCLUDE_DIR NAMES unicode/utypes.h HINTS ${PC_ICU_INCLUDE_DIRS} ${PC_ICU_INCLUDEDIR})
244   find_library(ICU_LIBRARY NAMES libicuuc cygicuuc cygicuuc32 icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR})
245
246   include_directories(${ICU_INCLUDE_DIR})
247
248   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-icu.cc)
249   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
250
251   list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
252
253   mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY)
254 endif ()
255
256 if (APPLE AND HB_HAVE_CORETEXT)
257   # Apple Advanced Typography
258   add_definitions(-DHAVE_CORETEXT)
259
260   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
261   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
262
263   find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
264   if (APPLICATION_SERVICES_FRAMEWORK)
265     list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
266   endif (APPLICATION_SERVICES_FRAMEWORK)
267   
268   mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
269 endif ()
270
271 if (WIN32 AND HB_HAVE_UNISCRIBE)
272   add_definitions(-DHAVE_UNISCRIBE)
273
274   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.cc)
275   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
276
277   list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
278 endif ()
279
280 if (WIN32 AND HB_HAVE_DIRECTWRITE)
281   add_definitions(-DHAVE_DIRECTWRITE)
282
283   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-directwrite.cc)
284   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
285
286   list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
287 endif ()
288 ##
289
290 ## Atomic ops availability detection
291 file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
292 "               void memory_barrier (void) { __sync_synchronize (); }
293                 int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
294                 int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
295                 void mutex_unlock (int *m) { __sync_lock_release (m); }
296                 int main () { return 0; }
297 ")
298 try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES
299   ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives
300   SOURCES ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c)
301 if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES)
302   add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES)
303 endif ()
304
305 file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c"
306 "               #include <atomic.h>
307                 /* This requires Solaris Studio 12.2 or newer: */
308                 #include <mbarrier.h>
309                 void memory_barrier (void) { __machine_rw_barrier (); }
310                 int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
311                 void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
312                 int main () { return 0; }
313 ")
314 try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS
315   ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops
316   SOURCES ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c)
317 if (HB_HAVE_SOLARIS_ATOMIC_OPS)
318   add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS)
319 endif ()
320 ##
321
322 add_library(harfbuzz ${project_sources} ${project_headers})
323 target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
324
325 if (HB_BUILD_UTILS)
326   # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake
327   find_package(PkgConfig)
328   pkg_check_modules(PC_CAIRO QUIET cairo)
329
330   find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo)
331   find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS})
332
333   add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
334   add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
335   include_directories(${CAIRO_INCLUDE_DIRS})
336
337   add_executable(hb-view ${HB_VIEW_sources})
338   target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES})
339
340   add_executable(hb-shape ${HB_SHAPE_sources})
341   target_link_libraries(hb-shape harfbuzz)
342
343   add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources})
344   target_link_libraries(hb-ot-shape-closure harfbuzz)
345
346   mark_as_advanced(CAIRO_LIBRARIESNAMES)
347 endif ()
348
349 ## Install
350 if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
351   install(FILES ${project_headers} DESTINATION include/harfbuzz)
352 endif ()
353
354 if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
355   install(TARGETS harfbuzz
356     ARCHIVE DESTINATION lib
357     LIBRARY DESTINATION lib
358     RUNTIME DESTINATION bin
359     )
360 endif ()
361 ##