我如何获得项目他们构建输出放入与使用SCons相同的目录? [英] How do I get projects to place their build output into the same directory with Scons?

查看:315
本文介绍了我如何获得项目他们构建输出放入与使用SCons相同的目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我通过建立一个具有两个子项目基本的C ++示例项目尝试使用SCons:


  • Prj1是取决于Prj2一个EXE

  • Prj2是部分出口函数的DLL

我遇到的问题是,该库建立自己的OBJ,.PDB,.LIB,.DLL等文件在同一目录,因为它是SConscript文件,而EXE建立在同一个目录作为其文件其SConscript。该应用程序成功生成两个Prj2依赖和自身。但是,你不能运行产生的EXE,因为它无法找到它所需要,因为它是在其他目录库。

问题

我怎样才能有依赖性输出它们的二进制文件和调试信息到一个共同的目录,以便他们可以执行和调试多个项目?

可能的解决方案

这是我想到至今:


  • 我试着用VariantDir(pviously称为BuildDir $ P $),但是这似乎并没有工作。也许我的东西搞​​乱这里。

  • 我可能会告诉编译器和明确的连接(通过佛/依存为例),其中砸他们的文件(这是最好的或唯一的解决办法?)

  • 在生成的二进制代码执行复制命令(这似乎是一个黑客,相当管理/维护疼痛)

更新

我更新了文件结构及以下文件的内容以反映工作液在它的全部内容。感谢哀悼他的洞察力。

命令

通过这种配置,您必须不幸被cd'ing到构建目录,然后运行以下命令执行构建。我需要一个正常工作的别名设置来解决这个问题。

 
建立> scons的../bin/project1.exe

文件结构

  / scons的样本
       /箱
          /发布
          /调试
       /建立
           SConstruct
           scons_helper.py
       / prj1
           SConscript
           /包括
           / src目录
              main.cpp中
       / prj2
          SConscript
          /包括
             functions.h
          / src目录
             functions.cpp

SConstruct

 
进口os.path中BIN_DIR ='../bin
OBJ_DIR ='./obj#--------------------------------------
#CxxTest选项
#--------------------------------------
CXXTEST_DIR ='../extern/CxxTest/CxxTest-latest
PERL ='perl的-w
试验='是* .h
TESTGEN = PERL + CXXTEST_DIR +'/cxxtestgen.pl
CXXTESTGEN_FLAGS ='--runner = ParenPrinter \\
                    --abort-ON-失败\\
                    --have-EH'#--------------------------------------
#选项
#--------------------------------------
的SetOption('implicit_cache',1)#命令行选项
OPTS =选项()
opts.AddOptions(
EnumOption(
            调试,
        Debug版本(用于开发只),
        '不',
        allowed_values​​ =(是,否),
        地图= {},
        IGNORECASE = 1
        )
)#--------------------------------------
# 环境
#--------------------------------------
ENV =环境(    选项​​=选择采用,    #--------------------------------------
    #链接器选项
    #--------------------------------------
    LIBPATH = [
                ../extern/wxWidgets/wxWidgets-latest/lib/vc_dll
              ]    LIBS = [
               #'wxmsw28d_core.lib',
               #'wxbase28d.lib',
               #'wxbase28d_odbc.lib',
               #'wxbase28d_net.lib',
                KERNEL32.LIB',
                USER32.LIB',
                GDI32.LIB',
                winspool.lib',
                comdlg32.lib',
                advapi32.lib',
                SHELL32.LIB',
                ole32.lib',
                oleaut32.lib',
                UUID.LIB',
                odbc32.lib',
                odbccp32.lib
            ]    LINKFLAGS ='/ NOLOGO /子系统:控制台/增量:是/调试/机:I386',    #--------------------------------------
    #编译器选项
    #--------------------------------------
    CPPPATH = [
                '。/包括/',
                ../extern/wxWidgets/wxWidgets-latest/include',
                ../extern/wxWidgets/wxWidgets-latest/vc_dll/mswd
               ]    CPPDEFINES = [
                    WIN32,
                    _DEBUG,
                    '_安慰',
                    _MBCS,
                    WXUSINGDLL',
                    __WXDEBUG__
                 ]    CCFLAGS ='/ W4 / EHSC / RTC1 / MDD / NOLOGO /紫/ TP / errorReport:提示
)env.Decider('MD5时间戳')#对于速度,使用时间戳的变化,其次是MD5
出口('ENV','BIN_DIR')#导出此环境中使用的SConscript文件#--------------------------------------
#建设者
#--------------------------------------
SConscript('../prj1/SConscript')
SConscript('../prj2/SConscript')
默认('prj1')

