CMakeLists.txt 27.2 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

## Limit framework build to Xcode generator
if (BUILD_FRAMEWORK)
8 9
  # for a framework build on macOS, use:
  # cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build
10 11 12 13
  if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
    message(FATAL_ERROR
      "You should use Xcode generator with BUILD_FRAMEWORK enabled")
  endif ()
14 15 16
  set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
  set (CMAKE_MACOSX_RPATH ON)
  set (BUILD_SHARED_LIBS ON)
17 18 19
endif ()


E
Ebrahim Byagowi 已提交
20 21
## 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 已提交
22 23 24 25 26 27 28 29 30 31 32
  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 已提交
33

E
ebraminio 已提交
34 35

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

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

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

E
Ebrahim Byagowi 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
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 已提交
85
include_directories(AFTER
86
  ${PROJECT_SOURCE_DIR}/src
E
ebraminio 已提交
87
  ${PROJECT_BINARY_DIR}/src
E
Ebrahim Byagowi 已提交
88
)
E
ebraminio 已提交
89 90

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

93 94 95 96 97

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

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

E
ebraminio 已提交
120 121 122 123 124

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

125 126 127 128 129 130 131 132
if (BUILD_SHARED_LIBS)
  if (WIN32 AND NOT MINGW)
    add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
  else ()
    set (CMAKE_CXX_FLAGS "-fvisibility=hidden ${CMAKE_CXX_FLAGS}")
    set (CMAKE_C_FLAGS "-fvisibility=hidden ${CMAKE_CXX_FLAGS}")
    add_definitions("-DHB_EXTERN=__attribute__((visibility(\"default\"))) extern")
  endif ()
E
ebraminio 已提交
133 134
endif ()

E
Ebrahim Byagowi 已提交
135

136
## Detect if we are running inside a distribution or regular repository folder
137
set (IN_HB_DIST FALSE)
138
if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
E
ebraminio 已提交
139
  # perhaps we are on dist directory
140 141
  set (IN_HB_DIST TRUE)
  set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
E
ebraminio 已提交
142 143
endif ()

E
Ebrahim Byagowi 已提交
144

145
## Extract variables from Makefile files
146 147 148 149 150 151 152 153
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)
154
  set (listVar "")
155
  foreach (f ${${var}})
156
    list(APPEND listVar "${prefix}${f}")
157
  endforeach ()
158
  set (${var} "${listVar}" PARENT_SCOPE)
159 160
endfunction ()

E
ebraminio 已提交
161 162 163
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)
164

165 166 167 168 169 170 171 172 173 174 175 176 177
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})
178
if (IN_HB_DIST)
179 180
  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/")
181
else ()
182 183
  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/")
184
endif ()
185

186 187 188 189 190 191 192 193 194
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 已提交
195

196

197 198
file(READ configure.ac CONFIGUREAC)
string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
199 200 201 202
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 已提交
203

204

205
## Define ragel tasks
E
ebraminio 已提交
206
if (NOT IN_HB_DIST)
207
  find_program(RAGEL "ragel" CMAKE_FIND_ROOT_PATH_BOTH)
E
ebraminio 已提交
208 209 210

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

215 216
  foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources} ${HB_OT_RAGEL_GENERATED_sources})
    string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
217
    set (target_name ${CMAKE_MATCH_1})
218 219 220
    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
221
    )
222 223
    add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
  endforeach ()
E
ebraminio 已提交
224 225

  mark_as_advanced(RAGEL)
226
endif ()
E
Ebrahim Byagowi 已提交
227

E
ebraminio 已提交
228

229 230
## Generate hb-version.h
if (NOT IN_HB_DIST)
231 232
  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 已提交
233 234 235 236
  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"
237
    "${HB_VERSION_H}"
238
  )
E
ebraminio 已提交
239 240 241
  file(REMOVE "${HB_VERSION_H}.tmp")
endif ()

242

243
## Define sources and headers of the project
244
set (project_sources
245 246
  ${HB_BASE_sources}
  ${HB_BASE_RAGEL_GENERATED_sources}
E
ebraminio 已提交
247

C
Chun-wei Fan 已提交
248
  ${HB_FALLBACK_sources}
249 250
  ${HB_OT_sources}
  ${HB_OT_RAGEL_GENERATED_sources}
251
)
E
ebraminio 已提交
252

253
set (project_extra_sources)
254

255
set (project_headers
E
ebraminio 已提交
256 257 258 259
  ${HB_VERSION_H}

  ${HB_BASE_headers}
  ${HB_OT_headers}
260
)
E
ebraminio 已提交
261

E
Ebrahim Byagowi 已提交
262 263

## Find and include needed header folders and libraries
E
ebraminio 已提交
264
if (HB_HAVE_FREETYPE)
265
  include (FindFreetype)
266 267
  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")
268
  endif ()
E
ebraminio 已提交
269

270 271 272
  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 已提交
273

274 275
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
276

277 278 279
  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 已提交
280 281
endif ()

