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)

Reply via email to