CMakeLists.txt 26.7 KB
Newer Older
E
ebraminio 已提交
1 2 3
cmake_minimum_required(VERSION 2.8.0)
project(harfbuzz)

K
Khaled Hosny 已提交
4
enable_testing()
5 6 7 8 9 10 11 12

## Limit framework build to Xcode generator
if (BUILD_FRAMEWORK)
  # for a framework on macOS, use `cmake .. -DBUILD_FRAMEWORK:BOOL=true -G Xcode`
  if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
    message(FATAL_ERROR
      "You should use Xcode generator with BUILD_FRAMEWORK enabled")
  endif ()
13 14 15
  set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
  set (CMAKE_MACOSX_RPATH ON)
  set (BUILD_SHARED_LIBS ON)
16 17 18
endif ()


E
Ebrahim Byagowi 已提交
19 20
## Disallow in-source builds, as CMake generated make files can collide with autotools ones
if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
E
ebraminio 已提交
21 22 23 24 25 26 27 28 29 30 31
  message(FATAL_ERROR
    "
In-source builds are not permitted!  Make a separate folder for"
    " building, e.g.,"
    "
  mkdir build; cd build; cmake .."
    "
Before that, remove the files created by this failed run with"
    "
  rm -rf CMakeCache.txt CMakeFiles")
endif ()
E
Ebrahim Byagowi 已提交
32

E
ebraminio 已提交
33 34

## HarfBuzz build configurations
35 36
option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
E
ebraminio 已提交
37
option(HB_BUILTIN_UCDN "Use HarfBuzz provided UCDN" ON)
38 39
option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
E
ebraminio 已提交
40 41
if (APPLE)
  option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
42
  set (CMAKE_MACOSX_RPATH ON)
E
ebraminio 已提交
43 44 45
endif ()
if (WIN32)
  option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
C
Chun-wei Fan 已提交
46
  option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
E
ebraminio 已提交
47
endif ()
48 49
option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
if (HB_BUILD_UTILS)
50 51
  set (HB_HAVE_GLIB ON)
  set (HB_HAVE_FREETYPE ON)
52
endif ()
E
ebraminio 已提交
53

54 55
option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF)
if (HB_HAVE_GOBJECT)
56
  set (HB_HAVE_GLIB ON)
57 58
endif ()

59 60
option(HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF)
if (HB_HAVE_INTROSPECTION)
61 62
  set (HB_HAVE_GOBJECT ON)
  set (HB_HAVE_GLIB ON)
63 64
endif ()

E
Ebrahim Byagowi 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
option(HB_CHECK OFF "Do a configuration suitable for testing (shared library and enable all options)")
if (HB_CHECK)
  set (BUILD_SHARED_LIBS ON)
  set (HB_BUILD_UTILS ON)
  set (HB_BUILTIN_UCDN ON)
  set (HB_HAVE_ICU)
  set (HB_HAVE_GLIB ON)
  #set (HB_HAVE_GOBJECT ON)
  #set (HB_HAVE_INTROSPECTION ON)
  set (HB_HAVE_FREETYPE ON)
  set (HB_HAVE_GRAPHITE2 ON)
  if (WIN32)
    set (HB_HAVE_UNISCRIBE ON)
    set (HB_HAVE_DIRECTWRITE ON)
  elseif (APPLE)
    set (HB_HAVE_CORETEXT ON)
  endif ()
endif ()

E
ebraminio 已提交
84
include_directories(AFTER
85
  ${PROJECT_SOURCE_DIR}/src
E
ebraminio 已提交
86
  ${PROJECT_BINARY_DIR}/src
E
Ebrahim Byagowi 已提交
87
)
E
ebraminio 已提交
88 89

add_definitions(-DHAVE_OT)
C
Chun-wei Fan 已提交
90
add_definitions(-DHAVE_FALLBACK)
E
ebraminio 已提交
91

92 93 94 95 96

include (CheckFunctionExists)
include (CheckIncludeFile)
macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
  foreach (func_name ${ARGN})
97 98 99
    string(TOUPPER ${func_name} definiton_to_add)
    check_function_exists(${func_name} HAVE_${definiton_to_add})
    if (${HAVE_${definiton_to_add}})
