Bert Huijben wrote on Thu, Mar 19, 2015 at 00:44:02 +0100:
> > [[[
> > svn_repos-1.lib(commit.obj) : error LNK2019: unresolved external
> > symbol _svn_editor3p__insert_shims referenced in funct
> > ion _svn_repos_get_commit_editor5
> > [C:\research\svn\dev\move-tracking-2\build\win32\vcnet-
> > vcproj\libsvn_repos_dll.vcxpro
> > j]
> > C:\research\svn\dev\move-tracking-
> > 2\Debug\subversion\libsvn_repos\libsvn_repos-1.dll
> > : fatal error LNK1120: 1 unresolve
> > d externals [C:\research\svn\dev\move-tracking-2\build\win32\vcnet-
> > vcproj\libsvn_repos_dll.vcxproj]
> > ...
> > svn_wc-1.lib(update_editor.obj) : error LNK2019: unresolved external
> > symbol _svn_delta__ev3_from_delta_for_update refer
> > enced in function _make_editor3
> > [C:\research\svn\dev\move-tracking-2\build\win32\vcnet-
> > vcproj\libsvn_wc_dll.vcxproj]
> > svn_wc-1.lib(deprecated.obj) : error LNK2019: unresolved external
> > symbol _svn_delta__delta_from_ev3_for_update referenc
> > ed in function _svn_wc_get_update_editor4
> > [C:\research\svn\dev\move-tracking-2\build\win32\vcnet-
> > vcproj\libsvn_wc_dll.v
> > cxproj]
> > C:\research\svn\dev\move-tracking-2\Debug\subversion\libsvn_wc\libsvn_wc-
> > 1.dll
> > : fatal error LNK1120: 2 unresolved exte
> > rnals [C:\research\svn\dev\move-tracking-2\build\win32\vcnet-
> > vcproj\libsvn_wc_dll.vcxproj]
> > ]]]
>
> I'm guessing this is caused by a missing msvc-export = <new-header>
> definition in build.conf.
>
> Without that new functions are not exported from .DLLs on Windows.
For what it's worth, here are a pair of scripts that can be used
together to generate a list of headers missing from msvc-export for
a given library.
That's just a proof-of-concept, in particular, it depends on having
an up-to-date tags file in the source tree.
Here is how it works:
% cd root-of-trunk-working-copy
% ctags -R ./
% ./extract-msvc-export.py libsvn_wc
subversion/include/private/svn_wc_private.h
subversion/include/svn_wc.h
% ./compute-msvc-export.py libsvn_wc
subversion/include/private/svn_wc_private.h
subversion/include/svn_wc.h
% list-headers-missing-from-msvc-export-for() { ./extract-msvc-export.py $1
>1; ./compute-msvc-export.py $1 >2; diff 1 2; rm 1 2 }
% list-headers-missing-from-msvc-export-for libsvn_subr
18a19
> subversion/include/private/svn_pseudo_md5.h
This example shows the script correctly determined that svn_pseudo_md5.h
declares functions that are defined in libsvn_subr, but is not listed in
the msvc-export setting for that library.¹
It won't be hard to turn it into a tools/dev/ script that automatically
edits build.conf to add anything that's missing, if anyone thinks that's
a good idea...
Daniel
¹ That svn_pseudo_md5.h discrepancy doesn't break the windows build
because, currently, nothing that uses libsvn_subr.dll uses that header.
#!/usr/bin/env python
"""
Attempt to generate an msvc-export list for a given library.
Assumptions:
- argv[1] is a library name, e.g., 'libsvn_wc'
- A tags file has been generated (by, e.g., `ctags -R ./`)
- The tags file is in the current directory
- The current directory is the root of a Subversion source tree
"""
import re
import sqlite3
import sys
# queries
# Select all header files that declare a "svn_*" symbol defined in the
# library ?1.
#
# ### Possible alternatives: look for the 'f' kind generated by exuberant ctags
SELECT_HEADERS_FOR_LIBRARY = '''
SELECT DISTINCT filename
FROM symbols
WHERE
symbol IN
(
SELECT symbol
FROM symbols
WHERE filename LIKE ('%subversion/' || ?1 || '/%.c')
AND symbol LIKE 'svn_%'
)
AND filename LIKE '%.h'
ORDER BY filename
'''
CREATE_DB = '''
PRAGMA case_sensitive_like = 1;
CREATE TABLE symbols (symbol TEXT, filename TEXT);
'''
# globals
conn = None
cursor = None
def init():
global cursor
global conn
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
cursor.executescript(CREATE_DB)
with open('tags') as tags:
for line in tags:
symbol, filename = line.split('\t')[:2]
cursor.execute('INSERT INTO symbols (symbol, filename) VALUES (?1, ?2)',
(symbol, filename),
)
conn.commit()
_header_pattern = re.compile(r'subversion/(include|bindings).*\.h$')
def headers_for_library(libname):
global cursor
global conn
cursor.execute(SELECT_HEADERS_FOR_LIBRARY, (libname,))
for row in cursor.fetchall():
headerfile = row[0]
if _header_pattern.match(headerfile):
yield headerfile
if __name__ == '__main__':
init()
try:
target = sys.argv[1]
except IndexError:
target = 'libsvn_subr'
for headerfile in headers_for_library(target):
print(headerfile)
#!/usr/bin/env python
"""
Print the 'msvc-export' section from the build.conf stanza for argv[1]
"""
import sys
try:
# Python >=3.0
import configparser
except ImportError:
# Python <3.0
import ConfigParser as configparser
if __name__ == '__main__':
parser = configparser.ConfigParser()
parser.readfp(open('build.conf'))
try:
target = sys.argv[1]
except IndexError:
target = 'libsvn_subr'
files = parser.get(target, 'msvc-export')
if files is not None:
files = sorted(
'subversion/include/' + fn.replace('\\', '/')
for fn in files.split()
)
for fn in files:
print(fn)