Skip to content

Commit 84d95cb

Browse files
authored
[ftgl] Download instead of bundle and bump from 2.1.2 to 2.4, and use CMake target (#21898)
ROOT's builtin FTGL version was forked 20 years ago from libftgl 2.1.2, and some temporary patches were applied on top, some of them were also in the upstream version. Upstream version evolved until 2.4.0, whereas ROOT stayed with minimal changes wrt 2.1.2 #21898 (comment) Herein, to reduce vulnerability surface, codebase size, and easen maintenance, ROOT's ancient builtin FTGL version is removed and replace with an on-the-fly builtin downloaded from LCG at version 2.4.0, which matches the version that other distributions such as Opensuse or Debian have. Like those distros, we need to apply some compilation patches because 2.4.0 was released with a few compilation errors that never got a 2.4.1 release, since FTGL is unmaintained since 6 years. In particular, a type error depending on the system Freetype version, a private header file removed from the CMakeLists, and an optional nullptr access prevention that popped up in Debian bug reports as well as ROOT whenever passing strings not following the UTF8 convention / update in newer FTGL versions. FTGL external or builtin-download can be used indistinctly now, but external is recommended to rely on maintained system packages by distro.
1 parent 9c1c707 commit 84d95cb

64 files changed

Lines changed: 239 additions & 5309 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/root-ci-config/buildconfig/alma10-clang_ninja.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ CMAKE_C_COMPILER=clang
22
CMAKE_CXX_COMPILER=clang++
33
CMAKE_GENERATOR=Ninja
44
builtin_freetype=ON
5+
builtin_ftgl=ON
56
builtin_gif=ON
67
builtin_gl2ps=ON
78
builtin_jpeg=ON

builtins/freetype/CMakeLists.txt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
# **PLEASE UPDATE ALSO THE FOLLOWING LINE WHEN UPDATING THE VERSION**
88
# 22 Mar 2026, https://github.com/freetype/freetype/releases/tag/VER-2-14-3
9-
set(FREETYPE_VERSION 2.14.3)
10-
set(FREETYPE_HASH "e61b31ab26358b946e767ed7eb7f4bb2e507da1cfefeb7a8861ace7fd5c899a1")
9+
set(ROOT_FREETYPE_VERSION 2.14.3)
10+
set(ROOT_FREETYPE_HASH "e61b31ab26358b946e767ed7eb7f4bb2e507da1cfefeb7a8861ace7fd5c899a1")
1111

1212
set(FREETYPE_PREFIX ${CMAKE_BINARY_DIR}/builtins/FREETYPE-prefix)
1313

@@ -34,8 +34,8 @@ set(FREETYPE_LIBRARY ${FREETYPE_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}freety
3434

3535
ExternalProject_Add(
3636
BUILTIN_FREETYPE
37-
URL ${lcgpackages}/freetype-${FREETYPE_VERSION}.tar.gz
38-
URL_HASH SHA256=${FREETYPE_HASH}
37+
URL ${lcgpackages}/freetype-${ROOT_FREETYPE_VERSION}.tar.gz
38+
URL_HASH SHA256=${ROOT_FREETYPE_HASH}
3939
PREFIX ${FREETYPE_PREFIX}
4040
CMAKE_ARGS -G ${CMAKE_GENERATOR}
4141
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
@@ -75,9 +75,8 @@ if(builtin_zlib)
7575
add_dependencies(BUILTIN_FREETYPE BUILTIN_ZLIB)
7676
endif()
7777

78-
# Set the canonical output of find_package according to
79-
# https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#standard-variable-names
78+
# Following https://cmake.org/cmake/help/latest/module/FindFreetype.html
8079
set(FREETYPE_INCLUDE_DIRS ${incdir} PARENT_SCOPE)
8180
set(FREETYPE_LIBRARIES ${FREETYPE_LIBRARY} PARENT_SCOPE)
8281
set(Freetype_FOUND TRUE PARENT_SCOPE)
83-
set(Freetype_VERSION ${FREETYPE_VERSION} PARENT_SCOPE)
82+
set(Freetype_VERSION ${ROOT_FREETYPE_VERSION} PARENT_SCOPE)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
From b043877060efafcfa00f1d07c264d69e32e5d3a9 Mon Sep 17 00:00:00 2001
2+
From: Frank Heckenbach <f.heckenbach@fh-soft.de>
3+
Date: Tue, 21 May 2019 23:09:18 +0200
4+
Subject: [PATCH] src/CMakeLists.txt: remove FTLibrary.h from
5+
libftgl_la_SOURCES (it's only in ftgl_headers)
6+
7+
---
8+
src/CMakeLists.txt | 1 -
9+
1 file changed, 1 deletion(-)
10+
11+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
12+
index 693e49f..b0f26f6 100644
13+
--- a/src/CMakeLists.txt
14+
+++ b/src/CMakeLists.txt
15+
@@ -26,7 +26,6 @@ SET(libftgl_la_SOURCES
16+
FTGlyphContainer.h
17+
FTInternals.h
18+
FTLibrary.cpp
19+
- FTLibrary.h
20+
FTList.h
21+
FTPoint.cpp
22+
FTSize.cpp
23+
--
24+
2.34.1
25+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
diff --git a/src/FTContour.cpp b/src/FTContour.cpp
2+
index c668d32..ef13576 100644
3+
--- a/src/FTContour.cpp
4+
+++ b/src/FTContour.cpp
5+
@@ -174,7 +174,7 @@ void FTContour::SetParity(int parity)
6+
}
7+
8+
9+
-FTContour::FTContour(FT_Vector* contour, char* tags, unsigned int n)
10+
+FTContour::FTContour(FT_Vector* contour, unsigned char* tags, unsigned int n)
11+
{
12+
FTPoint prev, cur(contour[(n - 1) % n]), next(contour[0]);
13+
double olddir, dir = atan2((next - cur).Y(), (next - cur).X());
14+
diff --git a/src/FTContour.h b/src/FTContour.h
15+
index d2d187c..dc64e3a 100644
16+
--- a/src/FTContour.h
17+
+++ b/src/FTContour.h
18+
@@ -52,7 +52,7 @@ class FTContour
19+
* @param pointTags
20+
* @param numberOfPoints
21+
*/
22+
- FTContour(FT_Vector* contour, char* pointTags, unsigned int numberOfPoints);
23+
+ FTContour(FT_Vector* contour, unsigned char* pointTags, unsigned int numberOfPoints);
24+
25+
/**
26+
* Destructor
27+
diff --git a/src/FTVectoriser.cpp b/src/FTVectoriser.cpp
28+
index 26e7da8..53d738e 100644
29+
--- a/src/FTVectoriser.cpp
30+
+++ b/src/FTVectoriser.cpp
31+
@@ -168,7 +168,7 @@ void FTVectoriser::ProcessContours()
32+
for(int i = 0; i < ftContourCount; ++i)
33+
{
34+
FT_Vector* pointList = &outline.points[startIndex];
35+
- char* tagList = &outline.tags[startIndex];
36+
+ unsigned char* tagList = (unsigned char*)&outline.tags[startIndex];
37+
38+
endIndex = outline.contours[i];
39+
contourLength = (endIndex - startIndex) + 1;

builtins/ftgl/CMakeLists.txt

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.
2+
# All rights reserved.
3+
#
4+
# For the licensing terms see $ROOTSYS/LICENSE.
5+
# For the list of contributors see $ROOTSYS/README/CREDITS.
6+
7+
# **PLEASE UPDATE ALSO THE FOLLOWING LINE WHEN UPDATING THE VERSION**
8+
# 7 Feb 2019, https://github.com/frankheckenbach/ftgl/releases/tag/v2.4.0
9+
set(ROOT_FTGL_VERSION 2.4.0)
10+
set(ROOT_FTGL_HASH "aa97da1c3442a8fd3941037655df18016d70b5266381c81d81e8b5335f196ea8")
11+
if (CMAKE_BUILD_TYPE MATCHES Debug)
12+
set(ROOT_FTGL_POSTFIX d)
13+
endif()
14+
# Cherry-pick https://github.com/frankheckenbach/ftgl/commit/835f2ba7911a6c15a1a314d5e3267fa089b5a319 :
15+
set(ROOT_FTGL_PATCH_FILE_1 "${CMAKE_CURRENT_SOURCE_DIR}/0001-src-CMakeLists.txt-remove-FTLibrary.h-from-libftgl_l.patch")
16+
# From https://github.com/frankheckenbach/ftgl/issues/22, see also https://github.com/xmake-io/xmake-repo/pull/9040/changes and https://github.com/root-project/root/commit/a028d13255f0c2d0c84f2e1b99ccb6a112598e0c
17+
if(Freetype_VERSION VERSION_GREATER_EQUAL 2.13.3) # https://github.com/root-project/root/commit/a028d13255f0c2d0c84f2e1b99ccb6a112598e0c
18+
set(ROOT_FTGL_PATCH_FILE_2 "${CMAKE_CURRENT_SOURCE_DIR}/0002-fix-type-error.patch")
19+
else()
20+
set(ROOT_FTGL_PATCH_FILE_2 "")
21+
endif()
22+
set(ROOT_FTGL_PATCH_FILE_3 "${CMAKE_CURRENT_SOURCE_DIR}/prevent_nullptr_access.patch") # https://github.com/root-project/root/issues/22076#issuecomment-4335481094
23+
set(ROOT_FTGL_PREFIX ${CMAKE_BINARY_DIR}/builtins/FTGL-prefix)
24+
set(ROOT_FTGL_LIBRARY ${ROOT_FTGL_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ftgl${ROOT_FTGL_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
25+
26+
if (NOT DEFINED GIT_EXECUTABLE)
27+
set(GIT_EXECUTABLE "git")
28+
endif()
29+
30+
if(NOT EXISTS "${ROOT_FTGL_PREFIX}/src/BUILTIN_FTGL/._patched")
31+
set(ROOT_FTGL_PATCH_COMMAND PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace
32+
${ROOT_FTGL_PATCH_FILE_1}
33+
${ROOT_FTGL_PATCH_FILE_2}
34+
${ROOT_FTGL_PATCH_FILE_3}
35+
${CMAKE_CURRENT_SOURCE_DIR}/ftgl-marker.diff)
36+
endif()
37+
38+
include(ExternalProject)
39+
40+
# Clear cache variables set by find_package(FTGL)
41+
# to ensure that we use the builtin version
42+
foreach(var FTGL_LIBRARIES FTGL_LIBRARY FTGL_LIBRARY_DEBUG FTGL_LIBRARY_RELEASE FTGL_FOUND FTGL_VERSION FTGL_INCLUDE_DIR FTGL_LIBRARY FTGL_LIBRARIES)
43+
unset(${var})
44+
unset(${var} CACHE)
45+
endforeach()
46+
47+
if(WIN32 AND NOT CMAKE_GENERATOR MATCHES Ninja)
48+
if(winrtdebug)
49+
set(ROOT_FTGL_BUILD_COMMAND_FLAGS "--config Debug")
50+
else()
51+
set(ROOT_FTGL_BUILD_COMMAND_FLAGS "--config $<IF:$<CONFIG:Debug,RelWithDebInfo>,RelWithDebInfo,Release>")
52+
endif()
53+
endif()
54+
55+
ExternalProject_Add(BUILTIN_FTGL
56+
PREFIX ${ROOT_FTGL_PREFIX}
57+
URL ${lcgpackages}/ftgl-${ROOT_FTGL_VERSION}.tar.gz
58+
URL_HASH SHA256=${ROOT_FTGL_HASH}
59+
${ROOT_FTGL_PATCH_COMMAND}
60+
61+
LOG_DOWNLOAD TRUE
62+
LOG_CONFIGURE TRUE
63+
LOG_BUILD TRUE
64+
LOG_PATCH TRUE
65+
LOG_INSTALL TRUE
66+
LOG_OUTPUT_ON_FAILURE TRUE
67+
68+
CMAKE_ARGS -G ${CMAKE_GENERATOR}
69+
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
70+
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
71+
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
72+
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
73+
-DBUILD_SHARED_LIBS:BOOL=FALSE
74+
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=TRUE
75+
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
76+
-DFREETYPE_LIBRARY=${FREETYPE_LIBRARIES} # Seems to be needed for Win32 (CMake 3.30 Freetype.cmake)
77+
-DFREETYPE_INCLUDE_DIRS=${FREETYPE_INCLUDE_DIRS} # Seems to be needed for Win32 (CMake 3.30 Freetype.cmake)
78+
-DFREETYPE_DIR=${FREETYPE_INCLUDE_DIRS}/../ # Seems to be needed for Win32 (CMake 3.30 Freetype.cmake)
79+
BUILD_COMMAND ${CMAKE_COMMAND} --build . ${ROOT_FTGL_BUILD_COMMAND_FLAGS}
80+
INSTALL_COMMAND ${CMAKE_COMMAND} --build . ${ROOT_FTGL_BUILD_COMMAND_FLAGS} --target install
81+
BUILD_BYPRODUCTS
82+
${ROOT_FTGL_LIBRARY}
83+
TIMEOUT 600
84+
)
85+
86+
file(MAKE_DIRECTORY ${ROOT_FTGL_PREFIX}/include)
87+
add_library(FTGL::FTGL IMPORTED STATIC GLOBAL)
88+
add_dependencies(FTGL::FTGL BUILTIN_FTGL)
89+
set_target_properties(FTGL::FTGL PROPERTIES
90+
IMPORTED_LOCATION ${ROOT_FTGL_LIBRARY}
91+
INTERFACE_INCLUDE_DIRECTORIES ${ROOT_FTGL_PREFIX}/include)
92+
target_compile_definitions(FTGL::FTGL INTERFACE FTGL_LIBRARY_STATIC) # needed for Win32 since public flag is not correctly propagated to parent scope (BUILD_SHARED_LIBS works fine for building but when installing, flag info is lost)
93+
if(builtin_freetype)
94+
add_dependencies(BUILTIN_FTGL BUILTIN_FREETYPE)
95+
endif()
96+
if(builin_zlib)
97+
add_dependencies(BUILTIN_FTGL BUILTIN_ZLIB)
98+
endif()
99+
target_link_libraries(FTGL::FTGL INTERFACE Freetype::Freetype) # private: OpenGL::GL OpenGL::GLU ZLIB::ZLIB
100+
101+
# Set the canonical output of find_package according to
102+
# https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#standard-variable-names
103+
set(FTGL_INCLUDE_DIRS ${ROOT_FTGL_PREFIX}/include PARENT_SCOPE)
104+
set(FTGL_LIBRARIES ${ROOT_FTGL_LIBRARY} PARENT_SCOPE)
105+
set(FTGL_FOUND TRUE PARENT_SCOPE)
106+
set(FTGL_VERSION ${ROOT_FTGL_VERSION} PARENT_SCOPE)

builtins/ftgl/ftgl-marker.diff

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--- /dev/null 2026-03-12 08:23:04
2+
+++ ._patched 2026-04-28 08:20:11
3+
@@ -0,0 +1,1 @@
4+
+ftgl has been patched
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
diff --git a/src/FTGlyphContainer.cpp b/src/FTGlyphContainer.cpp
2+
index 6a47291..a8847bb 100644
3+
--- a/src/FTGlyphContainer.cpp
4+
+++ b/src/FTGlyphContainer.cpp
5+
@@ -78,6 +78,7 @@ void FTGlyphContainer::Add(FTGlyph* tempGlyph, const unsigned int charCode)
6+
7+
const FTGlyph* FTGlyphContainer::Glyph(const unsigned int charCode) const
8+
{
9+
+ if (!charMap) return NULL;
10+
unsigned int index = charMap->GlyphListIndex(charCode);
11+
12+
return (index < glyphs.size()) ? glyphs[index] : NULL;
13+
@@ -86,7 +87,7 @@ const FTGlyph* FTGlyphContainer::Glyph(const unsigned int charCode) const
14+
15+
FTBBox FTGlyphContainer::BBox(const unsigned int charCode) const
16+
{
17+
- return Glyph(charCode)->BBox();
18+
+ return Glyph(charCode) ? Glyph(charCode)->BBox() : FTBBox();
19+
}
20+
21+
22+
@@ -113,11 +114,11 @@ FTPoint FTGlyphContainer::Render(const unsigned int charCode,
23+
24+
FTPoint kernAdvance = face->KernAdvance(left, right);
25+
26+
- if(!face->Error())
27+
+ if(!face->Error() && charMap)
28+
{
29+
unsigned int index = charMap->GlyphListIndex(charCode);
30+
if (index < glyphs.size())
31+
- kernAdvance += glyphs[index]->Render(penPosition, renderMode);
32+
+ if (glyphs[index]) kernAdvance += glyphs[index]->Render(penPosition, renderMode);
33+
}
34+
35+
return kernAdvance;

cmake/modules/FindFTGL.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,11 @@ if(FTGL_FOUND)
6969
endif()
7070
endif()
7171
set(FTGL_VERSION "${FTGL_VERSION}" CACHE INTERNAL "FTGL version")
72+
73+
if(NOT TARGET FTGL::FTGL)
74+
add_library(FTGL::FTGL UNKNOWN IMPORTED)
75+
set_target_properties(FTGL::FTGL PROPERTIES
76+
IMPORTED_LOCATION "${FTGL_LIBRARY}"
77+
INTERFACE_INCLUDE_DIRECTORIES "${FTGL_INCLUDE_DIRS}")
78+
endif()
7279
endif()

cmake/modules/SearchInstalledSoftware.cmake

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -751,30 +751,14 @@ if(dcache)
751751
endif()
752752

753753
#---Check for ftgl if needed----------------------------------------------------------
754-
if(opengl AND NOT builtin_ftgl)
755-
find_package(FTGL)
756-
if(NOT FTGL_FOUND)
757-
if(fail-on-missing)
758-
message(SEND_ERROR "ftgl library not found and is required ('builtin_ftgl' is OFF). Set variable FTGL_ROOT_DIR to installation location")
759-
else()
760-
message(STATUS "ftgl library not found. Set variable FTGL_ROOT_DIR to point to your installation")
761-
message(STATUS "For the time being switching ON 'builtin_ftgl' option")
762-
set(builtin_ftgl ON CACHE BOOL "Enabled because ftgl not found but opengl requested (${builtin_ftgl_description})" FORCE)
763-
endif()
754+
if(opengl)
755+
ROOT_FIND_REQUIRED_DEP(FTGL builtin_ftgl)
756+
if (builtin_ftgl)
757+
add_subdirectory(builtins/ftgl)
758+
list(APPEND ROOT_BUILTINS BUILTIN_FTGL)
764759
endif()
765-
endif()
766-
767-
if(builtin_ftgl)
768-
# clear variables set to NOTFOUND to allow builtin FTGL to override them
769-
foreach(var FTGL_LIBRARIES FTGL_LIBRARY FTGL_LIBRARY_DEBUG FTGL_LIBRARY_RELEASE)
770-
unset(${var})
771-
unset(${var} CACHE)
772-
endforeach()
773-
set(FTGL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/graf3d/ftgl/inc)
774-
set(FTGL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/graf3d/ftgl/inc)
775-
set(FTGL_CFLAGS -DBUILTIN_FTGL)
776-
set(FTGL_LIBRARIES FTGL)
777-
set(FTGL_VERSION 2.1.2)
760+
elseif(builtin_ftgl)
761+
message(SEND_ERROR "FTGL features enabled with \"builtin_ftgl=ON\" require \"opengl=ON\"")
778762
endif()
779763

780764
#---Check for R/Rcpp/RInside--------------------------------------------------------------------

graf2d/asimage/CMakeLists.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ASImage
2626
-writeEmptyRootPCM
2727
LIBRARIES
2828
libAfterImage
29-
${ASEXTRA_LIBRARIES}
30-
${FREETYPE_LIBRARIES}
31-
${X11_LIBRARIES}
29+
JPEG::JPEG
30+
PNG::PNG
31+
GIF::GIF
32+
libAfterImage
33+
Freetype::Freetype
3234
ZLIB::ZLIB
3335
DEPENDENCIES
3436
Core
3537
Graf
3638
Postscript
3739
)
3840

39-
target_link_libraries(ASImage PRIVATE JPEG::JPEG PNG::PNG GIF::GIF libAfterImage Freetype::Freetype)
4041
if (x11)
4142
target_link_libraries(ASImage PRIVATE X11::X11)
4243
endif()

0 commit comments

Comments
 (0)