100 101 102 103
      add_definitions(-DHAVE_${definiton_to_add})
    endif ()
  endforeach ()
endmacro ()
104
check_funcs(atexit mprotect sysconf mmap strtod_l) #TODO: getpagesize newlocale isatty
105 106 107 108 109

check_include_file(unistd.h HAVE_UNIST_H)
if (${HAVE_UNIST_H})
  add_definitions(-DHAVE_UNIST_H)
endif ()
110 111 112 113
check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
if (${HAVE_SYS_MMAN_H})
  add_definitions(-DHAVE_SYS_MMAN_H)
endif ()
114 115 116 117 118
check_include_file(xlocale.h HAVE_XLOCALE_H)
if (${HAVE_XLOCALE_H})
  add_definitions(-DHAVE_XLOCALE_H)
endif ()

E
ebraminio 已提交
119 120 121 122 123 124 125 126 127

if (MSVC)
  add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
endif ()

if (WIN32 AND NOT MINGW AND BUILD_SHARED_LIBS)
  add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
endif ()

E
Ebrahim Byagowi 已提交
128

129
## Detect if we are running inside a distribution or regular repository folder
130
set (IN_HB_DIST FALSE)
131
if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
E
ebraminio 已提交
132
  # perhaps we are on dist directory
133 134
  set (IN_HB_DIST TRUE)
  set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
E
ebraminio 已提交
135 136
endif ()

E
Ebrahim Byagowi 已提交
137

138
## Extract variables from Makefile files
139 140 141 142 143 144 145 146
function (extract_make_variable variable makefile_source)
  string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
  string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
  set (${variable} ${listVar} PARENT_SCOPE)
endfunction ()

# http://stackoverflow.com/a/27630120
function (add_prefix_to_list var prefix)
147
  set (listVar "")
148
  foreach (f ${${var}})
149
    list(APPEND listVar "${prefix}${f}")
150
  endforeach ()
151
  set (${var} "${listVar}" PARENT_SCOPE)
152 153
endfunction ()

E
ebraminio 已提交
154 155 156
file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
file(READ ${PROJECT_SOURCE_DIR}/src/hb-ucdn/Makefile.sources UCDNSOURCES)
157

158 159 160 161 162 163 164 165 166 167 168 169 170
extract_make_variable(HB_BASE_sources ${SRCSOURCES})
add_prefix_to_list(HB_BASE_sources "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_BASE_headers ${SRCSOURCES})
add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_FALLBACK_sources ${SRCSOURCES})
add_prefix_to_list(HB_FALLBACK_sources "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_OT_sources ${SRCSOURCES})
add_prefix_to_list(HB_OT_sources "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_OT_headers ${SRCSOURCES})
add_prefix_to_list(HB_OT_headers "${PROJECT_SOURCE_DIR}/src/")

extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES})
extract_make_variable(HB_OT_RAGEL_GENERATED_sources ${SRCSOURCES})
171
if (IN_HB_DIST)
172 173
  add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
  add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
174
else ()
175 176
  add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
  add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
177
endif ()
178

179 180 181 182 183 184 185 186 187
extract_make_variable(HB_VIEW_sources ${UTILSOURCES})
add_prefix_to_list(HB_VIEW_sources "${PROJECT_SOURCE_DIR}/util/")
extract_make_variable(HB_SHAPE_sources ${UTILSOURCES})
add_prefix_to_list(HB_SHAPE_sources "${PROJECT_SOURCE_DIR}/util/")
extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES})
add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/")

extract_make_variable(LIBHB_UCDN_sources ${UCDNSOURCES})
add_prefix_to_list(LIBHB_UCDN_sources "${PROJECT_SOURCE_DIR}/src/hb-ucdn/")
E
ebraminio 已提交
188

189

190 191
file(READ configure.ac CONFIGUREAC)
string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
192 193 194 195
set (HB_VERSION ${CMAKE_MATCH_1})
set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
E
Ebrahim Byagowi 已提交
196

197

198
## Define ragel tasks
E
ebraminio 已提交
199
if (NOT IN_HB_DIST)
200
  find_program(RAGEL "ragel" CMAKE_FIND_ROOT_PATH_BOTH)
E
ebraminio 已提交
201 202 203

  if (RAGEL)
    message(STATUS "ragel found at: ${RAGEL}")
