View Issue Details

IDProjectCategoryView StatusLast Update
0015852ScribusBuild Systempublic2020-04-26 20:16
Reporterbkylerussell Assigned Tocbradney  
Status resolvedResolutionreopened 
Product Version1.5.6.svn 
Target VersionFixed in Version1.5.6.svn 
Summary0015852: [PATCH] CMake can't locate some icu-uc headers with pkg-config
DescriptionA couple of libraries that depend on icu-uc headers don't use the pkg_check_modules provided ${ICU_INCLUDEDIR} variable to correctly configure their include_directories. I encountered this configuration error when icu4c was installed using brew.

$ brew install harfbuzz
==> Installing harfbuzz dependency: icu4c
For pkg-config to find icu4c you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig"

$ cmake ../Scribus
-- Package 'icu-uc', required by 'harfbuzz-icu', not found
CMake Error at /usr/local/Cellar/cmake/3.15.4/share/cmake/Modules/FindPkgConfig.cmake:458 (message):
  A required package was not found
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.15.4/share/cmake/Modules/FindPkgConfig.cmake:637 (_pkg_check_modules_internal)
  CMakeLists_Dependencies.cmake:319 (pkg_check_modules)
  CMakeLists.txt:358 (include)

-- Configuring incomplete, errors occurred!
$ export PKG_CONFIG_PATH=/usr/local/opt/icu4c/lib/pkgconfig/
$ make
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/styles/linestyle.cpp:18:
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/prefsmanager.h:28:
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/prefsstructs.h:24:
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/pdfoptions.h:21:
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/scribusstructs.h:32:
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/pageitem.h:50:
/Users/bkylerussell/code/scribus/Scribus/scribus/text/storytext.h:33:10: fatal error: 'unicode/brkiter.h' file not found
#include <unicode/brkiter.h>
1 error generated.
[ 7%] Building CXX object scribus/third_party/rtf-qt/CMakeFiles/scribus_rtf_lib.dir/sladocumentrtfoutput.cpp.o
In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/third_party/rtf-qt/sladocumentrtfoutput.cpp:20:

In file included from /Users/bkylerussell/code/scribus/Scribus/scribus/pageitem.h:50:
/Users/bkylerussell/code/scribus/Scribus/scribus/text/storytext.h:33:10: fatal error: 'unicode/brkiter.h' file not found
#include <unicode/brkiter.h>
1 error generated.




2019-10-14 02:33

reporter   ~0046775

Patch file for missing icu header includes

icu-headers.diff (868 bytes)
Index: Scribus/scribus/styles/CMakeLists.txt
--- Scribus/scribus/styles/CMakeLists.txt	(revision 23255)
+++ Scribus/scribus/styles/CMakeLists.txt	(working copy)
@@ -2,6 +2,7 @@
Index: Scribus/scribus/third_party/rtf-qt/CMakeLists.txt
--- Scribus/scribus/third_party/rtf-qt/CMakeLists.txt	(revision 23255)
+++ Scribus/scribus/third_party/rtf-qt/CMakeLists.txt	(working copy)
@@ -2,6 +2,7 @@
icu-headers.diff (868 bytes)


2020-04-10 21:35

administrator   ~0047504

Already fixed in r21563


2020-04-10 23:00

reporter   ~0047506

Are you sure r21563 resolves this? It looks like r21563 sets up the main CMakeLists.txt with the proper icu pkgconfig, but the error I encountered was building some of the subdirectories (scribus/third_party/rtf-qt and scribus/styles). I just wanted to make sure I understand. I'm not very familiar with the scribus build files, but would like to get more involved.


2020-04-10 23:06

administrator   ~0047507

I checked unicode/brkiter.h was supplied by ICU.. and that is not used in scribus/styles, for example. I'm not sure why we would need the ICU includes for that subdirectory?


2020-04-11 01:34

reporter   ~0047508

It's not directly included in scribus/styles, but there's an include dependency chain about six header files deep from styles/linestyle.cpp that causes unicode/brkiter.h to be included (ultimately via text/storytext.h). If there's somewhere to break that dependency chain from styles, then I agree that would be a better fix, but I'll defer to you. Otherwise, it does look like styles needs to be able to find unicode/brkiter.h in order for the compiler to resolve all its includes.

