MSVC builds: Add scripts to generate .pc files

Add a generic script, pc_base.py, which can be utilized to obtain path
info, along with user-input version info, which can be used to generate
pkg-config .pc files.  Also enhance replace.py a bit so that it can also
be used in the future to replace multiple items in a file in one shot.
This is done to make building introspection files easier, as it depends
much on the pkg-config .pc files to work.

Update the project files so that when Python is available, we can generate
the full, usable .pc files when we complete and 'install' the builds, and
copy them to appropriate locations so that pkg-config can be set to find
them easily.
This commit is contained in:
Chun-wei Fan 2016-03-10 20:33:35 +08:00
parent fd6ca66c16
commit 374a61f245
13 changed files with 320 additions and 4 deletions

View File

@ -7,6 +7,8 @@ SUBDIRS = \
vs14
EXTRA_DIST = \
glibpc.py \
make.msc \
module.defs \
pc_base.py \
replace.py

88
build/win32/glibpc.py Normal file
View File

@ -0,0 +1,88 @@
#!/usr/bin/python
#
# Utility script to generate .pc files for GLib
# for Visual Studio builds, to be used for
# building introspection files
# Author: Fan, Chun-wei
# Date: March 10, 2016
import os
import sys
from replace import replace_multi
from pc_base import BasePCItems
def main(argv):
base_pc = BasePCItems()
base_pc.setup(argv)
pkg_replace_items = {'@G_THREAD_CFLAGS@': '',
'@G_THREAD_LIBS@': '',
'@CARBON_LIBS@': '',
'@COCOA_LIBS@': ''}
glib_replace_items = {'glib-genmarshal': '${exec_prefix}/bin/glib-genmarshal',
'glib-mkenums': 'perl ${exec_prefix}/bin/glib-mkenums',
'gobject-query': '${exec_prefix}/bin/gobject-query',
'@PCRE_REQUIRES@': '',
'@INTLLIBS@': '-lintl',
'@G_LIBS_EXTRA@': '',
'@PCRE_LIBS@': '',
'@ICONV_LIBS@': '-liconv',
'@GLIB_EXTRA_CFLAGS@': ''}
pkg_replace_items.update(base_pc.base_replace_items)
glib_replace_items.update(pkg_replace_items)
# Generate glib-2.0.pc
replace_multi(base_pc.top_srcdir + '/glib-2.0.pc.in',
base_pc.srcdir + '/glib-2.0.pc',
glib_replace_items)
# Generate gthread-2.0.pc
replace_multi(base_pc.top_srcdir + '/gthread-2.0.pc.in',
base_pc.srcdir + '/gthread-2.0.pc',
pkg_replace_items)
# Generate gmodule*-2.0.pc
gmodule_replace_items = {'@G_MODULE_SUPPORTED@': 'yes',
'@G_MODULE_LDFLAGS@': '',
'@G_MODULE_LIBS@': ''}
gmodule_replace_items.update(pkg_replace_items)
replace_multi(base_pc.top_srcdir + '/gmodule-2.0.pc.in',
base_pc.srcdir + '/gmodule-2.0.pc',
gmodule_replace_items)
replace_multi(base_pc.top_srcdir + '/gmodule-export-2.0.pc.in',
base_pc.srcdir + '/gmodule-export-2.0.pc',
gmodule_replace_items)
replace_multi(base_pc.top_srcdir + '/gmodule-no-export-2.0.pc.in',
base_pc.srcdir + '/gmodule-no-export-2.0.pc',
gmodule_replace_items)
# Generate gobject-2.0.pc
gobject_replace_items = {'@LIBFFI_LIBS@': ''}
gobject_replace_items.update(pkg_replace_items)
replace_multi(base_pc.top_srcdir + '/gobject-2.0.pc.in',
base_pc.srcdir + '/gobject-2.0.pc',
gobject_replace_items)
# Generate gio*-2.0.pc
gio_replace_items = {'@GIO_MODULE_DIR@': '${exec_prefix}/bin/gio/modules',
'@ZLIB_LIBS@': '-lzlib1',
'@NETWORK_LIBS@': '-lws2_32',
'@SELINUX_LIBS@': '',
'glib-compile-schemas': '${exec_prefix}/bin/glib-compile-schemas',
'glib-compile-resources': '${exec_prefix}/bin/glib-compile-resources',
'gdbus-codegen': 'python ${exec_prefix}/bin/gdbus-codegen'}
gio_replace_items.update(pkg_replace_items)
replace_multi(base_pc.top_srcdir + '/gio-2.0.pc.in',
base_pc.srcdir + '/gio-2.0.pc',
gio_replace_items)
replace_multi(base_pc.top_srcdir + '/gio-windows-2.0.pc.in',
base_pc.srcdir + '/gio-windows-2.0.pc',
pkg_replace_items)
if __name__ == '__main__':
sys.exit(main(sys.argv))