204
  else ()
205
    message(FATAL_ERROR "ragel not found, get it here -- http://www.complang.org/ragel/ or, use harfbuzz releases https://github.com/harfbuzz/harfbuzz/releases")
206
  endif ()
E
ebraminio 已提交
207

208 209
  foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources} ${HB_OT_RAGEL_GENERATED_sources})
    string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
210
    set (target_name ${CMAKE_MATCH_1})
211 212 213
    add_custom_command(OUTPUT ${ragel_output}
      COMMAND ${RAGEL} -G2 -o ${ragel_output} ${PROJECT_SOURCE_DIR}/src/${target_name}.rl -I ${PROJECT_SOURCE_DIR} ${ARGN}
      DEPENDS ${PROJECT_SOURCE_DIR}/src/${target_name}.rl
214
    )
215 216
    add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
  endforeach ()
E
ebraminio 已提交
217 218

  mark_as_advanced(RAGEL)
219
endif ()
E
Ebrahim Byagowi 已提交
220

E
ebraminio 已提交
221

222 223
## Generate hb-version.h
if (NOT IN_HB_DIST)
224 225
  set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
  set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
E
ebraminio 已提交
226 227 228 229
  set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
  configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
  execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
    "${HB_VERSION_H}.tmp"
230
    "${HB_VERSION_H}"
231
  )
E
ebraminio 已提交
232 233 234
  file(REMOVE "${HB_VERSION_H}.tmp")
endif ()

235

236
## Define sources and headers of the project
237
set (project_sources
238 239
  ${HB_BASE_sources}
  ${HB_BASE_RAGEL_GENERATED_sources}
E
ebraminio 已提交
240

C
Chun-wei Fan 已提交
241
  ${HB_FALLBACK_sources}
242 243
  ${HB_OT_sources}
  ${HB_OT_RAGEL_GENERATED_sources}
244
)
E
ebraminio 已提交
245

246
set (project_extra_sources)
247

248
set (project_headers
E
ebraminio 已提交
249 250 251 252
  ${HB_VERSION_H}

  ${HB_BASE_headers}
  ${HB_OT_headers}
253
)
E
ebraminio 已提交
254

E
Ebrahim Byagowi 已提交
255 256

## Find and include needed header folders and libraries
E
ebraminio 已提交
257
if (HB_HAVE_FREETYPE)
258
  include (FindFreetype)
259 260
  if (NOT FREETYPE_FOUND)
    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")
261
  endif ()
E
ebraminio 已提交
262

263 264 265
  list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES})
  include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
  add_definitions(-DHAVE_FREETYPE=1 -DHAVE_FT_FACE_GETCHARVARIANTINDEX=1)
E
ebraminio 已提交
266

267 268
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
269

270 271 272
  set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS})
  set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES})
  check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
E
ebraminio 已提交
273 274
endif ()

275 276 277 278 279 280 281 282 283 284 285 286
if (HB_HAVE_GRAPHITE2)
  add_definitions(-DHAVE_GRAPHITE2)

  find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h)
  find_library(GRAPHITE2_LIBRARY graphite2)

  include_directories(${GRAPHITE2_INCLUDE_DIR})

  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-graphite2.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)

  list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
E
ebraminio 已提交
287 288

  mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
289 290
endif ()

E
ebraminio 已提交
291 292 293 294
if (HB_BUILTIN_UCDN)
  include_directories(src/hb-ucdn)
  add_definitions(-DHAVE_UCDN)

295 296
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ucdn.cc)
  list(APPEND project_extra_sources ${LIBHB_UCDN_sources})
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
endif ()

if (HB_HAVE_GLIB)
  add_definitions(-DHAVE_GLIB)

  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake
  find_package(PkgConfig)
  pkg_check_modules(PC_GLIB QUIET glib-2.0)

  find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
  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)
  find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)

  include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})

  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-glib.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)

  list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
E
ebraminio 已提交
316 317

  mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