282 283 284 285 286 287 288 289 290 291 292 293
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 已提交
294 295

  mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
296 297
endif ()

E
ebraminio 已提交
298 299 300 301
if (HB_BUILTIN_UCDN)
  include_directories(src/hb-ucdn)
  add_definitions(-DHAVE_UCDN)

302 303
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ucdn.cc)
  list(APPEND project_extra_sources ${LIBHB_UCDN_sources})
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
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 已提交
323 324

  mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
E
ebraminio 已提交
325 326
endif ()

327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
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 已提交
343 344

  mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY)
345 346
endif ()

E
ebraminio 已提交
347 348 349 350
if (APPLE AND HB_HAVE_CORETEXT)
  # Apple Advanced Typography
  add_definitions(-DHAVE_CORETEXT)

351 352
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
E
ebraminio 已提交
353 354 355

  find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
  if (APPLICATION_SERVICES_FRAMEWORK)
356
    list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
E
ebraminio 已提交
357
  endif (APPLICATION_SERVICES_FRAMEWORK)
E
ebraminio 已提交
358 359
  
  mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
E
ebraminio 已提交
360 361 362 363 364
endif ()

if (WIN32 AND HB_HAVE_UNISCRIBE)
  add_definitions(-DHAVE_UNISCRIBE)

365 366
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
E
ebraminio 已提交
367

368
  list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
E
ebraminio 已提交
369 370 371 372 373
endif ()

if (WIN32 AND HB_HAVE_DIRECTWRITE)
  add_definitions(-DHAVE_DIRECTWRITE)

374 375
  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-directwrite.cc)
  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
E
ebraminio 已提交
376

377
  list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
E
ebraminio 已提交
378
endif ()
E
Ebrahim Byagowi 已提交
379

380
if (HB_HAVE_GOBJECT)
381 382
  include (FindPythonInterp)
  include (FindPerl)
383 384 385 386 387 388
  
  # 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}
389 390
  )
  set (GLIB_MKENUMS_CMD)
391 392 393 394 395 396 397 398 399

  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
400
    )
401 402
    if (GLIB_MKENUMS_PYTHON EQUAL 0)
      message("${GLIB_MKENUMS} is a Python script.")
403
      set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}")
404 405 406 407
    else ()
      execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
        RESULT_VARIABLE GLIB_MKENUMS_PERL
        OUTPUT_QUIET ERROR_QUIET
408
      )
409 410
      if (GLIB_MKENUMS_PERL EQUAL 0)
        message("${GLIB_MKENUMS} is a PERL script.")
411
        set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}")
412 413 414 415
      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 ()
416
    endif ()
417
  else ()
418
    set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}")
419 420 421
  endif ()
  if (NOT GLIB_MKENUMS_CMD)
    message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required")
422
  endif ()
423 424 425 426 427 428 429 430 431 432 433 434

  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
435
  )
436 437
  list(APPEND hb_gobject_structs_headers
    ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h
438
  )
439 440
  list(APPEND hb_gobject_headers
    ${PROJECT_SOURCE_DIR}/src/hb-gobject.h
441
    ${hb_gobject_structs_headers}
442
  )
443 444
  list(APPEND hb_gobject_gen_headers
    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
445
  )
446

447
  add_custom_command(
448 449 450 451 452
    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
453
      ${hb_gobject_structs_headers}
454 455 456 457 458 459 460 461 462
      ${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}
463
  )
464

465
  add_custom_command(
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
    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}
482
  )
483
endif ()
E
ebraminio 已提交
484

E
Ebrahim Byagowi 已提交
485

486 487 488 489 490 491
## 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); }
492
		int main () { return 0; }
493 494 495
")
try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES
  ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives
R
rdb 已提交
496
  ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c)
497 498 499 500 501 502 503 504 505 506 507
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); }
508
		int main () { return 0; }
509 510 511
")
try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS
  ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops
R
rdb 已提交
512
  ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c)
E
ebraminio 已提交
513 514
if (HB_HAVE_SOLARIS_ATOMIC_OPS)
  add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS)
515 516
endif ()

E
Ebrahim Byagowi 已提交
517 518

## Define harfbuzz library
519
add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
E
ebraminio 已提交
520 521
target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})

522 523 524 525 526 527 528 529 530 531 532 533 534
if (UNIX OR MINGW)
  # Make symbols link locally
  link_libraries(-Bsymbolic-functions)

  # Make sure we don't link to libstdc++
  set (CMAKE_CXX_FLAGS "-fno-rtti -fno-exceptions ${CMAKE_CXX_FLAGS}")
  if (NOT APPLE)
    set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
    set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
    set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
  endif ()
endif ()

E
Ebrahim Byagowi 已提交
535

536 537 538 539 540 541 542
## 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}
543
  )
544 545 546 547
  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 已提交
548

549 550 551 552
# 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.")
553
    set (HB_HAVE_INTROSPECTION OFF)
554 555 556 557 558 559 560 561 562 563
  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}
564
  )