107
build/win32/pc_base.py Normal file
View File

@ -0,0 +1,107 @@
#!/usr/bin/python
#
# Simple utility script to generate the basic info
# needed in a .pc (pkg-config) file, used especially
# for introspection purposes
# This can be used in various projects where
# there is the need to generate .pc files,
# and is copied from GLib's $(srcroot)/build/win32
# Author: Fan, Chun-wei
# Date: March 10, 2016
import os
import sys
import argparse
class BasePCItems:
def __init__(self):
self.base_replace_items = {}
self.exec_prefix = ''
self.includedir = ''
self.libdir = ''
self.prefix = ''
self.srcdir = os.path.dirname(__file__)
self.top_srcdir = self.srcdir + '\\..\\..'
self.version = ''
def setup(self, argv):
parser = argparse.ArgumentParser(description='Setup basic .pc file info')
parser.add_argument('--prefix', help='prefix of the installed library',
required=True)
parser.add_argument('--exec-prefix',
help='prefix of the installed programs, \
if different from the prefix')
parser.add_argument('--includedir',
help='includedir of the installed library, \
if different from ${prefix}/include')
parser.add_argument('--libdir',
help='libdir of the installed library, \
if different from ${prefix}/lib')
parser.add_argument('--version', help='Version of the package',
required=True)
args = parser.parse_args()
self.version = args.version
# check whether the prefix and exec_prefix are valid
if not os.path.exists(args.prefix):
raise SystemExit('Specified prefix \'%s\' is invalid' % args.prefix)
# check and setup the exec_prefix
if getattr(args, 'exec_prefix', None) is None:
input_exec_prefix = args.prefix
else:
input_exec_prefix = args.exec_prefix
if not os.path.exists(input_exec_prefix):
raise SystemExit('Specified exec-prefix \'%s\' is invalid' %
input_exec_prefix)
# check and setup the includedir
if getattr(args, 'includedir', None) is None:
self.includedir = '${prefix}/include'
else:
if args.includedir.startswith('${prefix}'):
includedir_use_shorthand = True
input_includedir = args.prefix + args.includedir[len('${prefix}'):]
else:
includedir_use_shorthand = False
input_includedir = args.includedir
if not os.path.exists(input_includedir):
raise SystemExit('Specified includedir \'%s\' is invalid' %
args.includedir)
if includedir_use_shorthand is True:
self.includedir = args.includedir.replace('\\','/')
else:
self.includedir = os.path.abspath(input_includedir).replace('\\','/')
# check and setup the libdir
if getattr(args, 'libdir', None) is None:
self.libdir = '${prefix}/lib'
else:
if args.libdir.startswith('${prefix}'):
libdir_use_shorthand = True
input_libdir = args.prefix + args.libdir[len('${prefix}'):]
else:
libdir_use_shorthand = False
input_libdir = args.libdir
if not os.path.exists(input_libdir):
raise SystemExit('Specified libdir \'%s\' is invalid' %
args.libdir)
if libdir_use_shorthand is True:
self.libdir = args.libdir.replace('\\','/')
else:
self.libdir = os.path.abspath(input_libdir).replace('\\','/')
# use absolute paths for prefix and exec_prefix
self.prefix = os.path.abspath(args.prefix).replace('\\','/')
self.exec_prefix = os.path.abspath(input_exec_prefix).replace('\\','/')
# setup dictionary for replacing items in *.pc.in
self.base_replace_items.update({'@VERSION@': self.version})
self.base_replace_items.update({'@prefix@': self.prefix})
self.base_replace_items.update({'@exec_prefix@': self.exec_prefix})
self.base_replace_items.update({'@libdir@': self.libdir})
self.base_replace_items.update({'@includedir@': self.includedir})

View File

@ -21,6 +21,16 @@ valid_actions = ['remove-prefix',
'replace-str',
'remove-str']
def replace_multi(src, dest, replace_items):
with open(src, 'r') as s:
with open(dest, 'w') as d:
for line in s:
replace_dict = dict((re.escape(key), value) \
for key, value in replace_items.items())
replace_pattern = re.compile("|".join(replace_dict.keys()))
d.write(replace_pattern.sub(lambda m: \
replace_dict[re.escape(m.group(0))], line))
def replace(src, dest, instring, outstring):
with open(src, 'r') as s:
with open(dest, 'w') as d:

