[Scons-users] Shared library in bin subdirectory

William Deegan bill at baddogconsulting.com
Fri Dec 28 20:47:27 EST 2012



On Dec 28, 2012, at 4:05 PM, LRN wrote:


> -----BEGIN PGP SIGNED MESSAGE-----

> Hash: SHA1

>

> On 28.12.2012 20:31, William Deegan wrote:

>> On 12/28/2012 12:04 AM, LRN wrote:

>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1

>>>

>>> On 28.12.2012 11:32, William Deegan wrote:

>>>> On 12/27/2012 11:26 PM, LRN wrote:

>>>>>>>>> Here's what i do:

>>>>>>>>>

>>>>>>>>> prefix = ARGUMENTS.get ('prefix', None) destdir =

>>>>>>>>> ARGUMENTS.get ('destdir', None) if prefix == None:

>>>>>>>>> prefix = '/usr/local'

>>>>>>>>>

>>>>>>>>> foo = env.SharedLibrary (target = "foo", source =

>>>>>>>>> ["foo.c"], SHLIBPREFIX = 'lib', LIBSUFFIX='.dll.a')

>>>>>>>>> if destdir is not None: destprefix = destdir +

>>>>>>>>> prefix env.Install (os.path.join (destprefix, 'bin'),

>>>>>>>>> [foo]) env.Alias('install', destprefix)

>>>>>>>>>

>>>>>>>>> And when i do `scons prefix=/ destdir=c:/bar

>>>>>>>>> install', i end up having libfoo.dll.a import library

>>>>>>>>> in c:/bar/bin/ directory instead of c:/bar/lib. How

>>>>>>>>> do i make SharedLibrary or Install put the import

>>>>>>>>> library into /lib subdirectory?

>>>>>>>>>

>>>>>>>> Here's your problem: env.Install (os.path.join

>>>>>>>> (destprefix, 'bin'), [foo])

>>>>>>>>

>>>>>>>> Change 'bin' to 'lib'...

>>>>>>> Thank you for your quick response.

>>>>>>>

>>>>>>> I've tried that, and it works - libfoo.dll.a is

>>>>>>> installed into /lib subdir!

>>>>>>>

>>>>>>> However, a completely unrelated problem has cropped up:

>>>>>>> Now when i do `scons prefix=/ destdir=c:/bar install', i

>>>>>>> end up having libfoo.dll shared library in c:/bar/lib/

>>>>>>> directory instead of c:/bar/bin. How do i make

>>>>>>> SharedLibrary or Install put the shared library into /bin

>>>>>>> subdirectory?

>>>>>>>

>>>>>> Any builder only specifies 1 target dir. If you want to

>>>>>> have the output(s) go to more than one, then you'll have to

>>>>>> use env.Install() to do so.

>>>>>>

>>>>> And how do i do that? According to the man,

>>>>>> Installs one or more source files or directories in the

>>>>>> specified target, which must be a directory. The names of

>>>>>> the specified source files or directories remain the same

>>>>>> within the destination directory.

>>>>>> env.Install('/usr/local/bin', source = ['foo', 'bar'])

>>>>> only one directory is passed to Install. And even if it

>>>>> accepted two directories, i wouldn't want to have .dll and

>>>>> .dll.a in BOTH /bin and /lib subdirs. So, how do i put .dll

>>>>> in /bin and .dll.a. in /lib?

>>>> All env.BLAH's return a list of Node's. so:

>>>> libs=env.SharedLibrary('blah',[sources]) On windows will return

>>>> a list with more than one Nodes. Now you could iterate through

>>>> that list and get the file names and install the .dll one place

>>>> and the .dll.a another place

>>> Yeah, that worked! Thanks! I did:

>>>

>>> foo = env.SharedLibrary (target = "foo", source = ["foo.c"],

>>> SHLIBPREFIX = 'lib', LIBSUFFIX='.dll.a') str_foo = {} for x in

>>> foo: str_foo[str(x)] = x

>>>

>>> if destdir is not None: destprefix = destdir + prefix for s_x, x

>>> in str_foo.items (): if s_x[-2:] == '.a': env.Install

>>> (os.path.join (destprefix, 'lib'), x) else: env.Install

>>> (os.path.join (destprefix, 'bin'), x)

>>>

>>> env.Alias('install', destprefix)

>>>

>>>

>>> Now, the library is not supposed to build on anything that does

>>> not provide W32API, and so, it not being portable, i don't have

>>> to worry about SharedLibrary NOT returning a list, but i'm just

>>> curious: what does SharedLibrary return when it builds only one

>>> .so file? Single node? Or a list with one item? And how would i

>>> have to deal with that, if the library was portable, and

>>> SConstruct would have had to work on different OSes?

>>

>> Builders always return a list. Sometimes the list has only one

>> element, but always a list. You could define your Environment

>> differently for each platform and specify SHLIBSUFFIX and LIBSUFFIX

>> appropriately.

> Ok.

>> Any reason you don't use the default .lib instead of .dll.a ?

> Uh...you do know that gcc toolchain uses .a static libraries and

> .dll.a import libraries, right? And that in 99% cases ld can't link

> .lib libraries (by the way, i can't even remember now whether msvc has

> the concept of import libraries or not...) at all, so using the .lib

> extension just makes no sense?


So you're using mingw?

Yes. MSVC shared library builder outputs .dll .lib .def .exp I think are all the possible outputs.
And .lib inputs. (been a while so I'm not 100% sure)


>

>>>

>>>> (UGH.. you snipped the meat of the message.. please don't do

>>>> that).

>>> Uh, what?

>>>

>>>> , or you could just tell SCons to install the .dll from the

>>>> target dir of the SharedLibrary() to /bin and the .dll.a to

>>>> /lib as such:

>>>>

>>>> foo = env.SharedLibrary (target = "foo", source = ["foo.c"],

>>>> SHLIBPREFIX = 'lib', LIBSUFFIX='.dll.a')

>>>> env.Install('/bin','libfoo.dll')

>>>> env.Install('/lib','libfoo.dll.a')

>>>>

>>>> SCons will then connect the dots. (change the second arguments

>>>> of the installs to match the directory you're building them

>>>> into via your SharedLibrary().

>>> ...and for that i need to somehow know where the builddir is,

>>> and where the .dll and .dll.a files end up, and how they are

>>> named. Ok, the naming part should be obvious, since i did provide

>>> prefix and suffix. But the rest is not so obvious.

>> Not sure why it's not obvious what the build dir is. You specify it

>> in the first argument of the builder...

> Wait, the builder - that's the SharedLibrary() function, right? Its

> first argument is name of the target (in this case - name of the

> library). Not the build directory.


The default build directory is the same directory as the SConscript/SConstruct, are you using VariantDir()?

-BIll


More information about the Scons-users mailing list