[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