14

In my SConscript I have the following line:

Program("xtest", Split("main.cpp"), LIBS="mylib fltk Xft Xinerama Xext X11 m")

How do I get scons to use mylib.a instead of mylib.so, while linking dynamically with the other libraries?

EDIT: Looking to use as few platform specific hacks as possible.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
codehero
  • 157
  • 1
  • 1
  • 8
  • Does http://www.scons.org/wiki/StaticallyLink help you here? – BjoernD Jun 07 '10 at 06:26
  • The solution is highly specific to only gcc runtime libs. It also uses hacks like specifying "libNAME.a", which is Linux specific (need to compile on MinGW too...) – codehero Jun 07 '10 at 12:02

2 Answers2

15

Passing the full filepath wrapped in a File node will force static linking. For example:

lib = File('/usr/lib/libfoo.a')
Program('bar', 'main.c', LIBS = [lib])

Will produce the following linker command line

g++ -o bar main.o /usr/lib/libfoo.a

Notice how the "-l" flag is not passed to the linker for this LIBS entry. This effectively forces static linking. The alternative is to modify LINKFLAGS to get what you want with the caveat that you are bypassing the library dependency scanner -- the status of the library will not be checked for rebuilds.

BenG
  • 1,292
  • 8
  • 11
  • I have verified that the solution works. However, I will note that my solution resembles more: SConscript: ... lib = File(env.MyLibFile) and in the SConstruct: env.MyLibFile = "/usr/lib/libfoo.a") So that my windows SConstruct can override the filename. – codehero Jun 08 '10 at 11:45
  • This is not platform independent. To achieve that use the SHLIB suffix as noted in my answer. Like File('libfoo'+env['SHLIBSUFFIX']) – daramarak Jun 08 '10 at 14:03
  • Yes, good point about the use of platform-independent variables for prefix and suffix. – BenG Jun 09 '10 at 04:31
  • SHLIBSUFFIX is ".so" on Linux. That's for shared libraries. You;d need LIBSUFFIX (and LIBPREFIX, instead of explicit "lib") – Evgen Jun 03 '16 at 01:20
5

To make this platform independent you append the env['SHLIBSUFFIX'] onto the library you want to use. env['SHLIBSUFFIX'] gives you this environments suffix for shared libraries.

You also have the ['SHLIBPREFIX'], ['LIBPREFIX'], ['LIBSUFFIX'] and ['PROGSUFFIX'], all useful for situations like this.

Edit:

I obviously haven't made myself understood, so I will clarify. The return value of these lookups are strings to the pre/suffixes that platform uses. In that way you can refer to the file you need on each platform. Note that you cannot use it as a pure string, it has to be embedded as a file node as BennyG suggests. Working with nodes are anyway the best solution as file nodes are much more versatile than a string.

Hope this helps.

daramarak
  • 6,115
  • 1
  • 31
  • 50
  • I don't think any of those variables apply in this situation. The linker is actually doing the selection between the static vs. dynamic libraries when it finds both on disk. The pre/suffixes you mention only change the filename patterns of targets declared in scons. – BenG Jun 08 '10 at 09:10
  • env[SHLIBSUFFIX] returns as string containing the file suffix of the platform you are after. It would be a nice idea to test the answers this before actually downvoting. – daramarak Jun 08 '10 at 14:05