c++ build scons

c++ - ¿Cómo puedo obtener proyectos para colocar su salida de compilación en el mismo directorio con Scons?



build (2)

Ok, el tercer intento es un encanto. Solo estoy colocando esto en una nueva respuesta para mantenerlo más limpio. Hablé con mi gurú scons local, y afirmó que el método de instalación debería funcionar, pero que hay una manera mucho más sencilla.

Simplemente defina la ruta completa a la que desea que vaya el ejecutable (o dll). Asi que:

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

Si no desea tener que hacer esto en todos los lugares, puede realizar una función global:

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

Luego, en su SCONScript, algo como:

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

Tenga en cuenta que puede agregar su propio atributo al entorno, que es donde

env["MY_OUTPUT_DIR"]

viene de. Lo escribí de la manga, así que espere algunos errores de sintaxis menores y lo que no. Obviamente, puede aplicar el mismo truco para bibliotecas compartidas y estáticas.

Con el interés de la revelación completa, le ofrecí a mi gurú scons local la oportunidad de responder él solo, pero tenía miedo de que se volviera adicto al sitio y lo rechazara. :)

Fondo

Estoy probando Scons configurando un proyecto de muestra básico de C ++ que tiene dos subproyectos:

  • Prj1 es un EXE que depende de Prj2
  • Prj2 es una DLL que exporta algunas funciones

El problema al que me estoy enfrentando es que la biblioteca crea sus archivos .obj, .pdb, .lib, .dll, etc. en el mismo directorio que su archivo SConscript mientras el EXE crea sus archivos en el mismo directorio que SConscript. La aplicación construye con éxito tanto la dependencia Prj2 como ella misma. Sin embargo, no puede ejecutar el EXE resultante porque no puede encontrar la biblioteca que necesita porque está en el otro directorio.

Pregunta

¿Cómo puedo obtener múltiples proyectos que tienen dependencias para generar sus binarios y depurar información en un directorio común para que puedan ser ejecutados y depurados?

Soluciones potenciales

Esto es lo que he pensado hasta ahora:

  • Traté de usar VariantDir (anteriormente llamado BuildDir) sin embargo, esto no parece funcionar. Quizás estoy estropeando algo aquí.
  • Podría decirle al compilador y al enlazador explícitamente (a través de Fo / Fd por ejemplo) dónde soltar sus archivos (¿es esta la mejor o la única solución?)
  • Ejecute un comando de copia en los binarios resultantes (esto parece un truco y un gran dolor para administrar / mantener)

Actualizar

Actualicé la estructura del archivo y el contenido del archivo a continuación para reflejar la solución de trabajo en su totalidad. Gracias a la pena por su visión.

Mando

Con esta configuración, desafortunadamente debe ejecutar la compilación haciendo clic en el directorio de compilación y luego ejecutando el siguiente comando. Necesito tener una configuración de alias que funcione correctamente para evitar esto.

build> scons ../bin/project1.exe

Estructura de archivo

/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 para 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 para 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 )


VariantDir es la forma de hacer esto. ¿Cómo llama tu Sconstruct tus archivos de Sconscript? También ha leído esta sección de la documentación: http://www.scons.org/doc/1.1.0/HTML/scons-user/c3271.html (supongo que tiene).

Cuanto más lo pienso, más creo que quieres usar una combinación de Predeterminado e Instalar

En su llamada SConscripts

env.Install("../bin", <your target exe or dll>)

luego en tu llamada Sconstruct

env.Alias(''install'', "../bin") Default(''install'')

Eso debería ser el truco, y creo que los enlaces dejan en claro cómo funciona todo junto.