• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1cmake_minimum_required(VERSION 3.0.0)
2project(harfbuzz)
3
4message(WARN "HarfBuzz has a Meson port and tries to migrate all the other build systems to it, please consider using it as we might remove our cmake port soon.")
5
6## Limit framework build to Xcode generator
7if (BUILD_FRAMEWORK)
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")
11    message(FATAL_ERROR
12      "You should use Xcode generator with BUILD_FRAMEWORK enabled")
13  endif ()
14  set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
15  set (CMAKE_MACOSX_RPATH ON)
16  set (BUILD_SHARED_LIBS ON)
17endif ()
18
19
20## Disallow in-source builds, as CMake generated make files can collide with autotools ones
21if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
22  message(FATAL_ERROR
23    "
24In-source builds are not permitted!  Make a separate folder for"
25    " building, e.g.,"
26    "
27  mkdir build; cd build; cmake .."
28    "
29Before that, remove the files created by this failed run with"
30    "
31  rm -rf CMakeCache.txt CMakeFiles")
32endif ()
33
34
35## HarfBuzz build configurations
36option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
37option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
38option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
39option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
40if (APPLE)
41  option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
42  set (CMAKE_MACOSX_RPATH ON)
43endif ()
44if (WIN32)
45  option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
46  option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
47  option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
48endif ()
49option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
50if (HB_BUILD_UTILS)
51  set (HB_HAVE_GLIB ON)
52  set (HB_HAVE_FREETYPE ON)
53endif ()
54
55option(HB_BUILD_SUBSET "Build harfbuzz-subset" ON)
56
57option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF)
58if (HB_HAVE_GOBJECT)
59  set (HB_HAVE_GLIB ON)
60endif ()
61
62option(HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF)
63if (HB_HAVE_INTROSPECTION)
64  set (HB_HAVE_GOBJECT ON)
65  set (HB_HAVE_GLIB ON)
66endif ()
67
68include_directories(AFTER
69  ${PROJECT_SOURCE_DIR}/src
70  ${PROJECT_BINARY_DIR}/src
71)
72
73# We need PYTHON_EXECUTABLE to be set for running the tests...
74include (FindPythonInterp)
75
76## Functions and headers
77include (CheckFunctionExists)
78include (CheckIncludeFile)
79macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
80  foreach (func_name ${ARGN})
81    string(TOUPPER ${func_name} definition_to_add)
82    check_function_exists(${func_name} HAVE_${definition_to_add})
83    if (${HAVE_${definition_to_add}})
84      add_definitions(-DHAVE_${definition_to_add})
85    endif ()
86  endforeach ()
87endmacro ()
88if (UNIX)
89  list(APPEND CMAKE_REQUIRED_LIBRARIES m)
90endif ()
91check_funcs(atexit mprotect sysconf getpagesize mmap isatty)
92check_include_file(unistd.h HAVE_UNISTD_H)
93if (${HAVE_UNISTD_H})
94  add_definitions(-DHAVE_UNISTD_H)
95endif ()
96check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
97if (${HAVE_SYS_MMAN_H})
98  add_definitions(-DHAVE_SYS_MMAN_H)
99endif ()
100check_include_file(stdbool.h HAVE_STDBOOL_H)
101if (${HAVE_STDBOOL_H})
102  add_definitions(-DHAVE_STDBOOL_H)
103endif ()
104
105# https://github.com/harfbuzz/harfbuzz/pull/2874#issuecomment-782859099
106if (NOT WIN32)
107  add_definitions("-DHAVE_PTHREAD")
108endif ()
109
110if (MSVC)
111  add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
112endif ()
113
114
115## Detect if we are running inside a distribution or regular repository folder
116# if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
117#   # perhaps we are on dist directory
118#   set (IN_HB_DIST TRUE)
119#   #set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
120# endif ()
121
122
123## Extract variables from Makefile files
124function (extract_make_variable variable makefile_source)
125  string(REGEX MATCH "${variable} = ([^$]+)\\$" temp "${makefile_source}")
126  string(REGEX MATCHALL "[^ \n\t\\]+" listVar "${CMAKE_MATCH_1}")
127  set (${variable} ${listVar} PARENT_SCOPE)
128endfunction ()
129
130# https://stackoverflow.com/a/27630120
131function (add_prefix_to_list var prefix)
132  set (listVar "")
133  foreach (f ${${var}})
134    list(APPEND listVar "${prefix}${f}")
135  endforeach ()
136  set (${var} "${listVar}" PARENT_SCOPE)
137endfunction ()
138
139file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
140file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
141
142extract_make_variable(HB_BASE_headers ${SRCSOURCES})
143add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
144
145extract_make_variable(HB_SUBSET_sources ${SRCSOURCES})
146add_prefix_to_list(HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/")
147
148extract_make_variable(HB_SUBSET_headers ${SRCSOURCES})
149add_prefix_to_list(HB_SUBSET_headers "${PROJECT_SOURCE_DIR}/src/")
150
151extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES})
152#if (IN_HB_DIST)
153  add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
154#else ()
155#  add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
156#endif ()
157
158extract_make_variable(HB_VIEW_sources ${UTILSOURCES})
159add_prefix_to_list(HB_VIEW_sources "${PROJECT_SOURCE_DIR}/util/")
160extract_make_variable(HB_SHAPE_sources ${UTILSOURCES})
161add_prefix_to_list(HB_SHAPE_sources "${PROJECT_SOURCE_DIR}/util/")
162extract_make_variable(HB_SUBSET_CLI_sources ${UTILSOURCES})
163add_prefix_to_list(HB_SUBSET_CLI_sources "${PROJECT_SOURCE_DIR}/util/")
164extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES})
165add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/")
166
167
168file(READ configure.ac CONFIGUREAC)
169string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
170set (HB_VERSION ${CMAKE_MATCH_1})
171set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
172set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
173set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
174
175## Define sources and headers of the project
176set (project_sources ${PROJECT_SOURCE_DIR}/src/harfbuzz.cc) # use amalgam source
177set (subset_project_sources ${HB_SUBSET_sources})
178set (project_extra_sources)
179set (project_headers ${HB_BASE_headers})
180set (subset_project_headers ${HB_SUBSET_headers})
181
182## Find and include needed header folders and libraries
183if (HB_HAVE_FREETYPE)
184  include (FindFreetype)
185  if (NOT FREETYPE_FOUND)
186    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")
187  endif ()
188
189  list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES})
190  include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
191  add_definitions(-DHAVE_FREETYPE=1)
192
193  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
194
195  # So check_funcs can find its headers
196  set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS})
197  set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES})
198
199  check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
200endif ()
201
202if (HB_HAVE_GRAPHITE2)
203  add_definitions(-DHAVE_GRAPHITE2)
204
205  find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h)
206  find_library(GRAPHITE2_LIBRARY graphite2)
207
208  include_directories(${GRAPHITE2_INCLUDE_DIR})
209
210  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
211
212  list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
213
214  mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
215endif ()
216
217if (HB_HAVE_GLIB)
218  add_definitions(-DHAVE_GLIB)
219
220  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake
221  find_package(PkgConfig)
222  pkg_check_modules(PC_GLIB QUIET glib-2.0)
223
224  find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
225  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)
226  find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
227
228  include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
229
230  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
231
232  list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
233
234  mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
235endif ()
236
237if (HB_HAVE_ICU)
238  add_definitions(-DHAVE_ICU)
239
240  # https://github.com/WebKit/webkit/blob/fdd7733f2f30eab7fe096a9791f98c60f62f49c0/Source/cmake/FindICU.cmake
241  find_package(PkgConfig)
242  pkg_check_modules(PC_ICU QUIET icu-uc)
243
244  find_path(ICU_INCLUDE_DIR NAMES unicode/utypes.h HINTS ${PC_ICU_INCLUDE_DIRS} ${PC_ICU_INCLUDEDIR})
245  find_library(ICU_LIBRARY NAMES libicuuc cygicuuc cygicuuc32 icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR})
246
247  include_directories(${ICU_INCLUDE_DIR})
248
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)
254endif ()
255
256if (APPLE AND HB_HAVE_CORETEXT)
257  # Apple Advanced Typography
258  add_definitions(-DHAVE_CORETEXT)
259
260  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
261
262  if (HB_IOS)
263    find_library(COREFOUNDATION CoreFoundation)
264    if (COREFOUNDATION)
265      list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
266    endif ()
267    mark_as_advanced(COREFOUNDATION)
268
269    find_library(CORETEXT CoreText)
270    if (CORETEXT)
271      list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
272    endif ()
273    mark_as_advanced(CORETEXT)
274
275    find_library(COREGRAPHICS CoreGraphics)
276    if (COREGRAPHICS)
277      list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
278    endif ()
279    mark_as_advanced(COREGRAPHICS)
280  else ()
281    find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
282    if (APPLICATION_SERVICES_FRAMEWORK)
283      list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
284    endif ()
285
286    mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
287  endif ()
288endif ()
289
290if (WIN32 AND HB_HAVE_GDI)
291  add_definitions(-DHAVE_GDI)
292  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
293  list(APPEND THIRD_PARTY_LIBS gdi32)
294endif ()
295
296if (WIN32 AND HB_HAVE_UNISCRIBE)
297  add_definitions(-DHAVE_UNISCRIBE)
298  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
299  list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
300endif ()
301
302if (WIN32 AND HB_HAVE_DIRECTWRITE)
303  add_definitions(-DHAVE_DIRECTWRITE)
304  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
305  list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
306endif ()
307
308if (HB_HAVE_GOBJECT)
309  add_definitions(-DHAVE_GOBJECT)
310  include (FindPerl)
311
312  # Use the hints from glib-2.0.pc to find glib-mkenums
313  find_package(PkgConfig)
314  pkg_check_modules(PC_GLIB QUIET glib-2.0)
315  find_program(GLIB_MKENUMS glib-mkenums
316    HINTS ${PC_glib_mkenums}
317  )
318  set (GLIB_MKENUMS_CMD)
319
320  if (WIN32 AND NOT MINGW)
321    # In Visual Studio builds, shebang lines are not supported
322    # in the standard cmd.exe shell that we use, so we need to
323    # first determine whether glib-mkenums is a Python or PERL
324    # script
325    execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" --version
326      RESULT_VARIABLE GLIB_MKENUMS_PYTHON
327      OUTPUT_QUIET ERROR_QUIET
328    )
329    if (GLIB_MKENUMS_PYTHON EQUAL 0)
330      message("${GLIB_MKENUMS} is a Python script.")
331      set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}")
332    else ()
333      execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
334        RESULT_VARIABLE GLIB_MKENUMS_PERL
335        OUTPUT_QUIET ERROR_QUIET
336      )
337      if (GLIB_MKENUMS_PERL EQUAL 0)
338        message("${GLIB_MKENUMS} is a PERL script.")
339        set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}")
340      endif ()
341      if (NOT GLIB_MKENUMS_PERL EQUAL 0 AND NOT GLIB_MKENUMS_PYTHON EQUAL 0)
342        message(FATAL_ERROR "Unable to determine type of glib-mkenums script")
343      endif ()
344    endif ()
345  else ()
346    set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}")
347  endif ()
348  if (NOT GLIB_MKENUMS_CMD)
349    message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required")
350  endif ()
351
352  pkg_check_modules(PC_GOBJECT QUIET gobject-2.0)
353
354  find_library(GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
355  find_path(GOBJECT_INCLUDE_DIR NAMES glib-object.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
356
357  include_directories(${GOBJECTCONFIG_INCLUDE_DIR} ${GOBJECT_INCLUDE_DIR})
358  mark_as_advanced(GOBJECT_LIBRARIES GOBJECT_INCLUDE_DIR)
359
360  list(APPEND hb_gobject_sources ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.cc)
361  list(APPEND hb_gobject_gen_sources
362    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
363  )
364  list(APPEND hb_gobject_structs_headers
365    ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h
366  )
367  list(APPEND hb_gobject_headers
368    ${PROJECT_SOURCE_DIR}/src/hb-gobject.h
369    ${hb_gobject_structs_headers}
370  )
371  list(APPEND hb_gobject_gen_headers
372    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
373  )
374
375  add_custom_command(
376    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
377    COMMAND ${GLIB_MKENUMS_CMD}
378      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
379      --identifier-prefix hb_
380      --symbol-prefix hb_gobject
381      ${hb_gobject_structs_headers}
382      ${project_headers}
383      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp
384    COMMAND "${CMAKE_COMMAND}"
385      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp"
386      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h"
387      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
388    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
389      ${hb_gobject_header}
390      ${project_headers}
391  )
392
393  add_custom_command(
394    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
395    COMMAND ${GLIB_MKENUMS_CMD}
396      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
397      --identifier-prefix hb_
398      --symbol-prefix hb_gobject
399      ${hb_gobject_header}
400      ${project_headers}
401      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp
402    COMMAND "${CMAKE_COMMAND}"
403      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp"
404      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc"
405      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
406    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
407      ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
408      ${hb_gobject_header}
409      ${project_headers}
410  )
411endif ()
412
413
414## Define harfbuzz library
415add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
416target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
417target_include_directories(harfbuzz PUBLIC
418                           "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
419                           "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz>")
420
421## Define harfbuzz-icu library
422if (HB_HAVE_ICU)
423  add_library(harfbuzz-icu ${PROJECT_SOURCE_DIR}/src/hb-icu.cc ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
424  add_dependencies(harfbuzz-icu harfbuzz)
425  target_link_libraries(harfbuzz-icu harfbuzz ${THIRD_PARTY_LIBS})
426
427  if (BUILD_SHARED_LIBS)
428    set_target_properties(harfbuzz harfbuzz-icu PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
429  endif ()
430endif ()
431
432
433## Define harfbuzz-subset library
434if (HB_BUILD_SUBSET)
435  add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
436  add_dependencies(harfbuzz-subset harfbuzz)
437  target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
438
439  if (BUILD_SHARED_LIBS)
440    set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
441  endif ()
442endif ()
443
444if (UNIX OR MINGW)
445  # Make symbols link locally
446  include (CheckCXXCompilerFlag)
447  CHECK_CXX_COMPILER_FLAG(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
448  if (CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
449    link_libraries(-Bsymbolic-functions)
450  endif ()
451
452  if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
453    # Make sure we don't link to libstdc++
454    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
455    set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
456    set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
457    set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
458    if (HB_BUILD_SUBSET)
459      set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
460    endif ()
461
462    # No threadsafe statics as we do it ourselves
463    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
464  endif ()
465
466  CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
467  if (COMPILER_SUPPORTS_CXX11)
468    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
469  else()
470    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
471  endif()
472endif ()
473
474
475## Define harfbuzz-gobject library
476if (HB_HAVE_GOBJECT)
477  add_library(harfbuzz-gobject
478    ${hb_gobject_sources}
479    ${hb_gobject_gen_sources}
480    ${hb_gobject_headers}
481    ${hb_gobject_gen_headers}
482  )
483  include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src)
484  add_dependencies(harfbuzz-gobject harfbuzz)
485  target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
486
487  if (BUILD_SHARED_LIBS)
488    set_target_properties(harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
489  endif ()
490endif ()
491
492if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW)
493  add_definitions("-DHB_DLL_EXPORT")
494endif ()
495
496# On Windows, g-ir-scanner requires a DLL build in order for it to work
497if (WIN32)
498  if (NOT BUILD_SHARED_LIBS)
499    message("Building introspection files on Windows requires BUILD_SHARED_LIBS to be enabled.")
500    set (HB_HAVE_INTROSPECTION OFF)
501  endif ()
502endif ()
503
504if (HB_HAVE_INTROSPECTION)
505  find_package(PkgConfig)
506  pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
507
508  find_program(G_IR_SCANNER g-ir-scanner
509    HINTS ${PC_g_ir_scanner}
510  )
511
512  find_program(G_IR_COMPILER g-ir-compiler
513    HINTS ${PC_g_ir_compiler}
514  )
515
516  if (WIN32 AND NOT MINGW)
517    # Note that since we already enable HB_HAVE_GOBJECT
518    # we would already have PYTHON_EXECUTABLE handy
519    set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}")
520  else ()
521    set (G_IR_SCANNER_CMD "${G_IR_SCANNER}")
522  endif ()
523
524  # We need to account for the varying output directories
525  # when we build using Visual Studio projects
526  if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
527    set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
528  else ()
529    set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
530  endif ()
531
532  # Get the CFlags that we used to build HarfBuzz/HarfBuzz-GObject
533  set (hb_defines_cflags "")
534  foreach (hb_cflag ${hb_cflags})
535    list(APPEND hb_defines_cflags "-D${hb_cflag}")
536  endforeach (hb_cflag)
537
538  # Get the other dependent libraries we used to build HarfBuzz/HarfBuzz-GObject
539  set (extra_libs "")
540  foreach (extra_lib ${THIRD_PARTY_LIBS})
541    # We don't want the .lib extension here...
542    string(REPLACE ".lib" "" extra_lib_stripped "${extra_lib}")
543    list(APPEND extra_libs "--extra-library=${extra_lib_stripped}")
544  endforeach ()
545
546  set (introspected_sources)
547  foreach (f
548    ${project_headers}
549    ${project_sources}
550    ${hb_gobject_gen_sources}
551    ${hb_gobject_gen_headers}
552    ${hb_gobject_sources}
553    ${hb_gobject_headers}
554  )
555    if (WIN32)
556      # Nasty issue: We need to make drive letters lower case,
557      # otherwise g-ir-scanner won't like it and give us a bunch
558      # of invalid items and unresolved types...
559      STRING(SUBSTRING "${f}" 0 1 drive)
560      STRING(SUBSTRING "${f}" 1 -1 path)
561      if (drive MATCHES "[A-Z]")
562        STRING(TOLOWER ${drive} drive_lower)
563        list(APPEND introspected_sources "${drive_lower}${path}")
564      else ()
565        list(APPEND introspected_sources "${f}")
566      endif ()
567    else ()
568      list(APPEND introspected_sources "${f}")
569    endif ()
570  endforeach ()
571
572  file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list)
573  foreach (s ${introspected_sources})
574    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n")
575  endforeach ()
576
577  # Finally, build the introspection files...
578  add_custom_command(
579    TARGET harfbuzz-gobject
580    POST_BUILD
581    COMMAND ${G_IR_SCANNER_CMD}
582      --warn-all --no-libtool --verbose
583      --namespace=HarfBuzz
584      --nsversion=0.0
585      --symbol-prefix=hb
586      --symbol-prefix=hb_gobject
587      --identifier-prefix=hb_
588      --include GObject-2.0
589      --pkg-export=harfbuzz-gobject
590      --c-include=hb-gobject.h
591      --cflags-begin
592      -I${PROJECT_SOURCE_DIR}/src
593      -I${PROJECT_BINARY_DIR}/src
594      ${hb_includedir_cflags}
595      ${hb_defines_cflags}
596      -DHB_H
597      -DHB_H_IN
598      -DHB_OT_H
599      -DHB_OT_H_IN
600      -DHB_AAT_H
601      -DHB_AAT_H_IN
602      -DHB_GOBJECT_H
603      -DHB_GOBJECT_H_IN
604      -DHB_EXTERN=
605      --cflags-end
606      --library=harfbuzz-gobject
607      --library=harfbuzz
608      -L${hb_libpath}
609      ${extra_libs}
610      --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
611      -o ${hb_libpath}/HarfBuzz-0.0.gir
612    DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
613  )
614
615  add_custom_command(
616    TARGET harfbuzz-gobject
617    POST_BUILD
618    COMMAND "${G_IR_COMPILER}"
619      --verbose --debug
620      --includedir ${CMAKE_CURRENT_BINARY_DIR}
621      ${hb_libpath}/HarfBuzz-0.0.gir
622      -o ${hb_libpath}/HarfBuzz-0.0.typelib
623    DEPENDS ${hb_libpath}/HarfBuzz-0.0.gir harfbuzz-gobject
624  )
625endif ()
626
627
628## Additional framework build configs
629if (BUILD_FRAMEWORK)
630  set (CMAKE_MACOSX_RPATH ON)
631  set_target_properties(harfbuzz PROPERTIES
632    FRAMEWORK TRUE
633    PUBLIC_HEADER "${project_headers}"
634    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
635  )
636  set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
637  set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
638  set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}")
639endif ()
640
641
642## Additional harfbuzz build artifacts
643if (HB_BUILD_UTILS)
644  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake
645  find_package(PkgConfig)
646  pkg_check_modules(PC_CAIRO QUIET cairo)
647
648  find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo)
649  find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS})
650
651  add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
652  add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
653  include_directories(${CAIRO_INCLUDE_DIRS})
654
655  add_executable(hb-view ${HB_VIEW_sources})
656  target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES})
657
658  add_executable(hb-shape ${HB_SHAPE_sources})
659  target_link_libraries(hb-shape harfbuzz)
660
661  add_executable(hb-subset ${HB_SUBSET_CLI_sources})
662  target_link_libraries(hb-subset harfbuzz harfbuzz-subset)
663
664  add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources})
665  target_link_libraries(hb-ot-shape-closure harfbuzz)
666
667  mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES)
668endif ()
669
670
671## Install
672include (GNUInstallDirs)
673
674if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
675  install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
676  if (HB_HAVE_GOBJECT)
677    install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
678  endif ()
679endif ()
680
681if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
682  install(TARGETS harfbuzz
683    EXPORT harfbuzzConfig
684    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
685    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
686    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
687    FRAMEWORK DESTINATION Library/Frameworks
688  )
689  install(EXPORT harfbuzzConfig
690      NAMESPACE harfbuzz::
691      DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
692  )
693  if (HB_HAVE_ICU)
694    install(TARGETS harfbuzz-icu
695      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
696      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
697      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
698      FRAMEWORK DESTINATION Library/Frameworks
699    )
700  endif ()
701  if (HB_BUILD_UTILS)
702    if (WIN32 AND BUILD_SHARED_LIBS)
703      install(TARGETS harfbuzz-subset
704        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
705      )
706    endif ()
707    install(TARGETS hb-view
708      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
709    )
710    install(TARGETS hb-subset
711      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
712    )
713
714    install(TARGETS hb-shape
715      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
716    )
717
718    install(TARGETS hb-ot-shape-closure
719      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
720    )
721  endif ()
722  if (HB_HAVE_GOBJECT)
723    install(TARGETS harfbuzz-gobject
724      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
725      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
726      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
727    )
728    if (HB_HAVE_INTROSPECTION)
729      if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
730        set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
731      else ()
732        set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
733      endif ()
734
735      install(FILES "${hb_libpath}/HarfBuzz-0.0.gir"
736        DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0
737      )
738
739      install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
740        DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0
741      )
742    endif ()
743  endif ()
744endif ()
745