SCONS:我如何对目标进行动作

时间:2012-10-17 09:55:27

标签: shared-libraries scons

假设我想删除我构建的共享库中的所有调试符号,并保留原始文件名。

我尝试在方法中添加命令:

def mySharedLibrary(self, *args, **kwargs):
    # do some common work for every shared library like add a soname or append some lib files to LIBS      parameter
     target = SharedLibary(*args, **kwargs)
     target = env.Command(target,target, "objcopy --strip-debug ${SOURCE}")
     return target

我得到了这个错误:给同一个目标提供了两种不同的方法, 我想这是因为env.Command和SharedLibrary返回的两个目标名称完全相同。

有任何想法吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题并得到了同样的错误。我必须做的是创建一个中间目标/库。中间目标和最终目标都有自己的库名,因此SCons不会感到困惑。

您可能会执行以下操作:

env.SharedLibrary(target = 'namePreStrip', source = 'yourSource')
env.Command(target = 'name', source = 'namePreStrip', 'objcopy...')

我使用objcopy从几个库中构建一个库。这是我实现的实际源代码:

#
# Build an object file out of several other source files, objects, and libraries
# Optionally execute objcopy on the resulting library, depending if objcopyFlags
# has been populated
#
# env - SCons Environment used to build, Mandatory arg
# target - resulting library name, without LIBPREFIX and LIBSUFFIX, ej 'nsp2p',
#          Mandatory arg
# sourceFiles - list of '.cc' files that will be compiled and included in the
#               resulting lib, Optional arg
# objects - list of already compiled object files to be included in resulting lib,
#           Optional arg
# libraries - list of libraries to be included in resulting lib, Optional arg
# objcopyFlags - list of flags to pass to objcopy command. objcopy will only
#                be executed if this list is populated, Optional arg
# 
# One of [sourceFiles, objects, or libraries] must be specified, else nothing
# will be performed
#
# Not using a custom builder because I dont like the way SCons prints the
# entire command each time its called, even if its not going to actually
# build anything AND I need more method args than provided by custom builders
#
def buildWholeArchive(self, env, target, sourceFiles, objects, libraries, objcopyFlags):
    if len(sourceFiles) == 0 and len(objects) == 0 and len(libraries) == 0:
        print "Incorrect use of buildWholeArchive, at least one of [sourceFiles | objects | librarires] must be specified, no build action will be performed"
        return None

    # Compile each source file
    objNodes = []
    if len(sourceFiles) > 0:
        objNodes = env.Object(source = sourceFiles)

    cmdList = []
    cmdList.append(env['CXX'])
    cmdList.append('-nostdlib -r -o $TARGET -Wl,--whole-archive')
    for obj in objNodes:
        cmdList.append(env.File(obj).abspath)
    for obj in objects:
        cmdList.append(env.File(obj).abspath)
    for lib in libraries:
        cmdList.append(lib)
    cmdList.append('-Wl,--no-whole-archive')
    cmd = ' '.join(cmdList)

    libTarget = '%s%s%s' % (env['LIBPREFIX'], target, env['LIBSUFFIX'])

    if len(objcopyFlags) > 0:
        # First create the library, then run objcopy on it
        objTarget = '%s%s_preObjcopy%s' % (env['LIBPREFIX'], target, env['LIBSUFFIX'])
        preObjcopyTarget = env.Command(target = objTarget, source = [], action = cmd)
        env.Depends(preObjcopyTarget, [objNodes, sourceFiles, objects, libraries])

        objCmdList = [env['OBJCOPY']]
        objCmdList.extend(objcopyFlags)
        objCmdList.append('$SOURCE $TARGET')
        objcopyCmd = ' '.join(objCmdList)
        archiveTarget = env.Command(target = libTarget, source = preObjcopyTarget, action = objcopyCmd)
    else:
        # Just create the library
        archiveTarget = env.Command(target = libTarget, source = [], action = cmd)
        env.Depends(archiveTarget, [objNodes, sourceFiles, objects, libraries])

    return archiveTarget

以下是我的称呼方式:

sourceFiles = ['file1.cc', 'file2.cc']
libSource = []
if 'OcteonArchitecture' in env:
    libSource.append(lib1)
    libSource.append(lib2)
libSource.append(lib3)

objcopy = []
if 'OcteonArchitecture' in env:
    objcopy.extend([
        '--redefine-sym calloc=ns_calloc',
        '--redefine-sym free=ns_free',
        '--redefine-sym malloc=ns_malloc',
        '--redefine-sym realloc=ns_realloc'])

archiveTarget = clonedEnv.buildWholeArchive(target = libName,
                                            sourceFiles = sourceFiles,
                                            objects = [],
                                            libraries = libSource,
                                            objcopyFlags = objcopy)
env.Alias('libMyLib', archiveTarget)