Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ NOTE: Python 3.6 support is deprecated and will be dropped in a future release.

RELEASE VERSION/DATE TO BE FILLED IN LATER

From Ruben Di Battista:
- Expose `extra_libs` kwarg in Configure checks `CheckLibWithHeader`
and 'CheckLib' and forward it downstream to `CheckLib`

From Joseph Brill:
- Added error handling when creating MSVC detection debug log file specified by
SCONS_MSCOMMON_DEBUG.
Expand Down
1 change: 1 addition & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ DEPRECATED FUNCTIONALITY

CHANGED/ENHANCED EXISTING FUNCTIONALITY
---------------------------------------
- Expose the `extra_libs` keyword argument in `CheckLibWithHeader` and 'CheckLib'

- List modifications to existing features, where the previous behavior
wouldn't actually be considered a bug
Expand Down
33 changes: 22 additions & 11 deletions SCons/SConf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1101,12 +1101,17 @@ def CheckCXXHeader(context, header, include_quotes: str = '""'):


def CheckLib(context, library = None, symbol: str = "main",
header = None, language = None, autoadd: bool=True,
append: bool=True, unique: bool=False) -> bool:
header = None, language = None, extra_libs = None,
autoadd: bool=True, append: bool=True, unique: bool=False) -> bool:
"""
A test for a library. See also CheckLibWithHeader.
A test for a library. See also :func:`CheckLibWithHeader`.
Note that library may also be None to test whether the given symbol
compiles without flags.

.. versionchanged:: NEXT_RELEASE
Added the *extra_libs* keyword parameter. The actual implementation
is in :func:`SCons.Conftest.CheckLib` which already accepted this
parameter, so this is only exposing existing functionality.
"""

if not library:
Expand All @@ -1116,25 +1121,31 @@ def CheckLib(context, library = None, symbol: str = "main",
library = [library]

# ToDo: accept path for the library
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
language = language, autoadd = autoadd,
append=append, unique=unique)
res = SCons.Conftest.CheckLib(context, library, symbol, header=header,
language=language, extra_libs=extra_libs,
autoadd=autoadd, append=append, unique=unique)
context.did_show_result = True
return not res

# XXX
# Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H.

def CheckLibWithHeader(context, libs, header, language,
call = None, autoadd: bool=True, append: bool=True, unique: bool=False) -> bool:
# ToDo: accept path for library. Support system header files.
extra_libs = None, call = None, autoadd: bool=True,
append: bool=True, unique: bool=False) -> bool:
"""
Another (more sophisticated) test for a library.
Checks, if library and header is available for language (may be 'C'
or 'CXX'). Call maybe be a valid expression _with_ a trailing ';'.
As in CheckLib, we support library=None, to test if the call compiles
As in :func:`CheckLib`, we support library=None, to test if the call compiles
without extra link flags.

.. versionchanged:: NEXT_RELEASE
Added the *extra_libs* keyword parameter. The actual implementation
is in :func:`SCons.Conftest.CheckLib` which already accepted this
parameter, so this is only exposing existing functionality.
"""
# ToDo: accept path for library. Support system header files.
prog_prefix, dummy = createIncludesFromHeaders(header, 0)
if not libs:
libs = [None]
Expand All @@ -1143,8 +1154,8 @@ def CheckLibWithHeader(context, libs, header, language,
libs = [libs]

res = SCons.Conftest.CheckLib(context, libs, None, prog_prefix,
call = call, language = language, autoadd=autoadd,
append=append, unique=unique)
extra_libs = extra_libs, call = call, language = language,
autoadd=autoadd, append=append, unique=unique)
context.did_show_result = 1
return not res

Expand Down
58 changes: 43 additions & 15 deletions doc/man/scons.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4163,7 +4163,7 @@ function calls whose arguments are not type compatible with the prototype.
</varlistentry>