E
ebraminio 已提交
318 319
endif ()

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
if (HB_HAVE_ICU)
  add_definitions(-DHAVE_ICU)

  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindICU.cmake
  find_package(PkgConfig)
  pkg_check_modules(PC_ICU QUIET icu-uc)

  find_path(ICU_INCLUDE_DIR NAMES unicode/utypes.h HINTS ${PC_ICU_INCLUDE_DIRS} ${PC_ICU_INCLUDEDIR})
  find_library(ICU_LIBRARY NAMES libicuuc cygicuuc cygicuuc32 icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR})

  include_directories(${ICU_INCLUDE_DIR})

  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-icu.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)

  list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
E
ebraminio 已提交
336 337

  mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY)
338 339
endif ()

E
ebraminio 已提交
340 341 342 343
if (APPLE AND HB_HAVE_CORETEXT)
  # Apple Advanced Typography
  add_definitions(-DHAVE_CORETEXT)

344 345
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
E
ebraminio 已提交
346 347 348

  find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
  if (APPLICATION_SERVICES_FRAMEWORK)
349
    list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
E
ebraminio 已提交
350
  endif (APPLICATION_SERVICES_FRAMEWORK)
E
ebraminio 已提交
351 352
  
  mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
E
ebraminio 已提交
353 354 355 356 357
endif ()

if (WIN32 AND HB_HAVE_UNISCRIBE)
  add_definitions(-DHAVE_UNISCRIBE)

358 359
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
E
ebraminio 已提交
360

361
  list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
E
ebraminio 已提交
362 363 364 365 366
endif ()

if (WIN32 AND HB_HAVE_DIRECTWRITE)
  add_definitions(-DHAVE_DIRECTWRITE)

367 368
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-directwrite.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
E
ebraminio 已提交
369

370
  list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
E
ebraminio 已提交
371
endif ()
E
Ebrahim Byagowi 已提交
372

373
if (HB_HAVE_GOBJECT)
374 375
  include (FindPythonInterp)
  include (FindPerl)
376 377 378 379 380 381
  
  # Use the hints from glib-2.0.pc to find glib-mkenums
  find_package(PkgConfig)
  pkg_check_modules(PC_GLIB QUIET glib-2.0)
  find_program(GLIB_MKENUMS glib-mkenums
    HINTS ${PC_glib_mkenums}
382 383
  )
  set (GLIB_MKENUMS_CMD)
384 385 386 387 388 389 390 391 392

  if (WIN32 AND NOT MINGW)
    # In Visual Studio builds, shebang lines are not supported
    # in the standard cmd.exe shell that we use, so we need to
    # first determine whether glib-mkenums is a Python or PERL
    # script
    execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" --version
      RESULT_VARIABLE GLIB_MKENUMS_PYTHON
      OUTPUT_QUIET ERROR_QUIET
393
    )
394 395
    if (GLIB_MKENUMS_PYTHON EQUAL 0)
      message("${GLIB_MKENUMS} is a Python script.")
396
      set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}")
397 398 399 400
    else ()
      execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
        RESULT_VARIABLE GLIB_MKENUMS_PERL
        OUTPUT_QUIET ERROR_QUIET
401
      )
402 403
      if (GLIB_MKENUMS_PERL EQUAL 0)
        message("${GLIB_MKENUMS} is a PERL script.")
404
        set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}")
405 406 407 408
      endif ()
      if (NOT GLIB_MKENUMS_PERL EQUAL 0 AND NOT GLIB_MKENUMS_PYTHON EQUAL 0)
        message(FATAL_ERROR "Unable to determine type of glib-mkenums script")
      endif ()
409
    endif ()
410
  else ()
411
    set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}")
412 413 414
  endif ()
  if (NOT GLIB_MKENUMS_CMD)
    message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required")
415
  endif ()
