SCons 链接 DLL 导致依赖循环
SCons linking DLL cause a dependency cycle
这是我的图书馆的一个小例子。我有一个库 lib.c
和一个使用该库的应用程序 app.c
。我正在使用 Scons 来编译库和应用程序。 (脚本如下)
- 最初,我使用
lib = env.Library(...)
将 lib 编译为静态库并将库附加到 env env.Prepend(LIBS=[lib])
编译应用程序 env.Program(...)
,一切正常,没有依赖性错误。
- 现在我尝试将我的库编译为共享库。我添加了
__declspec(dllxxxx)
并使用 lib = env.SharedLibrary(...)
编译了库,就像在将库附加到 env env.Prepend(LIBS=[lib])
编译应用程序 env.Program(...)
之前一样,现在我得到了这个依赖错误
scons: *** Found dependency cycle(s):
lib.dll -> lib.lib -> lib.exp -> lib.dll
lib.lib -> lib.lib
lib.exp -> lib.lib -> lib.exp
我做错了什么,如何解决这个问题?
lib.c
__declspec(dllexport) int add(int a, int b);
int add(int a, int b) {
return a + b;
}
app.c
#include<stdio.h>
__declspec(dllimport) int add(int a, int b);
int main() {
printf("%i\n", add(1, 2));
return 0;
}
S构造
import os
env = DefaultEnvironment(TARGET_ARCH = 'x86_64')
os.environ['PATH'] = env['ENV']['PATH'] ## for "cl.exe"
lib = env.SharedLibrary(
target = 'lib',
source = 'lib.c')
env.Prepend(LIBS=[lib])
env.Program(
target = 'app',
source = 'app.c')
循环来自获取 SharedLibrary
的结果并将其添加到 LIBS
:来自调用的 return 是一个 NodeList - 包含三个文件的节点表示lib.dll
、lib.lib
、lib.exp
。您可以打印 lib
的值以查看此内容。
我已经添加了您的示例(已修改为我认为您正在努力实现的功能)。
请参阅下面 SConstruct 中的注释。
注意
env=DefaultEnvironment()
不是推荐的用法。
请使用
env=Environment()
同样在我新安装 MSVC 2019 的机器上,SCons 找到了编译器并默认生成了 X86_64 个二进制文件。 (如果编译器支持那个架构,SCons 应该默认为“本地”架构,否则它会尝试 x86)
的 msvc 调试输出
set SCONS_MSCOMMON_DEBUG=%TEMP%\SCONS_MSVS_DEBUG.log
这将有助于确定您为什么会遇到 SCons 的本机查找 MSVC 安装并正确配置它的问题。
另外,请考虑加入我们 https://discord.gg/bXVpWAy 以获得进一步的帮助。
见:
https://github.com/SCons/scons-examples/tree/master/shared-lib-program
S构造
# Skip initializing any tools in the DefaultEnvironment
# as we're not using it.
DefaultEnvironment(tools=[])
env = Environment()
lib = env.SharedLibrary(
target = 'a',
source = 'lib.c')
# We list the library by it's base name 'a' and not a.dll, or liba.a because SCons
# will expand this to the appropriate platform/compiler dependent file name
# and use the correct arguments to the linker to link against the shared library 'a'
# NOTE: We use LIBS here instead of env['LIBS']=['a'] as we're also building the
# shared library above with the same Environment().
# Having env.Prepend(LIBS=['a']) would cause the SharedLibrary() above to ALSO
# try to link against shared library a. (Or on win32 file 'a.lib') and fail.
env.Program(
target = 'app',
source = 'app.c',
LIBS=['a',])
app.c
#include<stdio.h>
__declspec(dllimport) int add(int a, int b);
int main() {
printf("%i\n", add(1, 2));
return 0;
}
lib.c
__declspec(dllexport) int add(int a, int b);
int add(int a, int b) {
return a + b;
}
这是我的图书馆的一个小例子。我有一个库 lib.c
和一个使用该库的应用程序 app.c
。我正在使用 Scons 来编译库和应用程序。 (脚本如下)
- 最初,我使用
lib = env.Library(...)
将 lib 编译为静态库并将库附加到 envenv.Prepend(LIBS=[lib])
编译应用程序env.Program(...)
,一切正常,没有依赖性错误。 - 现在我尝试将我的库编译为共享库。我添加了
__declspec(dllxxxx)
并使用lib = env.SharedLibrary(...)
编译了库,就像在将库附加到 envenv.Prepend(LIBS=[lib])
编译应用程序env.Program(...)
之前一样,现在我得到了这个依赖错误
scons: *** Found dependency cycle(s):
lib.dll -> lib.lib -> lib.exp -> lib.dll
lib.lib -> lib.lib
lib.exp -> lib.lib -> lib.exp
我做错了什么,如何解决这个问题?
lib.c
__declspec(dllexport) int add(int a, int b);
int add(int a, int b) {
return a + b;
}
app.c
#include<stdio.h>
__declspec(dllimport) int add(int a, int b);
int main() {
printf("%i\n", add(1, 2));
return 0;
}
S构造
import os
env = DefaultEnvironment(TARGET_ARCH = 'x86_64')
os.environ['PATH'] = env['ENV']['PATH'] ## for "cl.exe"
lib = env.SharedLibrary(
target = 'lib',
source = 'lib.c')
env.Prepend(LIBS=[lib])
env.Program(
target = 'app',
source = 'app.c')
循环来自获取 SharedLibrary
的结果并将其添加到 LIBS
:来自调用的 return 是一个 NodeList - 包含三个文件的节点表示lib.dll
、lib.lib
、lib.exp
。您可以打印 lib
的值以查看此内容。
我已经添加了您的示例(已修改为我认为您正在努力实现的功能)。
请参阅下面 SConstruct 中的注释。 注意
env=DefaultEnvironment()
不是推荐的用法。 请使用
env=Environment()
同样在我新安装 MSVC 2019 的机器上,SCons 找到了编译器并默认生成了 X86_64 个二进制文件。 (如果编译器支持那个架构,SCons 应该默认为“本地”架构,否则它会尝试 x86)
的 msvc 调试输出set SCONS_MSCOMMON_DEBUG=%TEMP%\SCONS_MSVS_DEBUG.log
这将有助于确定您为什么会遇到 SCons 的本机查找 MSVC 安装并正确配置它的问题。 另外,请考虑加入我们 https://discord.gg/bXVpWAy 以获得进一步的帮助。
见: https://github.com/SCons/scons-examples/tree/master/shared-lib-program
S构造
# Skip initializing any tools in the DefaultEnvironment
# as we're not using it.
DefaultEnvironment(tools=[])
env = Environment()
lib = env.SharedLibrary(
target = 'a',
source = 'lib.c')
# We list the library by it's base name 'a' and not a.dll, or liba.a because SCons
# will expand this to the appropriate platform/compiler dependent file name
# and use the correct arguments to the linker to link against the shared library 'a'
# NOTE: We use LIBS here instead of env['LIBS']=['a'] as we're also building the
# shared library above with the same Environment().
# Having env.Prepend(LIBS=['a']) would cause the SharedLibrary() above to ALSO
# try to link against shared library a. (Or on win32 file 'a.lib') and fail.
env.Program(
target = 'app',
source = 'app.c',
LIBS=['a',])
app.c
#include<stdio.h>
__declspec(dllimport) int add(int a, int b);
int main() {
printf("%i\n", add(1, 2));
return 0;
}
lib.c
__declspec(dllexport) int add(int a, int b);
int add(int a, int b) {
return a + b;
}