scons_helper.py

 
进口os.path中#--------------------------------------
# 功能
#--------------------------------------#prepends的完整路径信息输出目录,以便构建
#文件落入由TRGT而不是在指定的目录中
#同一目录下SConscript文件。

#参数:
#ENV - 分配的计划值的环境
#OUTDIR - 你想要的程序二进制文件位置的相对路径放置
#TRGT - 目标应用程序的名称(不带扩展名)
#SRCS - 源文件列表
#参考:
#信用格里夫和他的地方SCons的大师为此:
# http://stackoverflow.com/questions/279860/how-do-i-get-projects-to-place-their-build-output-into-the-same-directory-with
DEF prefixProgram(ENV,OUTDIR,TRGT,索马里红新月会):
    env.Program(目标= os.path.join(OUTDIR,TRGT),源= SRCS)#与上述类似prefixProgram,除了SharedLibrary
DEF prefixSharedLibrary(ENV,OUTDIR,TRGT,索马里红新月会):
    env.SharedLibrary(目标= os.path.join(OUTDIR,TRGT),源= SRCS)DEF prefixFilename(文件名,扩展名):
    返回[(文件名+ EXT)在扩展EXT]#preFIX与源目录中的源文件名
DEF prefixSources(SRCDIR,SRCS):
    返回[os.path.join(SRCDIR中,x),用于在SRCS X]

SConscript为Prj1

 
进口os.path中
进口SYS
sys.path.append('../build')
从scons_helper进口*进口('ENV','BIN_DIR')#导入通用环境prj1_env = env.Clone()#克隆它,所以我们不修改全局的#--------------------------------------
#项目选项
#--------------------------------------
PROG ='PROJECT1#--------------------------------------
#头文件
#--------------------------------------
INC_DIR = [
            ../prj2/include
          ]HEADERS = [
            ''
          ]#--------------------------------------
#源文件
#--------------------------------------
SRC_DIR ='./src
来源= [
            的main.cpp
          ]