416 417 418 419 420 421 422 423 424 425 426 427

  pkg_check_modules(PC_GOBJECT QUIET gobject-2.0)

  find_library(GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
  find_path(GOBJECT_INCLUDE_DIR NAMES glib-object.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)

  include_directories(${GOBJECTCONFIG_INCLUDE_DIR} ${GOBJECT_INCLUDE_DIR})
  mark_as_advanced(GOBJECT_LIBRARIES GOBJECT_INCLUDE_DIR)

  list(APPEND hb_gobject_sources ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.cc)
  list(APPEND hb_gobject_gen_sources
    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
428
  )
429 430
  list(APPEND hb_gobject_structs_headers
    ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h
431
  )
432 433
  list(APPEND hb_gobject_headers
    ${PROJECT_SOURCE_DIR}/src/hb-gobject.h
434
    ${hb_gobject_structs_headers}
435
  )
436 437
  list(APPEND hb_gobject_gen_headers
    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
438
  )
439

440
  add_custom_command(
441 442 443 444 445
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
    COMMAND ${GLIB_MKENUMS_CMD}
      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
      --identifier-prefix hb_
      --symbol-prefix hb_gobject
446
      ${hb_gobject_structs_headers}
447 448 449 450 451 452 453 454 455
      ${project_headers}
      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp
    COMMAND "${CMAKE_COMMAND}"
      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp"
      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h"
      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
      ${hb_gobject_header}
      ${project_headers}
456
  )
457

458
  add_custom_command(
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
    COMMAND ${GLIB_MKENUMS_CMD}
      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
      --identifier-prefix hb_
      --symbol-prefix hb_gobject
      ${hb_gobject_header}
      ${project_headers}
      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp
    COMMAND "${CMAKE_COMMAND}"
      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp"
      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc"
      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
      ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
      ${hb_gobject_header}
      ${project_headers}
475
  )
476
endif ()
E
ebraminio 已提交
477

E
Ebrahim Byagowi 已提交
478

479 480 481 482 483 484
## Atomic ops availability detection
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
"		void memory_barrier (void) { __sync_synchronize (); }
		int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
		int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
		void mutex_unlock (int *m) { __sync_lock_release (m); }
485
		int main () { return 0; }
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
")
try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES
  ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives
  SOURCES ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c)
if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES)
  add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES)
endif ()

file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c"
"		#include <atomic.h>
		/* This requires Solaris Studio 12.2 or newer: */
		#include <mbarrier.h>
		void memory_barrier (void) { __machine_rw_barrier (); }
		int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
		void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
501
		int main () { return 0; }
502 503 504 505
")
try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS
  ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops
  SOURCES ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c)
E
ebraminio 已提交
506 507
if (HB_HAVE_SOLARIS_ATOMIC_OPS)
  add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS)
508 509
endif ()

E
Ebrahim Byagowi 已提交
510 511

## Define harfbuzz library
512
add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
E
ebraminio 已提交
513 514
target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})

E
Ebrahim Byagowi 已提交
515

516 517 518 519 520 521 522
## Define harfbuzz-gobject library
if (HB_HAVE_GOBJECT)
  add_library(harfbuzz-gobject
    ${hb_gobject_sources}
    ${hb_gobject_gen_sources}
    ${hb_gobject_headers}
    ${hb_gobject_gen_headers}
523
  )
524 525 526 527
  include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src)
  add_dependencies(harfbuzz-gobject harfbuzz)
  target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
endif ()
E
Ebrahim Byagowi 已提交
528

529 530 531 532
# On Windows, g-ir-scanner requires a DLL build in order for it to work
if (WIN32)
  if (NOT BUILD_SHARED_LIBS)
    message("Building introspection files on Windows requires BUILD_SHARED_LIBS to be enabled.")
533
    set (HB_HAVE_INTROSPECTION OFF)
534 535 536 537 538 539 540 541 542 543
  endif ()
endif ()

if (HB_HAVE_INTROSPECTION)

  find_package(PkgConfig)
  pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)

  find_program(G_IR_SCANNER g-ir-scanner
    HINTS ${PC_g_ir_scanner}
544
  )
545 546 547

  find_program(G_IR_COMPILER g-ir-compiler
    HINTS ${PC_g_ir_compiler}
548
  )
549 550 551 552

  if (WIN32 AND NOT MINGW)
    # Note that since we already enable HB_HAVE_GOBJECT
    # we would already have PYTHON_EXECUTABLE handy
553
    set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}")
554
  else ()
555
    set (G_IR_SCANNER_CMD "${G_IR_SCANNER}")
556 557 558 559
  endif ()

  # We need to account for the varying output directories
  # when we build using Visual Studio projects
560
  if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
561 562 563 564 565 566 567
    set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
  else ()
    set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
  endif ()

  # Get the CFlags that we used to build HarfBuzz/HarfBuzz-GObject
  set (hb_defines_cflags "")
