cmake_minimum_required ( VERSION 2.8.0 )
project ( harfbuzz )
enable_testing ( )
## Limit framework build to Xcode generator
if ( BUILD_FRAMEWORK )
# for a framework build on macOS, use:
# cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build
if ( NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode" )
message ( FATAL_ERROR
" Y o u s h o u l d u s e X c o d e g e n e r a t o r w i t h B U I L D _ F R A M E W O R K e n a b l e d " )
endif ( )
set ( CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)" )
set ( CMAKE_MACOSX_RPATH ON )
set ( BUILD_SHARED_LIBS ON )
endif ( )
## 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}" )
message ( FATAL_ERROR
"
I n - s o u r c e b u i l d s a r e n o t p e r m i t t e d ! M a k e a s e p a r a t e f o l d e r f o r "
" b u i l d i n g , e . g . , "
"
m k d i r b u i l d ; c d b u i l d ; c m a k e . . "
"
B e f o r e t h a t , r e m o v e t h e f i l e s c r e a t e d b y t h i s f a i l e d r u n w i t h "
"
r m - r f C M a k e C a c h e . t x t C M a k e F i l e s " )
endif ( )
## HarfBuzz build configurations
option ( HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF )
option ( HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF )
option ( HB_BUILTIN_UCDN "Use HarfBuzz provided UCDN" ON )
option ( HB_HAVE_GLIB "Enable glib unicode functions" OFF )
option ( HB_HAVE_ICU "Enable icu unicode functions" OFF )
if ( APPLE )
option ( HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON )
set ( CMAKE_MACOSX_RPATH ON )
endif ( )
if ( WIN32 )
option ( HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF )
option ( HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF )
endif ( )
option ( HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF )
if ( HB_BUILD_UTILS )
set ( HB_HAVE_GLIB ON )
set ( HB_HAVE_FREETYPE ON )
endif ( )
option ( HB_HAVE_GOBJECT "Enable GObject Bindings" OFF )
if ( HB_HAVE_GOBJECT )
set ( HB_HAVE_GLIB ON )
endif ( )
option ( HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF )
if ( HB_HAVE_INTROSPECTION )
set ( HB_HAVE_GOBJECT ON )
set ( HB_HAVE_GLIB ON )
endif ( )
option ( HB_DISABLE_TEST_PROGS OFF "Do not build some of the test programs, useful for continuous builds" )
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 ( )
include_directories ( AFTER
$ { P R O J E C T _ S O U R C E _ D I R } / s r c
$ { P R O J E C T _ B I N A R Y _ D I R } / s r c
)
add_definitions ( -DHAVE_OT )
add_definitions ( -DHAVE_FALLBACK )
## Functions and headers
include ( CheckFunctionExists )
include ( CheckIncludeFile )
macro ( check_funcs ) # Similar to AC_CHECK_FUNCS of autotools
foreach ( func_name ${ ARGN } )
string ( TOUPPER ${ func_name } definiton_to_add )
check_function_exists ( ${ func_name } HAVE_ ${ definiton_to_add } )
if ( ${ HAVE_${definiton_to_add } } )
add_definitions ( -DHAVE_ ${ definiton_to_add } )
endif ( )
endforeach ( )
endmacro ( )
check_funcs ( atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l )
check_include_file ( unistd.h HAVE_UNISTD_H )
if ( ${ HAVE_UNISTD_H } )
add_definitions ( -DHAVE_UNISTD_H )
endif ( )
check_include_file ( sys/mman.h HAVE_SYS_MMAN_H )
if ( ${ HAVE_SYS_MMAN_H } )
add_definitions ( -DHAVE_SYS_MMAN_H )
endif ( )
check_include_file ( xlocale.h HAVE_XLOCALE_H )
if ( ${ HAVE_XLOCALE_H } )
add_definitions ( -DHAVE_XLOCALE_H )
endif ( )
if ( MSVC )
add_definitions ( -wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS )
endif ( )
if ( BUILD_SHARED_LIBS )
if ( WIN32 AND NOT MINGW )
add_definitions ( "-DHB_EXTERN=__declspec(dllexport) extern" )
else ( )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" )
endif ( )
endif ( )
## Detect if we are running inside a distribution or regular repository folder
set ( IN_HB_DIST FALSE )
if ( EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog" )
# perhaps we are on dist directory
set ( IN_HB_DIST TRUE )
set ( HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h" )
endif ( )
## Extract variables from Makefile files
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 )
set ( listVar "" )
foreach ( f ${ ${var } } )
list ( APPEND listVar "${prefix}${f}" )
endforeach ( )
set ( ${ var } "${listVar}" PARENT_SCOPE )
endfunction ( )
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 )
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_SUBSET_sources ${ SRCSOURCES } )
add_prefix_to_list ( HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/" )
extract_make_variable ( HB_SUBSET_headers ${ SRCSOURCES } )
add_prefix_to_list ( HB_SUBSET_headers "${PROJECT_SOURCE_DIR}/src/" )
extract_make_variable ( HB_BASE_RAGEL_GENERATED_sources ${ SRCSOURCES } )
extract_make_variable ( HB_OT_RAGEL_GENERATED_sources ${ SRCSOURCES } )
if ( IN_HB_DIST )
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/" )
else ( )
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/" )
endif ( )
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_SUBSET_CLI_sources ${ UTILSOURCES } )
add_prefix_to_list ( HB_SUBSET_CLI_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/" )
file ( READ configure.ac CONFIGUREAC )
string ( REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${ CONFIGUREAC } )
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 } )
## Define ragel tasks
if ( NOT IN_HB_DIST )
find_program ( RAGEL "ragel" CMAKE_FIND_ROOT_PATH_BOTH )
if ( RAGEL )
message ( STATUS "ragel found at: ${RAGEL}" )
else ( )
message ( FATAL_ERROR "ragel not found, get it here -- http://www.complang.org/ragel/ or, use harfbuzz releases https://github.com/harfbuzz/harfbuzz/releases" )
endif ( )
foreach ( ragel_output IN ITEMS ${ HB_BASE_RAGEL_GENERATED_sources } ${ HB_OT_RAGEL_GENERATED_sources } )
string ( REGEX MATCH "([^/]+)\\.hh" temp ${ ragel_output } )
set ( target_name ${ CMAKE_MATCH_1 } )
add_custom_command ( OUTPUT ${ ragel_output }
C O M M A N D $ { R A G E L } - G 2 - o $ { r a g e l _ o u t p u t } $ { P R O J E C T _ S O U R C E _ D I R } / s r c / $ { t a r g e t _ n a m e } . r l - I $ { P R O J E C T _ S O U R C E _ D I R } $ { A R G N }
D E P E N D S $ { P R O J E C T _ S O U R C E _ D I R } / s r c / $ { t a r g e t _ n a m e } . r l
)
add_custom_target ( harfbuzz_ ${ target_name } DEPENDS ${ PROJECT_BINARY_DIR } /src/ ${ target_name } )
endforeach ( )
mark_as_advanced ( RAGEL )
endif ( )
## Generate hb-version.h
if ( NOT IN_HB_DIST )
set ( HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in" )
set ( HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h" )
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
" $ { H B _ V E R S I O N _ H } . t m p "
" $ { H B _ V E R S I O N _ H } "
)
file ( REMOVE "${HB_VERSION_H}.tmp" )
endif ( )
## Define sources and headers of the project
set ( project_sources
$ { H B _ B A S E _ s o u r c e s }
$ { H B _ B A S E _ R A G E L _ G E N E R A T E D _ s o u r c e s }
$ { H B _ F A L L B A C K _ s o u r c e s }
$ { H B _ O T _ s o u r c e s }
$ { H B _ O T _ R A G E L _ G E N E R A T E D _ s o u r c e s }
)
set ( subset_project_sources
$ { H B _ S U B S E T _ s o u r c e s }
)
set ( project_extra_sources )
set ( project_headers
$ { H B _ V E R S I O N _ H }
$ { H B _ B A S E _ h e a d e r s }
$ { H B _ O T _ h e a d e r s }
)
set ( subset_project_headers
$ { H B _ S U B S E T _ h e a d e r s }
)
## Find and include needed header folders and libraries
if ( HB_HAVE_FREETYPE )
include ( FindFreetype )
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" )
endif ( )
list ( APPEND THIRD_PARTY_LIBS ${ FREETYPE_LIBRARIES } )
include_directories ( AFTER ${ FREETYPE_INCLUDE_DIRS } )
add_definitions ( -DHAVE_FREETYPE=1 )
list ( APPEND project_sources ${ PROJECT_SOURCE_DIR } /src/hb-ft.cc )
list ( APPEND project_headers ${ PROJECT_SOURCE_DIR } /src/hb-ft.h )
# So check_funcs can find its headers
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 )
endif ( )
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 } )
mark_as_advanced ( GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY )
endif ( )
if ( HB_BUILTIN_UCDN )
include_directories ( src/hb-ucdn )
add_definitions ( -DHAVE_UCDN )
list ( APPEND project_sources ${ PROJECT_SOURCE_DIR } /src/hb-ucdn.cc )
list ( APPEND project_extra_sources ${ LIBHB_UCDN_sources } )
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 } )
mark_as_advanced ( GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR )
endif ( )
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 } )
mark_as_advanced ( ICU_INCLUDE_DIR ICU_LIBRARY )
endif ( )
if ( APPLE AND HB_HAVE_CORETEXT )
# Apple Advanced Typography
add_definitions ( -DHAVE_CORETEXT )
list ( APPEND project_sources ${ PROJECT_SOURCE_DIR } /src/hb-coretext.cc )
list ( APPEND project_headers ${ PROJECT_SOURCE_DIR } /src/hb-coretext.h )
find_library ( APPLICATION_SERVICES_FRAMEWORK ApplicationServices )
if ( APPLICATION_SERVICES_FRAMEWORK )
list ( APPEND THIRD_PARTY_LIBS ${ APPLICATION_SERVICES_FRAMEWORK } )
endif ( APPLICATION_SERVICES_FRAMEWORK )
mark_as_advanced ( APPLICATION_SERVICES_FRAMEWORK )
endif ( )
if ( WIN32 AND HB_HAVE_UNISCRIBE )
add_definitions ( -DHAVE_UNISCRIBE )
list ( APPEND project_sources ${ PROJECT_SOURCE_DIR } /src/hb-uniscribe.cc )
list ( APPEND project_headers ${ PROJECT_SOURCE_DIR } /src/hb-uniscribe.h )
list ( APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4 )
endif ( )
if ( WIN32 AND HB_HAVE_DIRECTWRITE )
add_definitions ( -DHAVE_DIRECTWRITE )
list ( APPEND project_sources ${ PROJECT_SOURCE_DIR } /src/hb-directwrite.cc )
list ( APPEND project_headers ${ PROJECT_SOURCE_DIR } /src/hb-directwrite.h )
list ( APPEND THIRD_PARTY_LIBS dwrite rpcrt4 )
endif ( )
if ( HB_HAVE_GOBJECT )
include ( FindPythonInterp )
include ( FindPerl )
# 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
H I N T S $ { P C _ g l i b _ m k e n u m s }
)
set ( GLIB_MKENUMS_CMD )
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
R E S U L T _ V A R I A B L E G L I B _ M K E N U M S _ P Y T H O N
O U T P U T _ Q U I E T E R R O R _ Q U I E T
)
if ( GLIB_MKENUMS_PYTHON EQUAL 0 )
message ( "${GLIB_MKENUMS} is a Python script." )
set ( GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" )
else ( )
execute_process ( COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
R E S U L T _ V A R I A B L E G L I B _ M K E N U M S _ P E R L
O U T P U T _ Q U I E T E R R O R _ Q U I E T
)
if ( GLIB_MKENUMS_PERL EQUAL 0 )
message ( "${GLIB_MKENUMS} is a PERL script." )
set ( GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" )
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 ( )
endif ( )
else ( )
set ( GLIB_MKENUMS_CMD "${GLIB_MKENUMS}" )
endif ( )
if ( NOT GLIB_MKENUMS_CMD )
message ( FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required" )
endif ( )
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
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c
)
list ( APPEND hb_gobject_structs_headers
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t - s t r u c t s . h
)
list ( APPEND hb_gobject_headers
$ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t . h
$ { h b _ g o b j e c t _ s t r u c t s _ h e a d e r s }
)
list ( APPEND hb_gobject_gen_headers
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h
)
add_custom_command (
O U T P U T $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h
C O M M A N D $ { G L I B _ M K E N U M S _ C M D }
- - t e m p l a t e = $ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t - e n u m s . h . t m p l
- - i d e n t i f i e r - p r e f i x h b _
- - s y m b o l - p r e f i x h b _ g o b j e c t
$ { h b _ g o b j e c t _ s t r u c t s _ h e a d e r s }
$ { p r o j e c t _ h e a d e r s }
> $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h . t m p
C O M M A N D " $ { C M A K E _ C O M M A N D } "
" - D E N U M _ I N P U T _ S R C = $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h . t m p "
" - D E N U M _ O U T P U T _ S R C = $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h "
- P $ { P R O J E C T _ S O U R C E _ D I R } / r e p l a c e - e n u m - s t r i n g s . c m a k e
D E P E N D S $ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t - e n u m s . h . t m p l
$ { h b _ g o b j e c t _ h e a d e r }
$ { p r o j e c t _ h e a d e r s }
)
add_custom_command (
O U T P U T $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c
C O M M A N D $ { G L I B _ M K E N U M S _ C M D }
- - t e m p l a t e = $ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c . t m p l
- - i d e n t i f i e r - p r e f i x h b _
- - s y m b o l - p r e f i x h b _ g o b j e c t
$ { h b _ g o b j e c t _ h e a d e r }
$ { p r o j e c t _ h e a d e r s }
> $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c . t m p
C O M M A N D " $ { C M A K E _ C O M M A N D } "
" - D E N U M _ I N P U T _ S R C = $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c . t m p "
" - D E N U M _ O U T P U T _ S R C = $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c "
- P $ { P R O J E C T _ S O U R C E _ D I R } / r e p l a c e - e n u m - s t r i n g s . c m a k e
D E P E N D S $ { P R O J E C T _ S O U R C E _ D I R } / s r c / h b - g o b j e c t - e n u m s . c c . t m p l
$ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / s r c / h b - g o b j e c t - e n u m s . h
$ { h b _ g o b j e c t _ h e a d e r }
$ { p r o j e c t _ h e a d e r s }
)
endif ( )
## Atomic ops availability detection
file ( WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
" v o i d memory_barrier ( void ) { __sync_synchronize ( ) ; }
i n t atomic_add ( int *i ) { r e t u r n __sync_fetch_and_add ( i, 1 ) ; }
i n t mutex_trylock ( int *m ) { r e t u r n __sync_lock_test_and_set ( m, 1 ) ; }
v o i d mutex_unlock ( int *m ) { __sync_lock_release ( m ) ; }
i n t main ( ) { r e t u r n 0 ; }
" )
try_compile ( HB_HAVE_INTEL_ATOMIC_PRIMITIVES
$ { P R O J E C T _ B I N A R Y _ D I R } / t r y _ c o m p i l e _ i n t e l _ a t o m i c _ p r i m i t i v e s
$ { P R O J E C T _ B I N A R Y _ D I R } / t r y _ c o m p i l e _ i n t e l _ a t o m i c _ p r i m i t i v e s . 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>
/ * T h i s r e q u i r e s S o l a r i s S t u d i o 1 2 . 2 o r n e w e r : * /
#include <mbarrier.h>
v o i d memory_barrier ( void ) { __machine_rw_barrier ( ) ; }
i n t atomic_add ( volatile unsigned *i ) { r e t u r n atomic_add_int_nv ( i, 1 ) ; }
v o i d * atomic_ptr_cmpxchg ( volatile void **target, void *cmp, void *newval ) { r e t u r n atomic_cas_ptr ( target, cmp, newval ) ; }
i n t main ( ) { r e t u r n 0 ; }
" )
try_compile ( HB_HAVE_SOLARIS_ATOMIC_OPS
$ { P R O J E C T _ B I N A R Y _ D I R } / t r y _ c o m p i l e _ s o l a r i s _ a t o m i c _ o p s
$ { P R O J E C T _ B I N A R Y _ D I R } / t r y _ c o m p i l e _ s o l a r i s _ a t o m i c _ o p s . c )
if ( HB_HAVE_SOLARIS_ATOMIC_OPS )
add_definitions ( -DHAVE_SOLARIS_ATOMIC_OPS )
endif ( )
## Define harfbuzz library
add_library ( harfbuzz ${ project_sources } ${ project_extra_sources } ${ project_headers } )
target_link_libraries ( harfbuzz ${ THIRD_PARTY_LIBS } )
## Define harfbuzz-subset library
add_library ( harfbuzz-subset ${ subset_project_sources } ${ subset_project_headers } )
add_dependencies ( harfbuzz-subset harfbuzz )
target_link_libraries ( harfbuzz-subset harfbuzz ${ THIRD_PARTY_LIBS } )
if ( UNIX OR MINGW )
# Make symbols link locally
link_libraries ( -Bsymbolic-functions )
if ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
# Make sure we don't link to libstdc++
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" )
set ( CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m" ) # libm
set ( CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "" )
set_target_properties ( harfbuzz PROPERTIES LINKER_LANGUAGE C )
set_target_properties ( harfbuzz-subset PROPERTIES LINKER_LANGUAGE C )
# No threadsafe statics as we do it ourselves
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics" )
endif ( )
endif ( )
## Define harfbuzz-gobject library
if ( HB_HAVE_GOBJECT )
add_library ( harfbuzz-gobject
$ { h b _ g o b j e c t _ s o u r c e s }
$ { h b _ g o b j e c t _ g e n _ s o u r c e s }
$ { h b _ g o b j e c t _ h e a d e r s }
$ { h b _ g o b j e c t _ g e n _ h e a d e r s }
)
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 ( )
# 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." )
set ( HB_HAVE_INTROSPECTION OFF )
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
H I N T S $ { P C _ g _ i r _ s c a n n e r }
)
find_program ( G_IR_COMPILER g-ir-compiler
H I N T S $ { P C _ g _ i r _ c o m p i l e r }
)
if ( WIN32 AND NOT MINGW )
# Note that since we already enable HB_HAVE_GOBJECT
# we would already have PYTHON_EXECUTABLE handy
set ( G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}" )
else ( )
set ( G_IR_SCANNER_CMD "${G_IR_SCANNER}" )
endif ( )
# We need to account for the varying output directories
# when we build using Visual Studio projects
if ( "${CMAKE_GENERATOR}" MATCHES "Visual Studio*" )
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 "" )
foreach ( hb_cflag ${ hb_cflags } )
list ( APPEND hb_defines_cflags "-D${hb_cflag}" )
endforeach ( hb_cflag )
# 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 ( )
set ( introspected_sources )
foreach ( f
$ { p r o j e c t _ h e a d e r s }
$ { p r o j e c t _ s o u r c e s }
$ { h b _ g o b j e c t _ g e n _ s o u r c e s }
$ { h b _ g o b j e c t _ g e n _ h e a d e r s }
$ { h b _ g o b j e c t _ s o u r c e s }
$ { h b _ g o b j e c t _ h e a d e r s }
)
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...
add_custom_command (
T A R G E T h a r f b u z z - g o b j e c t
P O S T _ B U I L D
C O M M A N D $ { G _ I R _ S C A N N E R _ C M D }
- - w a r n - a l l - - n o - l i b t o o l - - v e r b o s e
- n h b
- - n a m e s p a c e = H a r f B u z z
- - n s v e r s i o n = 0 . 0
- - i d e n t i f i e r - p r e f i x = h b _
- - i n c l u d e G O b j e c t - 2 . 0
- - p k g - e x p o r t = h a r f b u z z
- - c f l a g s - b e g i n
- I $ { P R O J E C T _ S O U R C E _ D I R } / s r c
- I $ { P R O J E C T _ B I N A R Y _ D I R } / s r c
$ { h b _ i n c l u d e d i r _ c f l a g s }
$ { h b _ d e f i n e s _ c f l a g s }
- D H B _ H
- D H B _ H _ I N
- D H B _ O T _ H
- D H B _ O T _ H _ I N
- D H B _ G O B J E C T _ H
- D H B _ G O B J E C T _ H _ I N
- D H B _ E X T E R N =
- - c f l a g s - e n d
- - l i b r a r y = h a r f b u z z - g o b j e c t
- - l i b r a r y = h a r f b u z z
- L $ { h b _ l i b p a t h }
$ { e x t r a _ l i b s }
$ { i n t r o s p e c t e d _ s o u r c e s }
- o $ { h b _ l i b p a t h } / H a r f B u z z - 0 . 0 . g i r
D E P E N D S h a r f b u z z - g o b j e c t h a r f b u z z
)
add_custom_command (
T A R G E T h a r f b u z z - g o b j e c t
P O S T _ B U I L D
C O M M A N D " $ { G _ I R _ C O M P I L E R } "
- - v e r b o s e - - d e b u g
- - i n c l u d e d i r $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R }
$ { h b _ l i b p a t h } / H a r f B u z z - 0 . 0 . g i r
- o $ { h b _ l i b p a t h } / H a r f B u z z - 0 . 0 . t y p e l i b
D E P E N D S $ { h b _ l i b p a t h } / H a r f B u z z - 0 . 0 . g i r h a r f b u z z - g o b j e c t
)
endif ( )
## Additional framework build configs
if ( BUILD_FRAMEWORK )
set ( CMAKE_MACOSX_RPATH ON )
set_target_properties ( harfbuzz PROPERTIES
F R A M E W O R K T R U E
P U B L I C _ H E A D E R " $ { p r o j e c t _ h e a d e r s } "
X C O D E _ A T T R I B U T E _ I N S T A L L _ P A T H " @ r p a t h "
)
set ( MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz" )
set ( MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}" )
set ( MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}" )
endif ( )
## Additional harfbuzz build artifacts
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-subset ${ HB_SUBSET_CLI_sources } )
target_link_libraries ( hb-subset harfbuzz harfbuzz-subset )
add_executable ( hb-ot-shape-closure ${ HB_OT_SHAPE_CLOSURE_sources } )
target_link_libraries ( hb-ot-shape-closure harfbuzz )
mark_as_advanced ( CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES )
endif ( )
## Install
include ( GNUInstallDirs )
if ( NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
install ( FILES ${ project_headers } DESTINATION ${ CMAKE_INSTALL_INCLUDEDIR } /harfbuzz )
if ( HB_HAVE_GOBJECT )
install ( FILES ${ hb_gobject_headers } ${ hb_gobject_gen_headers } DESTINATION ${ CMAKE_INSTALL_INCLUDEDIR } /harfbuzz )
endif ( )
endif ( )
if ( NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
install ( TARGETS harfbuzz
A R C H I V E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
L I B R A R Y D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
F R A M E W O R K D E S T I N A T I O N L i b r a r y / F r a m e w o r k s
)
if ( HB_BUILD_UTILS )
install ( TARGETS hb-view
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
)
install ( TARGETS hb-view
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
)
install ( TARGETS hb-shape
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
)
install ( TARGETS hb-ot-shape-closure
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
)
endif ( )
if ( HB_HAVE_GOBJECT )
install ( TARGETS harfbuzz-gobject
A R C H I V E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
L I B R A R Y D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R }
R U N T I M E D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ B I N D I R }
)
if ( HB_HAVE_INTROSPECTION )
if ( "${CMAKE_GENERATOR}" MATCHES "Visual Studio*" )
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"
D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ D A T A R O O T D I R } / g i r - 1 . 0
)
install ( FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ L I B D I R } / g i r e p o s i t o r y - 1 . 0
)
endif ( )
endif ( )
endif ( )
if ( UNIX AND CMAKE_GENERATOR STREQUAL "Ninja" )
if ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics" )
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics" )
endif ( )
if ( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color" )
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color" )
endif ( )
endif ( )
## src/ executables
if ( NOT HB_DISABLE_TEST_PROGS )
foreach ( prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag )
set ( prog_name ${ prog } )
if ( ${ prog_name } STREQUAL "test" )
# test can not be used as a valid executable name on cmake, lets special case it
set ( prog_name test-test )
endif ( )
add_executable ( ${ prog_name } ${ PROJECT_SOURCE_DIR } /src/ ${ prog } .cc )
target_link_libraries ( ${ prog_name } harfbuzz ${ THIRD_PARTY_LIBS } )
endforeach ( )
set_target_properties ( hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN" )
endif ( )
## Tests
if ( UNIX OR MINGW )
if ( BUILD_SHARED_LIBS )
# generate harfbuzz.def after build completion
string ( REPLACE ";" " " space_separated_headers "${project_headers}" )
add_custom_command ( TARGET harfbuzz POST_BUILD
C O M M A N D $ { C M A K E _ C O M M A N D } - E e n v " h e a d e r s = $ { s p a c e _ s e p a r a t e d _ h e a d e r s } " p y t h o n $ { P R O J E C T _ S O U R C E _ D I R } / s r c / g e n - d e f . p y $ { P R O J E C T _ B I N A R Y _ D I R } / h a r f b u z z . d e f
W O R K I N G _ D I R E C T O R Y $ { P R O J E C T _ S O U R C E _ D I R } / s r c )
add_test ( NAME check-static-inits.sh
C O M M A N D $ { P R O J E C T _ S O U R C E _ D I R } / s r c / c h e c k - s t a t i c - i n i t s . s h
W O R K I N G _ D I R E C T O R Y $ { P R O J E C T _ B I N A R Y _ D I R } $ { C M A K E _ F I L E S _ D I R E C T O R Y } / h a r f b u z z . d i r / s r c # ugly hack
)
add_test ( NAME check-libstdc++.sh COMMAND ${ PROJECT_SOURCE_DIR } /src/check-libstdc++.sh )
add_test ( NAME check-symbols.sh COMMAND ${ PROJECT_SOURCE_DIR } /src/check-symbols.sh )
add_test ( NAME check-defs.sh COMMAND ${ PROJECT_SOURCE_DIR } /src/check-defs.sh )
set_tests_properties (
c h e c k - s t a t i c - i n i t s . s h c h e c k - l i b s t d c + + . s h c h e c k - s y m b o l s . s h c h e c k - d e f s . s h
P R O P E R T I E S
E N V I R O N M E N T " l i b s = . ; s r c d i r = $ { P R O J E C T _ S O U R C E _ D I R } / s r c "
S K I P _ R E T U R N _ C O D E 7 7 )
endif ( )
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 (
c h e c k - c - l i n k a g e - d e c l s . s h c h e c k - h e a d e r - g u a r d s . s h c h e c k - e x t e r n s . s h c h e c k - i n c l u d e s . s h
P R O P E R T I E S
W O R K I N G _ D I R E C T O R Y $ { P R O J E C T _ S O U R C E _ D I R } / s r c
S K I P _ R E T U R N _ C O D E 7 7 )
endif ( )
# Needs to come last so that variables defined above are passed to
# subdirectories.
add_subdirectory ( test )