#preFIX与源目录中的源文件名
SOURCES = prefixSources(SRC_DIR,来源)#--------------------------------------
#编译器和连接器覆盖
#--------------------------------------
prj1_env.Append(
    CPPPATH = INC_DIR,
    LIBS ='项目2',
    LIBPATH = BIN_DIR,    #微软的Visual Studio的具体
    PDB = os.path.join(BIN_DIR,PROG +'的.pdb)
)#--------------------------------------
#建设者
#--------------------------------------
prefixProgram(prj1_env,BIN_DIR,PROG,来源)

SConscript为Prj2

 
进口os.path中
进口SYS
sys.path.append('../build')
从scons_helper进口*进口('ENV','BIN_DIR')#导入通用环境prj2_env = env.Clone()#克隆它,所以我们不修改全局的#--------------------------------------
#项目选项
#--------------------------------------
PROG =项目2#--------------------------------------
#头文件
#--------------------------------------
INC_DIR = [
             ''
          ]
HEADERS = [
            functions.h
          ]#--------------------------------------
#源文件
#--------------------------------------
SRC_DIR ='./src/
来源= [
            functions.cpp
          ]
#preFIX与源目录中的源文件名
SOURCES = prefixSources(SRC_DIR,来源)#--------------------------------------
#编译器和连接器覆盖
#--------------------------------------
#更新与项目的具体信息环境
prj2_env.Append(
    CPPPATH = INC_DIR,    #微软的Visual Studio的具体
    PDB = os.path.join(BIN_DIR,PROG +'的.pdb)
)#--------------------------------------
#建设者
#--------------------------------------
prefixSharedLibrary(prj2_env,BIN_DIR,PROG,来源)


解决方案

好吧第三次尝试是魅力。我只是把这个在一个新的答案,保持清洁。我跟我的本地scons的大师,他说,安装方法应该可行,但还有一个更简单的方法。

简单地定义你想要的可执行文件(或DLL)去的完整路径。所以:

  prj2_env.Program(目标= os.path.join(BIN_DIR,PROG),源=来源)

如果你不希望有做这在所有的地方,你可以做一个全局函数:

  DEF prefixProgram(ENV,TRGT,索马里红新月会):
    env.Program(目标= os.path.join(ENV。[MY_OUTPUT_DIR],TRGT),源= SRCS)

然后在你的SConscript,是这样的:

 导入('prefixProgram')
# 东东 ...
prefixProgram(prj2_env,PROG,来源)

请注意,您可以将自己的属性添加到环境,这是其中

  ENV [MY_OUTPUT_DIR]

从何而来。我写这篇即兴,所以我们期待一些小的语法错误,什么不是。很明显,你可以使用同样的伎俩共享和静态库。

在充分披露的利益,我给我的本地scons的大师这个回答自己的机会,但他很害怕他会成为沉迷于网站和下降。 :)

Background

I'm trying out Scons by setting up a basic C++ sample project that has two sub-projects:

  • Prj1 is an EXE that depends on Prj2
  • Prj2 is a DLL that exports some functions

The problem I'm running into is that the library builds its .obj, .pdb, .lib, .dll, etc. files in the same directory as it's SConscript file while the EXE builds its files in the same directory as its SConscript. The application successfully builds both the Prj2 dependency and itself. However, you cannot run the resulting EXE because it can't find the library it needs because it is in the other directory.

Question

How can I get multiple projects that have dependences to output their binaries and debug information into a common directory so that they can be executed and debugged?

Potential Solutions

This is what I have thought of so far:

  • I tried using VariantDir (previously called BuildDir) however this doesn't seem to work. Perhaps I'm messing something up here.
  • I could potentially tell the compiler and the linker explicitly (via Fo/Fd for example) where to drop their files (is this the best or only solution???)
  • Execute a copy command on the resulting binaries (this seems like a hack and quite a pain to manage/maintain)

Update

I updated the File Structure and file contents below to reflect the working solution in it's entirety. Thanks to grieve for his insight.

Command

With this configuration, you must unfortunately execute the build by cd'ing to the build directory and then running the command below. I need to get a properly working alias setup to get around this.


build> scons ../bin/project1.exe

File Structure

    /scons-sample
       /bin
          /release
          /debug
       /build
           SConstruct
           scons_helper.py
       /prj1
           SConscript
           /include
           /src
              main.cpp
       /prj2
          SConscript
          /include
             functions.h
          /src
             functions.cpp

SConstruct


import os.path

BIN_DIR = '../bin'
OBJ_DIR = './obj'

#--------------------------------------
#            CxxTest Options
#--------------------------------------
CXXTEST_DIR = '../extern/CxxTest/CxxTest-latest'
PERL = 'perl -w'
TESTS = '*.h'
TESTGEN = PERL + CXXTEST_DIR + '/cxxtestgen.pl'
CXXTESTGEN_FLAGS = '--runner=ParenPrinter \
                    --abort-on-fail \
                    --have-eh'

#--------------------------------------
#            Options
#--------------------------------------
SetOption( 'implicit_cache', 1 )

# command line options
opts = Options()
opts.AddOptions(
EnumOption(
            'debug',
        	'Debug version (useful for developers only)',
        	'no',
        	allowed_values = ('yes', 'no'),
        	map = { },
        	ignorecase = 1
        )
)

#--------------------------------------
#           Environment
#--------------------------------------
env = Environment( 

    options = opts,

    #--------------------------------------
    #           Linker Options
    #--------------------------------------
    LIBPATH = [
                '../extern/wxWidgets/wxWidgets-latest/lib/vc_dll'
              ],

    LIBS =  [
               # 'wxmsw28d_core.lib',
               # 'wxbase28d.lib',
               # 'wxbase28d_odbc.lib',
               # 'wxbase28d_net.lib',
                'kernel32.lib',
                'user32.lib',
                'gdi32.lib',
                'winspool.lib',
                'comdlg32.lib',
                'advapi32.lib',
                'shell32.lib',
                'ole32.lib',
                'oleaut32.lib',
                'uuid.lib',
                'odbc32.lib',
                'odbccp32.lib'
            ],

    LINKFLAGS = '/nologo /subsystem:console /incremental:yes /debug /machine:I386',

    #--------------------------------------
    #           Compiler Options
    #--------------------------------------
    CPPPATH = [
                './include/', 
                '../extern/wxWidgets/wxWidgets-latest/include',
                '../extern/wxWidgets/wxWidgets-latest/vc_dll/mswd'
               ],

    CPPDEFINES = [ 
                    'WIN32',
                    '_DEBUG',
                    '_CONSOLE',
                    '_MBCS',
                    'WXUSINGDLL',
                    '__WXDEBUG__'
                 ],

    CCFLAGS = '/W4 /EHsc /RTC1 /MDd /nologo /Zi /TP /errorReport:prompt'
)

env.Decider( 'MD5-timestamp' )        # For speed, use timestamps for change, followed by MD5
Export( 'env', 'BIN_DIR' )          # Export this environment for use by the SConscript files

#--------------------------------------
#           Builders
#--------------------------------------
SConscript( '../prj1/SConscript' )
SConscript( '../prj2/SConscript' )
Default( 'prj1' )

scons_helper.py


import os.path

#--------------------------------------
#            Functions
#--------------------------------------

# Prepends the full path information to the output directory so that the build
# files are dropped into the directory specified by trgt rather than in the 
# same directory as the SConscript file.
# 
# Parameters:
#   env     - The environment to assign the Program value for
#   outdir  - The relative path to the location you want the Program binary to be placed
#   trgt    - The target application name (without extension)
#   srcs    - The list of source files
# Ref:
#   Credit grieve and his local SCons guru for this: 
#   http://stackoverflow.com/questions/279860/how-do-i-get-projects-to-place-their-build-output-into-the-same-directory-with
def PrefixProgram(env, outdir, trgt, srcs):
    env.Program(target = os.path.join(outdir, trgt), source = srcs)

# Similar to PrefixProgram above, except for SharedLibrary
def PrefixSharedLibrary(env, outdir, trgt, srcs):
    env.SharedLibrary(target = os.path.join(outdir, trgt), source = srcs)

def PrefixFilename(filename, extensions):
    return [(filename + ext) for ext in extensions]

# Prefix the source files names with the source directory
def PrefixSources(srcdir, srcs):
    return  [os.path.join(srcdir, x) for x in srcs]

SConscript for Prj1


import os.path
import sys
sys.path.append( '../build' )
from scons_helper import *

Import( 'env', 'BIN_DIR' )        # Import the common environment

prj1_env = env.Clone()          # Clone it so we don't make changes to the global one

#--------------------------------------
#           Project Options
#--------------------------------------
PROG = 'project1'

#--------------------------------------
#            Header Files
#--------------------------------------
INC_DIR = [
            '../prj2/include'
          ]

HEADERS = [
            ''
          ]

#--------------------------------------
#            Source Files
#--------------------------------------
SRC_DIR = './src'
SOURCES = [
            'main.cpp'
          ]
# Prefix the source files names with the source directory
SOURCES = PrefixSources( SRC_DIR, SOURCES )

#--------------------------------------
#      Compiler and Linker Overrides
#--------------------------------------
prj1_env.Append(
    CPPPATH = INC_DIR,
    LIBS = 'project2',
    LIBPATH = BIN_DIR,

    # Microsoft Visual Studio Specific
    PDB = os.path.join( BIN_DIR, PROG + '.pdb' )
)

#--------------------------------------
#            Builders
#--------------------------------------
PrefixProgram( prj1_env, BIN_DIR, PROG, SOURCES )

SConscript for Prj2


import os.path   
import sys
sys.path.append( '../build' )
from scons_helper import *

Import( 'env', 'BIN_DIR' )        # Import the common environment

prj2_env = env.Clone()          # Clone it so we don't make changes to the global one

#--------------------------------------
#           Project Options
#--------------------------------------
PROG = 'project2'

#--------------------------------------
#            Header Files
#--------------------------------------
INC_DIR = [
             ''
          ]
HEADERS = [
            'functions.h'
          ]

#--------------------------------------
#            Source Files
#--------------------------------------
SRC_DIR = './src/'
SOURCES = [
            'functions.cpp'
          ]
# Prefix the source files names with the source directory
SOURCES = PrefixSources( SRC_DIR, SOURCES )

#--------------------------------------
#      Compiler and Linker Overrides
#--------------------------------------
# Update the environment with the project specific information
prj2_env.Append(
    CPPPATH = INC_DIR,

    # Microsoft Visual Studio Specific
    PDB = os.path.join( BIN_DIR, PROG + '.pdb' )
)

#--------------------------------------
#               Builders
#--------------------------------------
PrefixSharedLibrary( prj2_env, BIN_DIR, PROG, SOURCES )

解决方案

Ok Third try is a charm. I am just placing this in a new answer to keep it cleaner. I talked with my local scons guru, and he stated that the install method should work, but there is a much easier way.

Simply define the full path where you want the executable (or dll) to go. So:

prj2_env.Program(target = os.path.join(BIN_DIR,PROG), source = SOURCES )

If you don't want to have to do this in all places you can make a global function:

def PrefixProgram(env, trgt, srcs):
    env.Program(target = os.path.join(env.["MY_OUTPUT_DIR"], trgt), source = srcs)

Then in your SConscript, something like:

import ('PrefixProgram')
# stuff ...
PrefixProgram(prj2_env, PROG, SOURCES)

Note that you can add your own attribute to the environment, which is where the

env["MY_OUTPUT_DIR"]

comes from. I wrote this off the cuff, so expect some minor syntax errors and what not. Obviously you can apply the same trick for shared and static libraries.

In the interest of full disclosure I offered my local scons guru the chance to answer this himself, but he was scared he would become addicted to the site and declined. :)

这篇关于我如何获得项目他们构建输出放入与使用SCons相同的目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