Similarly from third_party/rtf-qt/sladocumentrtfoutput.cpp, although the chain is much shorter.

scribus/pageitem.h appears to be the common include between styles and third_party/rtf-qt.


2020-04-12 19:54

administrator   ~0047512

What OS are you building on?


2020-04-13 13:40

reporter   ~0047513

macOS 10.15 right now. I may have been running 10.14 at the time, but I'm not exactly sure. I don't think I was using any non-default configure options.


2020-04-14 09:21

administrator   ~0047517

same.. 10.14 and 10.15 on multiple machines


2020-04-17 04:08

reporter   ~0047536

Did you use brew to install the icu dependency? Maybe <unicode/brkiter.h> on your system is in the default include search path? What do your compile lines for styles/linestyle.cpp and third_party/rtf-qt/sladocumentrtfoutput.cpp look like?

I think either those two cpp files must not be compiling in your setup like they did in mine (which I'm guessing is unlikely?), or your system has the <unicode/brkiter.h> header installed in a default include search path. The only version I found on my system was /usr/local/Cellar/icu4c/64.2/include/unicode/brkiter.h, so I can't imagine that the compiler would look there without the includedir directive from the icu-uc pkg-config file.

I'm not sure why my system is configured differently (brew?). I thought I had seen somewhere in the wiki that brew was supposed to be a supported setup for Scribus dev environment, but maybe not? It would be helpful for it to work.

I also see ${ICU_INCLUDE_DIRS} used in Scribus/scribus/text/CMakeLists.txt, which was added in r21563 like you said. It looks like pageitem.h gets included from text/ as well, so that all checks out. I think these other two cases just got missed somehow.


2020-04-19 12:46

administrator   ~0047540

I use MacPorts. Here's my line for linestyle.cpp:

[ 0%] Building CXX object scribus/styles/CMakeFiles/scribus_styles_lib.dir/linestyle.cpp.o
cd /Users/craig/scribus/PostTrunk/bt514/scribus/styles && /Applications/ -DAPPDATADIR=\"/Users/craig/Applications/\" -DDESKTOPDIR=\"/Users/craig/Applications/\" -DDOCDIR=\"/Users/craig/Applications/\" -DHAVE_CONFIG_H -DHAVE_DLFCN_H -DHAVE_SVNVERSION -DHAVE_UNISTD_H -DICONDIR=\"/Users/craig/Applications/\" -DLIBDIR=\"/Users/craig/Applications/\" -DPLUGINDIR=\"/Users/craig/Applications/\" -DQMLDIR=\"/Users/craig/Applications/\" -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -DSAMPLESDIR=\"/Users/craig/Applications/\" -DSCRIPTSDIR=\"/Users/craig/Applications/\" -DSHAREDIR=\"/Users/craig/Applications/\" -DTEMPLATEDIR=\"/Users/craig/Applications/\" -I/Users/craig/scribus/PostTrunk/bt514/scribus/styles -I/Users/craig/scribus/PostTrunk/trunk/Scribus/scribus/styles -F/Users/craig/Qt/5.14.2/clang_64/lib -I/Users/craig/Qt/5.14.2/clang_64/lib/QtCore.framework/Headers -I/Users/craig/Qt/5.14.2/clang_64/./mkspecs/macx-clang -I/Users/craig/Qt/5.14.2/clang_64/lib/QtWidgets.framework/Headers -I/Users/craig/Qt/5.14.2/clang_64/lib/QtGui.framework/Headers -I/Applications/ -I/Users/craig/Qt/5.14.2/clang_64/lib/QtXml.framework/Headers -I/Users/craig/Qt/5.14.2/clang_64/lib/QtNetwork.framework/Headers -I/Users/craig/Qt/5.14.2/clang_64/lib/QtOpenGL.framework/Headers -I/Users/craig/Qt/5.14.2/clang_64/lib/QtPrintSupport.framework/Headers -I/Users/craig/scribus/PostTrunk/bt514 -I/Users/craig/scribus/PostTrunk/bt514/scribus -I/opt/local/include -I/opt/local/include/libxml2 -I/Users/craig/scribus/PostTrunk/trunk/Scribus -I/Users/craig/scribus/PostTrunk/trunk/Scribus/scribus -I/opt/local/include/freetype2 -g -O0 -g -fno-inline-functions -Wall -mmacosx-version-min=10.14 -arch x86_64 -isysroot /Applications/ -mmacosx-version-min=10.14 -fPIC -DCOMPILE_SCRIBUS_MAIN_APP -std=gnu++11 -o CMakeFiles/scribus_styles_lib.dir/linestyle.cpp.o -c /Users/craig/scribus/PostTrunk/trunk/Scribus/scribus/styles/linestyle.cpp

I don't see the dependency on that file for those two files though.


2020-04-21 03:18

reporter   ~0047546

I didn't notice too many significant differences in our compile lines for linestyle.cpp, but I'm guessing macports installed /opt/local/include/unicode/brkiter.h on your system. My patch adds -I/usr/local/Cellar/icu4c/64.2/include to my compile line, which is where brew installed the header for me.

I looked more closely at linestyle.cpp, and it doesn't actually need to include prefsmanager.h, so just removing that include fixes that file, but I hit the same include dependency chain on styles/charstyle.cpp, which does grab a PrefsManager instance in ScFace parse<ScFace>(const Xml_string& str). Is there another way to get to the right AvailFonts instance without going through PrefsManager? prefsmanager.h is one header that causes <unicode/brkiter.h> to be needed.

third_party/rtf-qt/sladocumentrtfoutput.cpp appears to be more complicated, even if the above charstyle.cpp PrefsManager case can be resolved.


2020-04-22 14:03

reporter   ~0047551

I installed macports and verified that the icu port does in fact provide /opt/local/include/unicode/brkiter.h, and since -I/opt/local/include is provided on your compile line (probably through some other CMake include_directory), that's why it compiles successfully on your system.

$ port contents icu | grep brkiter.h

I'll assume ${LCMS2_INCLUDE_DIR} provides -I/opt/local/include from your root CMakeLists.txt since ${LCMS2_INCLUDE_DIR} is listed right before ${LIBXML2_INCLUDE_DIR}, which corresponds with the position of -I/opt/local/include on your compile command line. It looks like the lcms2 pc file only specifies -I${includedir}, so if macports builds its packages with /opt/local/include as the default ${includedir}, that does seem like the culprit. To check that, you could try removing ${LCMS2_INCLUDE_DIR} in the root CMakeLists.txt and you'll probably hit the same error I received building styles/, assuming /opt/local/include isn't being added back to the compile line from anywhere else. Lots of other things may break too though since macports seems to put lots of things in /opt/local/include.

#Set up include dirs with all found packages

In summary, I think there is a deficiency in at least one CMakeLists.txt file. It only works currently because someone else (not the actual icu pkg-config) is putting /opt/local/include on the compile line for you. If that stops happening (for example, by removing ${LCMS2_INCLUDE_DIR}), or icu gets installed somewhere else (like on my system), then you're going to hit this error.

I understand styles/linestyle.cpp doesn't include <unicode/brkiter.h> directly, but it is a transitive dependency. So that transitive dependency should either be broken, or the correct ${ICU_INCLUDE_DIR} provided somewhere.

Since this transitive dependency seems to involve several global headers (like scribusstructs.h), maybe you're suggesting ${ICU_INCLUDE_DIR} would be better placed in the root CMakeLists.txt include_directories (listed above)? My patch only added ${ICU_INCLUDE_DIR} in the styles/ and third_party/rtf-qt/ because I generally try to avoid global, implicit dependencies, as they can be hard to unwind. But I would be glad to try adding it to the root CMakeLists.txt and provide an updated patch if you like that solution better.

Also, I understand brew's behavior a little better now too. It typically links things in /usr/local to its custom install path, but it warns it does not do that for icu to avoid conflicting with the macOS provided libicucore.dylib. (My compile line does have -I/usr/local/include.) But for that conflict, this would all behave the same. But the CMakeLists.txt files here are not technically allowing the install/configuration flexibility that pkg-config was designed to support.


2020-04-25 18:21

reporter   ~0047568

Ok, I dug in further. :) scribus/text/storytext.h is the actual header file pulling in <unicode/brkiter.h> for everyone (including clients that actually use it). I can remove <unicode/brkiter.h> from the header file by forward-declaring icu::BreakIteartor, but properly forward declaring that class requires <unicode/uversion.h> since icu is an aliased namespace against a version-specific icu namespace (see "Namespaces" under, which puts us back into the position of requiring an icu header in scribus/text/storytext.h.

So I tried including ${ICU_INCLUDE_DIRS} in scribus/CMakeLists.txt since pageitem.h is a top-level header file, and that seems to work, if you like that approach better than in the original two CMakeLists.txt files I chose. (See the icu-headers-v2.diff attachment.)

I also attached a patch to remove an unused prefsmanger.h header from linestyle.cpp because it kept getting in my way (see linestyle-unused-prefsmanager.diff).

Thirdly, I attached a patch from the path I started down trying to remove <unicode/brkiter.h> from storytext.h (see remove-using-icu-from-storytext.diff). There's shouldn't be any significant different, but it does remove the 'using namespace icu;' line from storytext.h in favor of forward-declaration. I try to avoid 'using namespace' in header files when possible, so I thought there might be some interest in this. It still requires a unicode header though, so depends on the icu-headers-v2.diff patch. It's possible there's a way to avoid even <unicode/uversion.h> by turning off the icu namespace versioning flag, but that involves other complications, and I didn't want to track down all the ways Scribus uses icu.

icu-headers-v2.diff (929 bytes)
Index: scribus/CMakeLists.txt
--- scribus/CMakeLists.txt	(revision 23587)
+++ scribus/CMakeLists.txt	(working copy)
@@ -21,6 +21,15 @@
@@ -1151,14 +1160,6 @@
 set(SCRIBUS_ZIP_LIB "scribus_zip_lib")
 set(SCRIBUS_RTF_LIB "scribus_rtf_lib")
icu-headers-v2.diff (929 bytes)
linestyle-unused-prefsmanager.diff (368 bytes)
Index: scribus/styles/linestyle.cpp
--- scribus/styles/linestyle.cpp	(revision 23587)
+++ scribus/styles/linestyle.cpp	(working copy)
@@ -15,7 +15,6 @@
 #include "linestyle.h"
 #include "desaxe/saxiohelper.h"
 #include "desaxe/simple_actions.h"
-#include "prefsmanager.h"
 #include "util_math.h"
remove-using-icu-from-storytext.diff (3,833 bytes)
Index: scribus/text/boxes.cpp
--- scribus/text/boxes.cpp	(revision 23587)
+++ scribus/text/boxes.cpp	(working copy)
@@ -6,6 +6,7 @@
 #include <cmath>
+#include <unicode/brkiter.h>
 #include "pageitem.h"
 #include "boxes.h"
@@ -21,6 +22,8 @@
 #include "itextcontext.h"
 #include "itextsource.h"
+using namespace icu;
 int GroupBox::pointToPosition(QPointF coord, const StoryText &story) const
 	QPointF rel = coord - QPointF(m_x, m_y);
Index: scribus/hyphenator.cpp
--- scribus/hyphenator.cpp	(revision 23587)
+++ scribus/hyphenator.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include <QCursor>
 #include <QCheckBox>
 #include <QByteArray>
+#include <unicode/brkiter.h>
 #include "langmgr.h"
 #include "scpaths.h"
@@ -37,6 +38,8 @@
 #include "prefsfile.h"
 #include "prefsmanager.h"
+using namespace icu;
 Hyphenator::Hyphenator(QWidget* parent, ScribusDoc *dok) : QObject( parent ),
Index: scribus/text/storytext.cpp
--- scribus/text/storytext.cpp	(revision 23587)
+++ scribus/text/storytext.cpp	(working copy)
@@ -22,6 +22,8 @@
 //#include <QDebug>
+#include <unicode/brkiter.h>
 //FIXME: this include must go to sctextstruct.h !
 #include <QList>
 #include <cassert>  //added to make Fedora-5 happy
@@ -40,6 +42,7 @@
 #include "desaxe/simple_actions.h"
 #include "shapedtextcache.h"
+using namespace icu;
 StoryText::StoryText(ScribusDoc * doc_) : m_doc(doc_)
Index: scribus/text/storytext.h
--- scribus/text/storytext.h	(revision 23587)
+++ scribus/text/storytext.h	(working copy)
@@ -29,9 +29,8 @@
 #include <QObject>
 #include <QString>
 #include <QList>
+#include <unicode/uversion.h>
-#include <unicode/brkiter.h>
 #include "itextsource.h"
 #include "marks.h"
 #include "text/frect.h"
@@ -50,7 +49,9 @@
 class ResourceCollection;
 class ShapedTextCache;
-using namespace icu;
+class BreakIterator;
  * This class holds the text of a Scribus textframe and pointers to its
@@ -258,10 +259,10 @@
 	bool isSelected() const;
 	// break iterators
-	static BreakIterator* getGraphemeIterator();
-	static BreakIterator* getWordIterator();
-	static BreakIterator* getSentenceIterator();
-	static BreakIterator* getLineIterator();
+	static icu::BreakIterator* getGraphemeIterator();
+	static icu::BreakIterator* getWordIterator();
+	static icu::BreakIterator* getSentenceIterator();
+	static icu::BreakIterator* getLineIterator();
 // layout helpers
@@ -295,10 +296,10 @@
 	ScribusDoc * m_doc; 
 	int m_selFirst, m_selLast;
 	ShapedTextCache* m_shapedTextCache;
-	static BreakIterator* m_graphemeIterator;
-	static BreakIterator* m_wordIterator;
-	static BreakIterator* m_sentenceIterator;
-	static BreakIterator* m_lineIterator;
+	static icu::BreakIterator* m_graphemeIterator;
+	static icu::BreakIterator* m_wordIterator;
+	static icu::BreakIterator* m_sentenceIterator;
+	static icu::BreakIterator* m_lineIterator;
 	QString textWithSoftHyphens (int pos, uint len) const;
 	void    insertCharsWithSoftHyphens(int pos, const QString& txt, bool applyNeighbourStyle = false);
Index: scribus/text/textshaper.cpp
--- scribus/text/textshaper.cpp	(revision 23587)
+++ scribus/text/textshaper.cpp	(working copy)
@@ -3,6 +3,7 @@
 #include <harfbuzz/hb.h>
 #include <harfbuzz/hb-ft.h>
 #include <harfbuzz/hb-icu.h>
+#include <unicode/brkiter.h>
 #include <unicode/ubidi.h>
 #include "scrptrun.h"


2020-04-26 20:15

administrator   ~0047570

Thanks, I have applied those three patches in r23660.

Issue History

Date Modified Username Field Change
2019-10-14 02:29 bkylerussell New Issue
2019-10-14 02:33 bkylerussell File Added: icu-headers.diff
2019-10-14 02:33 bkylerussell Note Added: 0046775
2019-10-14 07:06 ale Summary CMake can't locate some icu-uc headers with pkg-config => [PATCH] CMake can't locate some icu-uc headers with pkg-config
2019-10-14 07:06 ale Tag Attached: patch
2020-04-10 21:35 cbradney Assigned To => cbradney
2020-04-10 21:35 cbradney Status new => resolved
2020-04-10 21:35 cbradney Resolution open => fixed
2020-04-10 21:35 cbradney Note Added: 0047504
2020-04-10 23:00 bkylerussell Status resolved => feedback
2020-04-10 23:00 bkylerussell Resolution fixed => reopened
2020-04-10 23:00 bkylerussell Note Added: 0047506
2020-04-10 23:06 cbradney Note Added: 0047507
2020-04-11 01:34 bkylerussell Note Added: 0047508
2020-04-11 01:34 bkylerussell Status feedback => assigned
2020-04-12 19:54 cbradney Note Added: 0047512
2020-04-13 13:40 bkylerussell Note Added: 0047513
2020-04-14 09:21 cbradney Note Added: 0047517
2020-04-17 04:08 bkylerussell Note Added: 0047536
2020-04-19 12:46 cbradney Note Added: 0047540
2020-04-21 03:18 bkylerussell Note Added: 0047546
2020-04-22 14:03 bkylerussell Note Added: 0047551
2020-04-25 18:21 bkylerussell File Added: icu-headers-v2.diff
2020-04-25 18:21 bkylerussell File Added: linestyle-unused-prefsmanager.diff
2020-04-25 18:21 bkylerussell File Added: remove-using-icu-from-storytext.diff
2020-04-25 18:21 bkylerussell Note Added: 0047568
2020-04-26 20:15 cbradney Note Added: 0047570
2020-04-26 20:15 cbradney Status assigned => resolved
2020-04-26 20:16 cbradney Product Version => 1.5.6.svn
2020-04-26 20:16 cbradney Fixed in Version => 1.5.6.svn