1 cmake_minimum_required(VERSION 2.8.0)
6 ## Limit framework build to Xcode generator
8 # for a framework build on macOS, use:
9 # cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build
10 if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
12 "You should use Xcode generator with BUILD_FRAMEWORK enabled")
14 set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
15 set (CMAKE_MACOSX_RPATH ON)
16 set (BUILD_SHARED_LIBS ON)
20 ## Disallow in-source builds, as CMake generated make files can collide with autotools ones
21 if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
24 In-source builds are not permitted! Make a separate folder for"
27 mkdir build; cd build; cmake .."
29 Before that, remove the files created by this failed run with"
31 rm -rf CMakeCache.txt CMakeFiles")
35 ## HarfBuzz build configurations
36 option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
37 option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
38 option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
39 option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
41 option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
42 set (CMAKE_MACOSX_RPATH ON)
45 option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
46 option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
48 option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
51 set (HB_HAVE_FREETYPE ON)
54 option(HB_BUILD_SUBSET "Build harfbuzz-subset" ON)
55 option(HB_BUILD_TESTS "Build harfbuzz tests" ON)
57 option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF)
62 option(HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF)
63 if (HB_HAVE_INTROSPECTION)
64 set (HB_HAVE_GOBJECT ON)
68 option(HB_CHECK OFF "Do a configuration suitable for testing (shared library and enable all options)")
70 set (BUILD_SHARED_LIBS ON)
71 set (HB_BUILD_UTILS ON)
74 #set (HB_HAVE_GOBJECT ON)
75 #set (HB_HAVE_INTROSPECTION ON)
76 set (HB_HAVE_FREETYPE ON)
77 set (HB_HAVE_GRAPHITE2 ON)
79 set (HB_HAVE_UNISCRIBE ON)
80 set (HB_HAVE_DIRECTWRITE ON)
82 set (HB_HAVE_CORETEXT ON)
86 include_directories(AFTER
87 ${PROJECT_SOURCE_DIR}/src
88 ${PROJECT_BINARY_DIR}/src
91 # We need PYTHON_EXECUTABLE to be set for running the tests...
92 include (FindPythonInterp)
94 ## Functions and headers
95 include (CheckFunctionExists)
96 include (CheckIncludeFile)
97 macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
98 foreach (func_name ${ARGN})
99 string(TOUPPER ${func_name} definition_to_add)
100 check_function_exists(${func_name} HAVE_${definition_to_add})
101 if (${HAVE_${definition_to_add}})
102 add_definitions(-DHAVE_${definition_to_add})
107 list(APPEND CMAKE_REQUIRED_LIBRARIES m)
109 check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
110 check_include_file(unistd.h HAVE_UNISTD_H)
111 if (${HAVE_UNISTD_H})
112 add_definitions(-DHAVE_UNISTD_H)
114 check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
115 if (${HAVE_SYS_MMAN_H})
116 add_definitions(-DHAVE_SYS_MMAN_H)
118 check_include_file(xlocale.h HAVE_XLOCALE_H)
119 if (${HAVE_XLOCALE_H})
120 add_definitions(-DHAVE_XLOCALE_H)
122 check_include_file(stdbool.h HAVE_STDBOOL_H)
123 if (${HAVE_STDBOOL_H})
124 add_definitions(-DHAVE_STDBOOL_H)
129 add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
133 ## Detect if we are running inside a distribution or regular repository folder
134 # if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
135 # # perhaps we are on dist directory
136 # set (IN_HB_DIST TRUE)
137 # #set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
141 ## Extract variables from Makefile files
142 function (extract_make_variable variable makefile_source)
143 string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
144 string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
145 set (${variable} ${listVar} PARENT_SCOPE)
148 # http://stackoverflow.com/a/27630120
149 function (add_prefix_to_list var prefix)
151 foreach (f ${${var}})
152 list(APPEND listVar "${prefix}${f}")
154 set (${var} "${listVar}" PARENT_SCOPE)
157 file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
158 file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
160 extract_make_variable(HB_BASE_headers ${SRCSOURCES})
161 add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
163 extract_make_variable(HB_SUBSET_sources ${SRCSOURCES})
164 add_prefix_to_list(HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/")
166 extract_make_variable(HB_SUBSET_headers ${SRCSOURCES})
167 add_prefix_to_list(HB_SUBSET_headers "${PROJECT_SOURCE_DIR}/src/")
169 extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES})
171 add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
173 # add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
176 extract_make_variable(HB_VIEW_sources ${UTILSOURCES})
177 add_prefix_to_list(HB_VIEW_sources "${PROJECT_SOURCE_DIR}/util/")
178 extract_make_variable(HB_SHAPE_sources ${UTILSOURCES})
179 add_prefix_to_list(HB_SHAPE_sources "${PROJECT_SOURCE_DIR}/util/")
180 extract_make_variable(HB_SUBSET_CLI_sources ${UTILSOURCES})
181 add_prefix_to_list(HB_SUBSET_CLI_sources "${PROJECT_SOURCE_DIR}/util/")
182 extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES})
183 add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/")
186 file(READ configure.ac CONFIGUREAC)
187 string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
188 set (HB_VERSION ${CMAKE_MATCH_1})
189 set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
190 set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
191 set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
193 ## Define sources and headers of the project
194 set (project_sources ${PROJECT_SOURCE_DIR}/src/harfbuzz.cc) # use amalgam source
195 set (subset_project_sources ${HB_SUBSET_sources})
196 set (project_extra_sources)
197 set (project_headers ${HB_BASE_headers})
198 set (subset_project_headers ${HB_SUBSET_headers})
200 ## Find and include needed header folders and libraries
201 if (HB_HAVE_FREETYPE)
202 include (FindFreetype)
203 if (NOT FREETYPE_FOUND)
204 message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix")
207 list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES})
208 include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
209 add_definitions(-DHAVE_FREETYPE=1)
211 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
213 # So check_funcs can find its headers
214 set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS})
215 set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES})
217 check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
220 if (HB_HAVE_GRAPHITE2)
221 add_definitions(-DHAVE_GRAPHITE2)
223 find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h)
224 find_library(GRAPHITE2_LIBRARY graphite2)
226 include_directories(${GRAPHITE2_INCLUDE_DIR})
228 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
230 list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
232 mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
236 add_definitions(-DHAVE_GLIB)
238 # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake
239 find_package(PkgConfig)
240 pkg_check_modules(PC_GLIB QUIET glib-2.0)
242 find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
243 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)
244 find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
246 include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
248 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
250 list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
252 mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
256 add_definitions(-DHAVE_ICU)
258 # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindICU.cmake
259 find_package(PkgConfig)
260 pkg_check_modules(PC_ICU QUIET icu-uc)
262 find_path(ICU_INCLUDE_DIR NAMES unicode/utypes.h HINTS ${PC_ICU_INCLUDE_DIRS} ${PC_ICU_INCLUDEDIR})
263 find_library(ICU_LIBRARY NAMES libicuuc cygicuuc cygicuuc32 icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR})
265 include_directories(${ICU_INCLUDE_DIR})
267 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
269 list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
271 mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY)
274 if (APPLE AND HB_HAVE_CORETEXT)
275 # Apple Advanced Typography
276 add_definitions(-DHAVE_CORETEXT)
278 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
281 find_library(COREFOUNDATION CoreFoundation)
283 list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
285 mark_as_advanced(COREFOUNDATION)
287 find_library(CORETEXT CoreText)
289 list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
291 mark_as_advanced(CORETEXT)
293 find_library(COREGRAPHICS CoreGraphics)
295 list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
297 mark_as_advanced(COREGRAPHICS)
299 find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
300 if (APPLICATION_SERVICES_FRAMEWORK)
301 list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
304 mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
308 if (WIN32 AND HB_HAVE_UNISCRIBE)
309 add_definitions(-DHAVE_UNISCRIBE)
310 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
311 list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
314 if (WIN32 AND HB_HAVE_DIRECTWRITE)
315 add_definitions(-DHAVE_DIRECTWRITE)
316 list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
317 list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
323 # Use the hints from glib-2.0.pc to find glib-mkenums
324 find_package(PkgConfig)
325 pkg_check_modules(PC_GLIB QUIET glib-2.0)
326 find_program(GLIB_MKENUMS glib-mkenums
327 HINTS ${PC_glib_mkenums}
329 set (GLIB_MKENUMS_CMD)
331 if (WIN32 AND NOT MINGW)
332 # In Visual Studio builds, shebang lines are not supported
333 # in the standard cmd.exe shell that we use, so we need to
334 # first determine whether glib-mkenums is a Python or PERL
336 execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" --version
337 RESULT_VARIABLE GLIB_MKENUMS_PYTHON
338 OUTPUT_QUIET ERROR_QUIET
340 if (GLIB_MKENUMS_PYTHON EQUAL 0)
341 message("${GLIB_MKENUMS} is a Python script.")
342 set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}")
344 execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
345 RESULT_VARIABLE GLIB_MKENUMS_PERL
346 OUTPUT_QUIET ERROR_QUIET
348 if (GLIB_MKENUMS_PERL EQUAL 0)
349 message("${GLIB_MKENUMS} is a PERL script.")
350 set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}")
352 if (NOT GLIB_MKENUMS_PERL EQUAL 0 AND NOT GLIB_MKENUMS_PYTHON EQUAL 0)
353 message(FATAL_ERROR "Unable to determine type of glib-mkenums script")
357 set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}")
359 if (NOT GLIB_MKENUMS_CMD)
360 message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required")
363 pkg_check_modules(PC_GOBJECT QUIET gobject-2.0)
365 find_library(GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
366 find_path(GOBJECT_INCLUDE_DIR NAMES glib-object.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
368 include_directories(${GOBJECTCONFIG_INCLUDE_DIR} ${GOBJECT_INCLUDE_DIR})
369 mark_as_advanced(GOBJECT_LIBRARIES GOBJECT_INCLUDE_DIR)
371 list(APPEND hb_gobject_sources ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.cc)
372 list(APPEND hb_gobject_gen_sources
373 ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
375 list(APPEND hb_gobject_structs_headers
376 ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h
378 list(APPEND hb_gobject_headers
379 ${PROJECT_SOURCE_DIR}/src/hb-gobject.h
380 ${hb_gobject_structs_headers}
382 list(APPEND hb_gobject_gen_headers
383 ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
387 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
388 COMMAND ${GLIB_MKENUMS_CMD}
389 --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
390 --identifier-prefix hb_
391 --symbol-prefix hb_gobject
392 ${hb_gobject_structs_headers}
394 > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp
395 COMMAND "${CMAKE_COMMAND}"
396 "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp"
397 "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h"
398 -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
399 DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
405 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
406 COMMAND ${GLIB_MKENUMS_CMD}
407 --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
408 --identifier-prefix hb_
409 --symbol-prefix hb_gobject
412 > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp
413 COMMAND "${CMAKE_COMMAND}"
414 "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp"
415 "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc"
416 -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
417 DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
418 ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
424 ## Atomic ops availability detection
425 file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
426 " void memory_barrier (void) { __sync_synchronize (); }
427 int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
428 int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
429 void mutex_unlock (int *m) { __sync_lock_release (m); }
430 int main () { return 0; }
432 try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES
433 ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives
434 ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c)
435 if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES)
436 add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES)
439 file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c"
440 " #include <atomic.h>
441 /* This requires Solaris Studio 12.2 or newer: */
442 #include <mbarrier.h>
443 void memory_barrier (void) { __machine_rw_barrier (); }
444 int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
445 void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
446 int main () { return 0; }
448 try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS
449 ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops
450 ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c)
451 if (HB_HAVE_SOLARIS_ATOMIC_OPS)
452 add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS)
456 ## Define harfbuzz library
457 add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
458 target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
460 ## Define harfbuzz-subset library
462 add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
463 add_dependencies(harfbuzz-subset harfbuzz)
464 target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
466 if (BUILD_SHARED_LIBS)
467 set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
472 # Make symbols link locally
473 include (CheckCXXCompilerFlag)
474 CHECK_CXX_COMPILER_FLAG(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
475 if (CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
476 link_libraries(-Bsymbolic-functions)
479 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
480 # Make sure we don't link to libstdc++
481 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
482 set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
483 set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
484 set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
486 set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
489 # No threadsafe statics as we do it ourselves
490 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
493 CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
494 if (COMPILER_SUPPORTS_CXX11)
495 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
497 message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
502 ## Define harfbuzz-gobject library
504 add_library(harfbuzz-gobject
505 ${hb_gobject_sources}
506 ${hb_gobject_gen_sources}
507 ${hb_gobject_headers}
508 ${hb_gobject_gen_headers}
510 include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src)
511 add_dependencies(harfbuzz-gobject harfbuzz)
512 target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
514 if (BUILD_SHARED_LIBS)
515 set_target_properties(harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
519 if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW)
520 add_definitions("-DHB_DLL_EXPORT")
523 # On Windows, g-ir-scanner requires a DLL build in order for it to work
525 if (NOT BUILD_SHARED_LIBS)
526 message("Building introspection files on Windows requires BUILD_SHARED_LIBS to be enabled.")
527 set (HB_HAVE_INTROSPECTION OFF)
531 if (HB_HAVE_INTROSPECTION)
532 find_package(PkgConfig)
533 pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
535 find_program(G_IR_SCANNER g-ir-scanner
536 HINTS ${PC_g_ir_scanner}
539 find_program(G_IR_COMPILER g-ir-compiler
540 HINTS ${PC_g_ir_compiler}
543 if (WIN32 AND NOT MINGW)
544 # Note that since we already enable HB_HAVE_GOBJECT
545 # we would already have PYTHON_EXECUTABLE handy
546 set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}")
548 set (G_IR_SCANNER_CMD "${G_IR_SCANNER}")
551 # We need to account for the varying output directories
552 # when we build using Visual Studio projects
553 if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
554 set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
556 set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
559 # Get the CFlags that we used to build HarfBuzz/HarfBuzz-GObject
560 set (hb_defines_cflags "")
561 foreach (hb_cflag ${hb_cflags})
562 list(APPEND hb_defines_cflags "-D${hb_cflag}")
563 endforeach (hb_cflag)
565 # Get the other dependent libraries we used to build HarfBuzz/HarfBuzz-GObject
567 foreach (extra_lib ${THIRD_PARTY_LIBS})
568 # We don't want the .lib extension here...
569 string(REPLACE ".lib" "" extra_lib_stripped "${extra_lib}")
570 list(APPEND extra_libs "--extra-library=${extra_lib_stripped}")
573 set (introspected_sources)
577 ${hb_gobject_gen_sources}
578 ${hb_gobject_gen_headers}
579 ${hb_gobject_sources}
580 ${hb_gobject_headers}
583 # Nasty issue: We need to make drive letters lower case,
584 # otherwise g-ir-scanner won't like it and give us a bunch
585 # of invalid items and unresolved types...
586 STRING(SUBSTRING "${f}" 0 1 drive)
587 STRING(SUBSTRING "${f}" 1 -1 path)
588 if (drive MATCHES "[A-Z]")
589 STRING(TOLOWER ${drive} drive_lower)
590 list(APPEND introspected_sources "${drive_lower}${path}")
592 list(APPEND introspected_sources "${f}")
595 list(APPEND introspected_sources "${f}")
599 file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list)
600 foreach (s ${introspected_sources})
601 file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n")
604 # Finally, build the introspection files...
606 TARGET harfbuzz-gobject
608 COMMAND ${G_IR_SCANNER_CMD}
609 --warn-all --no-libtool --verbose
613 --identifier-prefix=hb_
614 --include GObject-2.0
615 --pkg-export=harfbuzz
617 -I${PROJECT_SOURCE_DIR}/src
618 -I${PROJECT_BINARY_DIR}/src
619 ${hb_includedir_cflags}
631 --library=harfbuzz-gobject
635 --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
636 -o ${hb_libpath}/HarfBuzz-0.0.gir
637 DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
641 TARGET harfbuzz-gobject
643 COMMAND "${G_IR_COMPILER}"
645 --includedir ${CMAKE_CURRENT_BINARY_DIR}
646 ${hb_libpath}/HarfBuzz-0.0.gir
647 -o ${hb_libpath}/HarfBuzz-0.0.typelib
648 DEPENDS ${hb_libpath}/HarfBuzz-0.0.gir harfbuzz-gobject
653 ## Additional framework build configs
655 set (CMAKE_MACOSX_RPATH ON)
656 set_target_properties(harfbuzz PROPERTIES
658 PUBLIC_HEADER "${project_headers}"
659 XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
661 set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
662 set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
663 set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}")
667 ## Additional harfbuzz build artifacts
669 # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake
670 find_package(PkgConfig)
671 pkg_check_modules(PC_CAIRO QUIET cairo)
673 find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo)
674 find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS})
676 add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
677 add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
678 include_directories(${CAIRO_INCLUDE_DIRS})
680 add_executable(hb-view ${HB_VIEW_sources})
681 target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES})
683 add_executable(hb-shape ${HB_SHAPE_sources})
684 target_link_libraries(hb-shape harfbuzz)
686 add_executable(hb-subset ${HB_SUBSET_CLI_sources})
687 target_link_libraries(hb-subset harfbuzz harfbuzz-subset)
689 add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources})
690 target_link_libraries(hb-ot-shape-closure harfbuzz)
692 mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES)
697 include (GNUInstallDirs)
699 if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
700 install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
702 install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
706 if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
707 install(TARGETS harfbuzz
708 EXPORT harfbuzzConfig
709 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
710 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
711 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
712 FRAMEWORK DESTINATION Library/Frameworks
714 install(EXPORT harfbuzzConfig
716 DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
719 if (WIN32 AND BUILD_SHARED_LIBS)
720 install(TARGETS harfbuzz-subset
721 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
724 install(TARGETS hb-view
725 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
727 install(TARGETS hb-subset
728 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
731 install(TARGETS hb-shape
732 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
735 install(TARGETS hb-ot-shape-closure
736 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
740 install(TARGETS harfbuzz-gobject
741 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
742 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
743 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
745 if (HB_HAVE_INTROSPECTION)
746 if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
747 set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
749 set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
752 install(FILES "${hb_libpath}/HarfBuzz-0.0.gir"
753 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0
756 install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
757 DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0
765 foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize test-unicode-ranges) # hb-ot-tag
766 set (prog_name ${prog})
767 if (${prog_name} STREQUAL "test")
768 # test can not be used as a valid executable name on cmake, lets special case it
769 set (prog_name test-test)
771 add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
772 target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
774 # set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
778 if (BUILD_SHARED_LIBS)
779 # generate harfbuzz.def after build completion
780 add_custom_command(TARGET harfbuzz POST_BUILD
781 COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
782 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
784 add_test(NAME check-static-inits.sh
785 COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
786 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
788 add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
789 add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
791 set_tests_properties(
792 check-static-inits.sh check-libstdc++.sh check-symbols.sh
794 ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
798 add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
799 add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
800 add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
801 add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
802 set_tests_properties(
803 check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
805 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
809 # Needs to come last so that variables defined above are passed to
811 add_subdirectory(test)