<varlistentry>
<term><replaceable>context</replaceable>.<methodname>CheckLib</methodname>(<parameter>[library, symbol, header, language, autoadd=True, append=True, unique=False]</parameter>) </term>
<term><replaceable>context</replaceable>.<methodname>CheckLib</methodname>(<parameter>[library, symbol, header, language, extra_libs=None, autoadd=True, append=True, unique=False]</parameter>) </term>
<listitem>
<para>Checks if
<parameter>library</parameter>
Expand All @@ -4173,12 +4173,19 @@ with the compiler selected by <parameter>language</parameter>,
and optionally adds that library to the context.
If supplied, the text of <parameter>header</parameter> is included at the
top of the stub.
</para>
<para>
The remaining arguments should be specified in keyword style.
If <parameter>extra_libs</parameter> is specified,
it is a list off additional libraries to include when
linking the stub program (usually, dependencies of
the library being checked).
If <parameter>autoadd</parameter> is true (the default),
and the library provides the specified
<parameter>symbol</parameter> (as defined by successfully
linking the stub program),
<parameter>symbol</parameter>,
as defined by successfully linking the stub program,
it is added to the &cv-link-LIBS; &consvar; in the context.
if <parameter>append</parameter> is true (the default),
If <parameter>append</parameter> is true (the default),
the library is appended, otherwise it is prepended.
If <parameter>unique</parameter> is true,
and the library would otherwise be added but is
Expand Down Expand Up @@ -4212,38 +4219,53 @@ at least one should be supplied.
<emphasis>Changed in version 4.5.0: added the
<parameter>append</parameter> and <parameter>unique</parameter>
parameters.</emphasis>
</para>
<para>
<emphasis>Changed in version NEXT_RELEASE: added the
<parameter>extra_libs</parameter> parameter.</emphasis>
</para>
</listitem>
</varlistentry>

<varlistentry>
<term><replaceable>context</replaceable>.<methodname>CheckLibWithHeader</methodname>(<parameter>library, header, [language, call, autoadd=True, append=True, unique=False]</parameter>)</term>
<term><replaceable>context</replaceable>.<methodname>CheckLibWithHeader</methodname>(<parameter>[library, header, language, extra_libs=None, call=None, autoadd=True, append=True, unique=False]</parameter>)</term>
<listitem>

<para>Provides an alternative to the
<methodname>CheckLib</methodname> method
for checking for libraries usable in a build.
for checking whether libraries are usable in a build.
The first three arguments can be given as
positional or keyword style arguments.
<parameter>library</parameter>
specifies a library or list of libraries to check.
specifies a library or list of libraries to check
(the default is <literal>None</literal>),
<parameter>header</parameter>
specifies a header to include in the test program,
and <parameter>language</parameter> indicates the compiler to use.
specifies header text to include in the test program.
<parameter>header</parameter>
may be a list,
may also be a list,
in which case the last item in the list
is the header file to be checked,
and the previous list items are
header files whose
<literal>#include</literal>
lines should precede the
header line being checked for.
A code fragment
(must be a valid expression, including a trailing semicolon)
to serve as the test can be supplied in
<parameter>call</parameter>;
if not supplied,
The default is to include no header text.
<parameter>language</parameter> indicates the compiler to use
(default "C").
</para>

<para>
The remaining parameters should be specified in keyword style.
If provided, <parameter>call</parameter>
is a code fragment to compile as the stub test,
replacing the auto-generated stub.
The fragment must be a valid expression in <parameter>language</parameter>.
If not supplied,
the default checks the ability to link against the specified
<parameter>library</parameter>.
<parameter>extra_libs</parameter> can be used to add additional libraries
to link against (usually, dependencies of the library under test).
If <parameter>autoadd</parameter> is true (the default),
the first library that passes the check
is added to the &cv-link-LIBS; &consvar; in the context
Expand All @@ -4255,11 +4277,17 @@ and the library would otherwise be added but is
already present in &cv-link-LIBS; in the configure context,
it will not be added again. The default is <literal>False</literal>.
</para>

<para>Returns a boolean indicating success or failure.</para>

<para>
<emphasis>Changed in version 4.5.0: added the
<parameter>append</parameter> and <parameter>unique</parameter>
parameters.</emphasis>
</para>
<para>
<emphasis>Changed in version NEXT_RELEASE: added the
<parameter>extra_libs</parameter> parameter.</emphasis>
</para>
</listitem>
</varlistentry>
Expand Down
64 changes: 64 additions & 0 deletions test/Configure/CheckLibWithHeader_extra_libs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python
#
# MIT License
#
# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

"""
Verify that a program which depends on library which in turn depends
on another library can be built correctly using CheckLibWithHeader
"""

from pathlib import Path

from TestSCons import TestSCons, dll_, _dll

test = TestSCons(match=TestSCons.match_re_dotall)