View File

@ -46,6 +46,7 @@ EXTRA_DIST = \
gdbus.vcxproj \
gdbus.vcxproj.filters \
glib-install.vcxproj \
glib-install.vcxproj.filters \
glib-build-defines.props \
glib-install.propsin \
glib-version-paths.props.in \

View File

@ -69,12 +69,24 @@ copy $(BinDir)\gmodule-$(ApiVersion).lib $(CopyDir)\lib
copy $(BinDir)\gobject-$(ApiVersion).lib $(CopyDir)\lib
copy $(BinDir)\gio-$(ApiVersion).lib $(CopyDir)\lib
mkdir $(CopyDir)\lib\pkgconfig
copy ..\gio-windows-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gio-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gobject-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gmodule-no-export-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gmodule-export-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gmodule-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\gthread-2.0.pc $(CopyDir)\lib\pkgconfig
copy ..\glib-2.0.pc $(CopyDir)\lib\pkgconfig
mkdir $(CopyDir)\share\glib-$(ApiVersion)\schemas
copy ..\..\..\gio\gschema.dtd $(CopyDir)\share\glib-$(ApiVersion)\schemas
mkdir $(CopyDir)\share\glib-$(ApiVersion)\codegen
copy ..\..\..\gio\gdbus-2.0\codegen\*.py $(CopyDir)\share\glib-$(ApiVersion)\codegen
</GlibDoInstall>
<GlibPCFiles>..\gio-windows-2.0.pc;..\gio-2.0.pc;..\gobject-2.0.pc;..\gmodule-no-export-2.0.pc;..\gmodule-export-2.0.pc;..\gmodule-2.0.pc;..\gthread-2.0.pc;..\glib-2.0.pc</GlibPCFiles>
<GlibGenPC>if exist $(PythonPath)\python.exe $(PythonPath)\python.exe ..\glibpc.py --prefix=$(CopyDir) --version=$(GlibVersion)</GlibGenPC>
</PropertyGroup>
<PropertyGroup>
<_PropertySheetDisplayName>glibinstallprops</_PropertySheetDisplayName>
@ -98,5 +110,11 @@ copy ..\..\..\gio\gdbus-2.0\codegen\*.py $(CopyDir)\share\glib-$(ApiVersion)\cod
<BuildMacro Include="GlibDoInstall">
<Value>$(GlibDoInstall)</Value>
</BuildMacro>
<BuildMacro Include="GlibPCFiles">
<Value>$(GlibPCFiles)</Value>
</BuildMacro>
<BuildMacro Include="GlibGenPC">
<Value>$(GlibGenPC)</Value>
</BuildMacro>
</ItemGroup>
</Project>

View File

@ -85,17 +85,35 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</ItemDefinitionGroup>
<ItemGroup>
<CustomBuild Include="..\glibpc.py">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generating .pc files...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GlibGenPC)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GlibPCFiles);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generating .pc files...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GlibGenPC)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GlibPCFiles);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generating .pc files...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GlibGenPC)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GlibPCFiles);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generating .pc files...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GlibGenPC)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GlibPCFiles);%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="..\..\..\config.h.win32">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Installing Build Results...</Message>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GlibPCFiles)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(GlibDoInstall)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(InstalledDlls);$(InstalledBins);$(InstalledWin32Bins);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Installing Build Results...</Message>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GlibPCFiles)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(GlibDoInstall)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(InstalledDlls);$(InstalledBins);$(InstalledX64Bins);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Installing Build Results...</Message>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GlibPCFiles)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(GlibDoInstall)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(InstalledDlls);$(InstalledBins);$(InstalledWin32Bins);%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Installing Build Results...</Message>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GlibPCFiles)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(GlibDoInstall)</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(InstalledDlls);$(InstalledBins);$(InstalledX64Bins);%(Outputs)</Outputs>
</CustomBuild>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\..\config.h.win32"><Filter>Resource Files</Filter></CustomBuild>
<CustomBuild Include="..\glibpc.py"><Filter>Resource Files</Filter></CustomBuild>
</ItemGroup>
</Project>

View File

@ -30,6 +30,7 @@ EXTRA_DIST = \
gdbus.vcxproj \
gdbus.vcxproj.filters \
glib-install.vcxproj \
glib-install.vcxproj.filters \
glib-build-defines.props \
glib-install.props \
glib-version-paths.props \

View File