568
  foreach (hb_cflag ${hb_cflags})
569
    list(APPEND hb_defines_cflags "-D${hb_cflag}")
570
  endforeach (hb_cflag)
571 572 573 574 575 576 577 578 579

  # Get the other dependent libraries we used to build HarfBuzz/HarfBuzz-GObject
  set (extra_libs "")
  foreach (extra_lib ${THIRD_PARTY_LIBS})
    # We don't want the .lib extension here...
    string(REPLACE ".lib" "" extra_lib_stripped "${extra_lib}")
    list(APPEND extra_libs "--extra-library=${extra_lib_stripped}")
  endforeach ()

580
  set (introspected_sources)
581 582 583 584 585 586 587
  foreach (f
    ${project_headers}
    ${project_sources}
    ${hb_gobject_gen_sources}
    ${hb_gobject_gen_headers}
    ${hb_gobject_sources}
    ${hb_gobject_headers}
E
Ebrahim Byagowi 已提交
588
  )
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
    if (WIN32)
      # Nasty issue: We need to make drive letters lower case,
      # otherwise g-ir-scanner won't like it and give us a bunch
      # of invalid items and unresolved types...
      STRING(SUBSTRING "${f}" 0 1 drive)
      STRING(SUBSTRING "${f}" 1 -1 path)
      if (drive MATCHES "[A-Z]")
        STRING(TOLOWER ${drive} drive_lower)
        list(APPEND introspected_sources "${drive_lower}${path}")
      else ()
        list(APPEND introspected_sources "${f}")
      endif ()
    else ()
      list(APPEND introspected_sources "${f}")
    endif ()
  endforeach ()

  # Finally, build the introspection files...
607
  add_custom_command(
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
    TARGET harfbuzz-gobject
    POST_BUILD
    COMMAND ${G_IR_SCANNER_CMD}
      --warn-all --no-libtool --verbose
      -n hb
      --namespace=HarfBuzz
      --nsversion=0.0
      --identifier-prefix=hb_
      --include GObject-2.0
      --pkg-export=harfbuzz
      --cflags-begin
      -I${PROJECT_SOURCE_DIR}/src
      -I${PROJECT_BINARY_DIR}/src
      ${hb_includedir_cflags}
      ${hb_defines_cflags}
      -DHB_H
      -DHB_H_IN
      -DHB_OT_H
      -DHB_OT_H_IN
      -DHB_GOBJECT_H
      -DHB_GOBJECT_H_IN
      -DHB_EXTERN=
      --cflags-end
      --library=harfbuzz-gobject
      --library=harfbuzz
      -L${hb_libpath}
      ${extra_libs}
      ${introspected_sources}
      -o ${hb_libpath}/HarfBuzz-0.0.gir
    DEPENDS harfbuzz-gobject harfbuzz
638
  )
639

640
  add_custom_command(
641 642 643 644 645 646 647 648
    TARGET harfbuzz-gobject
    POST_BUILD
    COMMAND "${G_IR_COMPILER}"
      --verbose --debug
      --includedir ${CMAKE_CURRENT_BINARY_DIR}
      ${hb_libpath}/HarfBuzz-0.0.gir
      -o ${hb_libpath}/HarfBuzz-0.0.typelib
    DEPENDS ${hb_libpath}/HarfBuzz-0.0.gir harfbuzz-gobject
649
  )
650 651
endif ()

E
Ebrahim Byagowi 已提交
652

653 654
## Additional framework build configs
if (BUILD_FRAMEWORK)
655
  set (CMAKE_MACOSX_RPATH ON)
656 657 658 659 660
  set_target_properties(harfbuzz PROPERTIES
    FRAMEWORK TRUE
    PUBLIC_HEADER "${project_headers}"
    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
  )
661 662 663
  set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
  set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
  set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}")
664 665 666
endif ()


E
Ebrahim Byagowi 已提交
667
## Additional harfbuzz build artifacts
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
if (HB_BUILD_UTILS)
  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake
  find_package(PkgConfig)
  pkg_check_modules(PC_CAIRO QUIET cairo)

  find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo)
  find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS})

  add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
  add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
  include_directories(${CAIRO_INCLUDE_DIRS})

  add_executable(hb-view ${HB_VIEW_sources})
  target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES})

  add_executable(hb-shape ${HB_SHAPE_sources})
  target_link_libraries(hb-shape harfbuzz)

  add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources})
  target_link_libraries(hb-ot-shape-closure harfbuzz)