565 566 567

  find_program(G_IR_COMPILER g-ir-compiler
    HINTS ${PC_g_ir_compiler}
568
  )
569 570 571 572

  if (WIN32 AND NOT MINGW)
    # Note that since we already enable HB_HAVE_GOBJECT
    # we would already have PYTHON_EXECUTABLE handy
573
    set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}")
574
  else ()
575
    set (G_IR_SCANNER_CMD "${G_IR_SCANNER}")
576 577 578 579
  endif ()

  # We need to account for the varying output directories
  # when we build using Visual Studio projects
580
  if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
581 582 583 584 585 586 587
    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 "")
588
  foreach (hb_cflag ${hb_cflags})
589
    list(APPEND hb_defines_cflags "-D${hb_cflag}")
590
  endforeach (hb_cflag)
591 592 593 594 595 596 597 598 599

  # 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 ()

600
  set (introspected_sources)
601 602 603 604 605 606 607
  foreach (f
    ${project_headers}
    ${project_sources}
    ${hb_gobject_gen_sources}
    ${hb_gobject_gen_headers}
    ${hb_gobject_sources}
    ${hb_gobject_headers}
E
Ebrahim Byagowi 已提交
608
  )
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
    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...
627
  add_custom_command(
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
    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
658
  )
659

660
  add_custom_command(
661 662 663 664 665 666 667 668
    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
669
  )
670 671
endif ()

E
Ebrahim Byagowi 已提交
672

673 674
## Additional framework build configs
if (BUILD_FRAMEWORK)
675
  set (CMAKE_MACOSX_RPATH ON)
676 677 678 679 680
  set_target_properties(harfbuzz PROPERTIES
    FRAMEWORK TRUE
    PUBLIC_HEADER "${project_headers}"
    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
  )
681 682 683
  set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
  set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
  set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}")
684 685 686
endif ()


E
Ebrahim Byagowi 已提交
687
## Additional harfbuzz build artifacts
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
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 已提交
708

E
Ebrahim Byagowi 已提交
709
  mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES)
710 711
endif ()

E
Ebrahim Byagowi 已提交
712

E
ebraminio 已提交
713
## Install
714
include (GNUInstallDirs)
715

E
ebraminio 已提交
716
if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
717
  install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
718
  if (HB_HAVE_GOBJECT)
719
    install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
720
  endif ()
E
ebraminio 已提交
721 722 723 724
endif ()

if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
  install(TARGETS harfbuzz
725 726 727
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
728
    FRAMEWORK DESTINATION Library/Frameworks
729
  )
C
Chun-wei Fan 已提交
730 731
  if (HB_BUILD_UTILS)
    install(TARGETS hb-view
732
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
733 734
    )
    install(TARGETS hb-view
735
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
736 737 738
    )

    install(TARGETS hb-shape
739
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
740 741 742
    )

    install(TARGETS hb-ot-shape-closure
743
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
C
Chun-wei Fan 已提交
744 745
    )
  endif ()
746 747
  if (HB_HAVE_GOBJECT)
    install(TARGETS harfbuzz-gobject
748 749 750
      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
751
    )
752
    if (HB_HAVE_INTROSPECTION)
753
      if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
754 755 756 757 758 759
        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"
760
        DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0
E
Ebrahim Byagowi 已提交
761
      )
762 763

      install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
764 765
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0
      )
766
    endif ()
767
  endif ()
E
ebraminio 已提交
768
endif ()
K
Khaled Hosny 已提交
769

770 771 772 773 774 775 776 777 778 779
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 已提交
780

E
Ebrahim Byagowi 已提交
781

E
Ebrahim Byagowi 已提交
782
## Tests
783
if (UNIX OR MINGW)
E
Ebrahim Byagowi 已提交
784 785
  if (BUILD_SHARED_LIBS)
    # does some "make" stuff inside
E
Ebrahim Byagowi 已提交
786
    #add_test(NAME check-defs.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-defs.sh)
787
    #set_tests_properties(check-defs.sh PROPERTIES ENVIRONMENT "libs=.")
788 789 790

    add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
    set_tests_properties(check-symbols.sh PROPERTIES ENVIRONMENT "libs=.")
E
Ebrahim Byagowi 已提交
791 792

    if (NOT APPLE)
793
      add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
E
Ebrahim Byagowi 已提交
794 795 796 797
      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
      )
798 799
      set_tests_properties(check-libstdc++.sh check-static-inits.sh
        PROPERTIES ENVIRONMENT "libs=.")
E
Ebrahim Byagowi 已提交
800
    endif ()
E
Ebrahim Byagowi 已提交
801 802
  endif ()

803 804 805 806 807 808 809
  add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
  add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
  add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
  add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
  set_tests_properties(
    check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
    PROPERTIES WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
E
Ebrahim Byagowi 已提交
810 811
endif ()

K
Khaled Hosny 已提交
812 813
# Needs to come last so that variables defined above are passed to
# subdirectories.
R
rdb 已提交
814
add_subdirectory(test)