@ -30,6 +30,7 @@ EXTRA_DIST = \
gdbus.vcxproj \
gdbus.vcxproj.filters \
glib-install.vcxproj \
glib-install.vcxproj.filters \
glib-build-defines.props \
glib-install.props \
glib-version-paths.props \

View File

@ -30,6 +30,7 @@ EXTRA_DIST = \
gdbus.vcxproj \
gdbus.vcxproj.filters \
glib-install.vcxproj \
glib-install.vcxproj.filters \
glib-build-defines.props \
glib-install.props \
glib-version-paths.props \

View File

@ -28,7 +28,7 @@
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
Name="VCPostBuildEventTool"
CommandLine="$(GlibDoInstall)"
/>
</Configuration>
@ -41,7 +41,7 @@
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
Name="VCPostBuildEventTool"
CommandLine="$(GlibDoInstall)"
/>
</Configuration>
@ -55,7 +55,7 @@
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
Name="VCPostBuildEventTool"
CommandLine="$(GlibDoInstall)"
/>
</Configuration>
@ -69,9 +69,51 @@
DeleteExtensionsOnClean=""
>
<Tool
Name="VCPreBuildEventTool"
Name="VCPostBuildEventTool"
CommandLine="$(GlibDoInstall)"
/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File RelativePath="..\glibpc.py">
<FileConfiguration Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Generating .pc files..."
CommandLine="$(GlibGenPC)"
Outputs="..\gio-windows-2.0.pc;..\gio-2.0.pc;..\gobject-2.0.pc;..\gmodule-no-export-2.0.pc;..\gmodule-export-2.0.pc;..\gmodule-2.0.pc;..\gthread-2.0.pc;..\glib-2.0.pc"
/>
</FileConfiguration>
<FileConfiguration Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Generating .pc files..."
CommandLine="$(GlibGenPC)"
Outputs="..\gio-windows-2.0.pc;..\gio-2.0.pc;..\gobject-2.0.pc;..\gmodule-no-export-2.0.pc;..\gmodule-export-2.0.pc;..\gmodule-2.0.pc;..\gthread-2.0.pc;..\glib-2.0.pc"
/>
</FileConfiguration>
<FileConfiguration Name="Debug|x64">
<Tool
Name="VCCustomBuildTool"
Description="Generating .pc files..."
CommandLine="$(GlibGenPC)"
Outputs="..\gio-windows-2.0.pc;..\gio-2.0.pc;..\gobject-2.0.pc;..\gmodule-no-export-2.0.pc;..\gmodule-export-2.0.pc;..\gmodule-2.0.pc;..\gthread-2.0.pc;..\glib-2.0.pc"
/>
</FileConfiguration>
<FileConfiguration Name="Release|x64">
<Tool
Name="VCCustomBuildTool"
Description="Generating .pc files..."
CommandLine="$(GlibGenPC)"
Outputs="..\gio-windows-2.0.pc;..\gio-2.0.pc;..\gobject-2.0.pc;..\gmodule-no-export-2.0.pc;..\gmodule-export-2.0.pc;..\gmodule-2.0.pc;..\gthread-2.0.pc;..\glib-2.0.pc"
/>
</FileConfiguration>
</File>
</Filter>
</Files>
</VisualStudioProject>

View File

@ -66,6 +66,16 @@ copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\gmodule-$(ApiVersion
copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\gobject-$(ApiVersion).lib $(CopyDir)\lib&#x0D;&#x0A;
copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\gio-$(ApiVersion).lib $(CopyDir)\lib&#x0D;&#x0A;
mkdir $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gio-windows-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gio-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gobject-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gmodule-no-export-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gmodule-export-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gmodule-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\gthread-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
copy ..\glib-2.0.pc $(CopyDir)\lib\pkgconfig&#x0D;&#x0A;
mkdir $(CopyDir)\share\glib-$(ApiVersion)\schemas&#x0D;&#x0A;
copy ..\..\..\gio\gschema.dtd $(CopyDir)\share\glib-$(ApiVersion)\schemas&#x0D;&#x0A;
@ -73,4 +83,8 @@ mkdir $(CopyDir)\share\glib-$(ApiVersion)\codegen&#x0D;&#x0A;
copy ..\..\..\gio\gdbus-2.0\codegen\*.py $(CopyDir)\share\glib-$(ApiVersion)\codegen&#x0D;&#x0A;
"
/>
<UserMacro
Name="GlibGenPC"
Value="if exist $(PythonPath)\python.exe $(PythonPath)\python.exe ..\glibpc.py --prefix=$(CopyDir) --version=$(GlibVersion)"
/>
</VisualStudioPropertySheet>