# This is the first library project
libA_dir = Path(test.workdir) / "libA"
libA_dir.mkdir()
libA = str(libA_dir / (dll_ + 'A' + _dll)) # for existence check
test.dir_fixture(['fixture', 'checklib_extra', 'libA'], 'libA')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should just be able to do this once as
test.dir_fixture(['fixture', 'checklib_extra'])

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose. If you think it's worth doing yet another iteration...


# This is the second library project, depending on the first
libB_dir = Path(test.workdir) / "libB"
libB_dir.mkdir()
libB = str(libB_dir / (dll_ + 'B' + _dll)) # for existence check
test.dir_fixture(['fixture', 'checklib_extra', 'libB'], 'libB')

test.run(arguments='-C libA')
test.must_exist(libA)
test.run(arguments='-C libB')
test.must_exist(libB)

test.file_fixture(['fixture', 'checklib_extra', 'SConstruct'])
test.dir_fixture(['fixture', 'checklib_extra', 'src'], 'src')
test.run()

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
30 changes: 30 additions & 0 deletions test/Configure/fixture/checklib_extra/SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SPDX-License-Identifier: MIT
#
# Copyright The SCons Foundation

env = Environment(
CPPPATH=['#'],
LIBPATH=['libB', 'libA'],
LIBS=['A', 'B'],
RPATH=['libA', 'libB'],
)

conf = Configure(env)
if not conf.CheckLibWithHeader(
['B'],
header="libB/libB.h",
language='C',
extra_libs=['A'],
call='libB();',
autoadd=False,
):
print("Cannot build against 'B' library, exiting.")
Exit(1)
env = conf.Finish()

# TODO: we should be able to build and run a test program now,
# to make sure Configure() didn't lie to us about usability.
# Disabled for now, because that's trickier in Windows (the rpath
# only works for Linux)
# env.Program(target="testlibs", source="src/test.c")

Empty file.
6 changes: 6 additions & 0 deletions test/Configure/fixture/checklib_extra/libA/SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: MIT
#
# Copyright The SCons Foundation

SharedLibrary(target='A', source=['libA.c'], CPPDEFINES='BUILDINGSHAREDLIB')

10 changes: 10 additions & 0 deletions test/Configure/fixture/checklib_extra/libA/libA.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
//
// Copyright The SCons Foundation

#include <stdio.h>
#include "libA.h"

LIBA_DECL void libA(void) {
printf("libA\\n");
}
22 changes: 22 additions & 0 deletions test/Configure/fixture/checklib_extra/libA/libA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
//
// Copyright The SCons Foundation

#ifndef _LIBA_H
#define _LIBA_H

// define BUILDINGSHAREDLIB when building libA as shared lib
#ifdef _MSC_VER
# ifdef BUILDINGSHAREDLIB
# define LIBA_DECL __declspec(dllexport)
# else
# define LIBA_DECL __declspec(dllimport)
# endif
#endif // WIN32

#ifndef LIBA_DECL
# define LIBA_DECL
#endif

LIBA_DECL void libA(void);
#endif // _LIBA_H
12 changes: 12 additions & 0 deletions test/Configure/fixture/checklib_extra/libB/SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: MIT
#
# Copyright The SCons Foundation

SharedLibrary(
target='B',
source=['libB.c'],
LIBS=['A'],
LIBPATH='../libA',
CPPPATH='../libA',
CPPDEFINES='BUILDINGSHAREDLIB',
)
12 changes: 12 additions & 0 deletions test/Configure/fixture/checklib_extra/libB/libB.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
//
// Copyright The SCons Foundation

#include <stdio.h>
#include "libA.h"
#include "libB.h"

LIBB_DECL void libB (void) {
printf("libB\\n");
libA();
}
22 changes: 22 additions & 0 deletions test/Configure/fixture/checklib_extra/libB/libB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
//
// Copyright The SCons Foundation

#ifndef _LIBB_H
#define _LIBB_H

// define BUILDINGSHAREDLIB when building libB as shared lib
#ifdef _MSC_VER
# ifdef BUILDINGSHAREDLIB
# define LIBB_DECL __declspec(dllexport)
# else
# define LIBB_DECL __declspec(dllimport)
# endif
#endif // WIN32

#ifndef LIBB_DECL
# define LIBB_DECL
#endif

LIBB_DECL void libB(void);
#endif // _LIBB_H
6 changes: 6 additions & 0 deletions test/Configure/fixture/checklib_extra/src/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "libB/libB.h"

int main()
{
libB();
}
Loading