E
ebraminio 已提交
688

E
Ebrahim Byagowi 已提交
689
  mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES)
690 691
endif ()

E
Ebrahim Byagowi 已提交
692

E
ebraminio 已提交
693
## Install
694
include (GNUInstallDirs)
695

E
ebraminio 已提交
696
if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
697
  install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
698
  if (HB_HAVE_GOBJECT)
699
    install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
700
  endif ()
E
ebraminio 已提交
701 702 703 704
endif ()

if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
  install(TARGETS harfbuzz
705 706 707
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
708
    FRAMEWORK DESTINATION Library/Frameworks
709
  )
C
Chun-wei Fan 已提交
710 711
  if (HB_BUILD_UTILS)
    install(TARGETS hb-view
712
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
713 714
    )
    install(TARGETS hb-view
715
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
716 717 718
    )

    install(TARGETS hb-shape
719
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
720 721 722
    )

    install(TARGETS hb-ot-shape-closure
723
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
724 725
    )
  endif ()
726 727
  if (HB_HAVE_GOBJECT)
    install(TARGETS harfbuzz-gobject
728 729 730
      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
731
    )
732
    if (HB_HAVE_INTROSPECTION)
733
      if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
734 735 736 737 738 739
        set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
      else ()
        set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
      endif ()

      install(FILES "${hb_libpath}/HarfBuzz-0.0.gir"
740
        DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0
E
Ebrahim Byagowi 已提交
741
      )
742 743

      install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
744 745
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0
      )
746
    endif ()
747
  endif ()
E
ebraminio 已提交
748
endif ()
K
Khaled Hosny 已提交
749

750 751 752 753 754 755 756 757 758 759
if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
  if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    set (CMAKE_CXX_FLAGS "-fcolor-diagnostics ${CMAKE_CXX_FLAGS}")
    set (CMAKE_C_FLAGS "-fcolor-diagnostics ${CMAKE_C_FLAGS}")
  endif ()
  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    set (CMAKE_CXX_FLAGS "-fdiagnostics-color ${CMAKE_CXX_FLAGS}")
    set (CMAKE_C_FLAGS "-fdiagnostics-color ${CMAKE_C_FLAGS}")
  endif ()
endif ()
E
Ebrahim Byagowi 已提交
760

E
Ebrahim Byagowi 已提交
761

E
Ebrahim Byagowi 已提交
762 763 764 765
## Tests
if (UNIX)
  if (BUILD_SHARED_LIBS)
    # does some "make" stuff inside
E
Ebrahim Byagowi 已提交
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
    #add_test(NAME check-defs.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-defs.sh)
    #set_tests_properties(check-defs.sh PROPERTIES ENVIRONMENT "libs=.")

    # broken on cmake builds right now :(
    #add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
    #add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
    #set_tests_properties(check-symbols.sh check-libstdc++.sh PROPERTIES ENVIRONMENT "libs=.")

    if (NOT APPLE)
      add_test(NAME check-static-inits.sh
        COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/CMakeFiles/harfbuzz.dir/src # ugly hack
      )
      set_tests_properties(check-static-inits.sh PROPERTIES ENVIRONMENT "libs=.")
    endif ()
E
Ebrahim Byagowi 已提交
781
  else ()
E
Ebrahim Byagowi 已提交
782
    message(WARN "Enable BUILD_SHARED_LIBS for more tests.")
E
Ebrahim Byagowi 已提交
783 784
  endif ()

E
Ebrahim Byagowi 已提交
785
  if (IN_HB_DIST)
E
Ebrahim Byagowi 已提交
786 787 788 789 790 791 792 793
    add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
    add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
  endif ()

  add_test(NAME check-externs.sh COMMAND ./check-externs.sh WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
  add_test(NAME check-includes.sh COMMAND ./check-includes.sh WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
endif ()

K
Khaled Hosny 已提交
794 795
# Needs to come last so that variables defined above are passed to
# subdirectories.
E
Ebrahim Byagowi 已提交
796
add_subdirectory(test)