Using the Conan package manager with Scintilla

52 views
Skip to first unread message

Neil Hodgson

unread,
Mar 14, 2018, 6:57:51 AM3/14/18
to Scintilla mailing list
[An earlier version of this mail with a .zip attachment appears to have been blocked by Google Groups]

Conan is a cross-platform C++ package manager that has been seeing some popularity. Its web site is at https://conan.io

Trying to use it to package up Scintilla for 3 of the main platforms Win32, macOS, and Linux/GTK+ has shown that it has some potential although there were problems as well. Conan uses a Python script called conanfile.py to define the recipe for what sources and dependencies are required for a package; what the binary and text outputs are; and how to build them. It can use any build tool (like make or Meson) and does not define its own.

The supported features mapped OK for Win32 and Linux/GTK+, but less well on macOS as Conan wants to produce simple dynamic libraries .dylib and does not understand the more complex .framework format which is more common when using Xcode.

Conan has built-in knowledge of some of the standard variants when building: debug vs release, static library vs shared, 32-bit vs 64-bit. It can cache binaries on a system or download from repositories. It has some features for other variants but fitting in a choice of GUI platform like GTK+/Qt/wxWidgets wasn’t obvious to me and it may be better to make these separate packages with separate conanfiles.

My current conanfile.py is shown below - its incomplete in that it doesn’t respect any options like release/debug or shared/static but it does download and build on all 3 platforms and it exports a directory with headers + libraries except on macOS where the .framework (which is a directory) isn’t copied. Its quite likely I haven’t understood everything so there may be some major mistakes.

Common usage with Conan is to also include a short test that the packaging worked - this is in the test_package subdirectory with example.cpp just checking that the Scintilla.h header is available and contains the SCI_ADDTEXT symbol. It also has its own conanfile.py to build.

An archive can be downloaded from http://www.scintilla.org/scintilla_conan.zip with each of the files. It can be expanded and, with conan installed, run either stage by stage (source, install, build, package, export-pkg, test) or all in a single command with (in the top level directory from the archive):

conan create . demo/testing

This should show a lot of intermediate output and end with

SCI_ADDTEXT=2001

The conanfile.py for Scintilla:

from conans import ConanFile
import platform

class ScintillaConan(ConanFile):
name = "scintilla"
version = "4.0.3"
license = "Historical Permission Notice and Disclaimer"
url = "http://www.scintilla.org"
description = "Scintilla text editing component"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = "shared=True"
generators = "txt"

def source(self):
self.run("hg clone http://hg.code.sf.net/p/scintilla/code scintilla")

def build(self):
if platform.system() == "Windows":
self.run('cd %s/scintilla/win32 && nmake -f scintilla.mak' % (self.source_folder, ))
elif platform.system() == "Darwin":
self.run('cd %s/scintilla/cocoa/ScintillaFramework && xcodebuild -project ScintillaFramework.xcodeproj' % (self.source_folder, ))
else:
self.run('cd %s/scintilla/gtk && make' % (self.source_folder, ))

def package(self):
self.copy("*.h", dst="include", src="scintilla/include", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.framework", dst="lib", src="scintilla/cocoa/ScintillaFramework/build/Release", keep_path=False)
self.copy("*.dylib", dst="lib", keep_path=False)
self.copy("*.a", dst="lib", keep_path=False)
self.copy("*.lib", dst="lib", keep_path=False)

def package_info(self):
self.cpp_info.libs = ["SciLexer”]

Neil



Neil Hodgson

unread,
Mar 31, 2018, 7:15:16 PM3/31/18
to scintilla...@googlegroups.com
Updated to Conan 1.2.0 and added support for building with gcc or Clang on Windows.

The compiler, compiler.libcxx, and compiler.version settings are used when building with gcc or Clang. Viable build command lines include (may be line-wrapped by mailer - use one line):

conan create . user/test

conan create . user/test -s "compiler=Visual Studio”

conan create . user/test -s compiler=gcc -s compiler.libcxx=libstdc++11 -s compiler.version=7.3

conan create . user/test -s compiler=clang -s compiler.libcxx=libstdc++11 -s compiler.version=5.0

The updated conanfile.py is:

from conans import ConanFile
import platform

class ScintillaConan(ConanFile):
name = "scintilla"
version = "4.0.3"
license = "Historical Permission Notice and Disclaimer"
url = "http://www.scintilla.org"
description = "Scintilla text editing component"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False]}
default_options = "shared=True"
generators = "txt"

def source(self):
self.run(
"hg clone http://hg.code.sf.net/p/scintilla/code scintilla")

def build(self):
# Settings read are:
# build_type=Release|Debug
# compiler=Visual Studio|gcc|clang
if platform.system() == "Windows":
cdCmd = 'cd ' + self.source_folder + '\\scintilla\\win32'
if self.settings.compiler == "Visual Studio":
buildCmd = 'nmake -f scintilla.mak'
else: # GCC or Clang
buildCmd = 'mingw32-make -j 4'
if self.settings.compiler != "gcc":
buildCmd += ' CLANG=1'
if self.settings.build_type != "Release":
buildCmd += ' DEBUG=1'
elif platform.system() == "Darwin":
cdCmd = 'cd ' + self.source_folder + \
'/scintilla/cocoa/ScintillaFramework'
buildCmd = \
'xcodebuild -project ScintillaFramework.xcodeproj'
if self.settings.build_type != "Release":
buildCmd += ' -configuration Debug'
else:
cdCmd = 'cd ' + self.source_folder + '/scintilla/gtk'
buildCmd = 'make -j 4'
if self.settings.compiler != "gcc":
buildCmd += ' CLANG=1'
if self.settings.build_type != "Release":
buildCmd += ' DEBUG=1'
fullCmd = '%s && %s' % (cdCmd, buildCmd)
print("Command =", fullCmd)
self.run(fullCmd)

def package(self):
self.copy("*.h", dst="include", src="scintilla/include",
keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.framework", dst="lib", keep_path=False)
Reply all
Reply to author
Forward
0 new messages