链接DLL的SCON会导致依赖循环

链接DLL的SCON会导致依赖循环,c,windows,dll,scons,C,Windows,Dll,Scons,这是我的图书馆的一个小例子。我有一个库lib.c和一个使用库的应用程序app.c。我用它来编译库和应用程序。(脚本如下) 最初,我使用lib=env.library(…)将lib编译为一个静态库,并将库附加到envenv.Prepend(LIBS=[lib])编译appenv.Program(…),一切正常,没有依赖性错误 现在我尝试将我的库编译为一个共享库。我添加了\uuu declspec(dllxxx)并使用lib=env.SharedLibrary(…)等编译库,然后将库附加到enve

这是我的图书馆的一个小例子。我有一个库
lib.c
和一个使用库的应用程序
app.c
。我用它来编译库和应用程序。(脚本如下)

  • 最初,我使用
    lib=env.library(…)
    将lib编译为一个静态库,并将库附加到env
    env.Prepend(LIBS=[lib])
    编译app
    env.Program(…)
    ,一切正常,没有依赖性错误
  • 现在我尝试将我的库编译为一个共享库。我添加了
    \uuu declspec(dllxxx)
    并使用
    lib=env.SharedLibrary(…)
    等编译库,然后将库附加到env
    env.Prepend(LIBS=[lib])
    编译应用程序
    env.Program(…)
    ,现在我得到了这个依赖性错误
我做错了什么,如何解决

lib.c
\uuuu declspec(dllexport)intadd(inta,intb);
整数相加(整数a,整数b){
返回a+b;
}
附录c
#包括
__declspec(dllimport)int add(int a,int b);
int main(){
printf(“%i\n”,添加(1,2));
返回0;
}
SConstruct
导入操作系统
env=DefaultEnvironment(TARGET\u ARCH='x86\u 64')
os.environ['PATH']=env['env']['PATH'].##表示“cl.exe”
lib=env.SharedLibrary(
target='lib',
source='lib.c')
环境预结束(LIBS=[lib])
环境规划(
目标='app',
source='app.c')

循环来自于获取
共享库的结果并将其添加到
LIBS
:调用返回的是一个节点列表-包含三个文件的节点表示形式
lib.dll
lib.lib
lib.exp
。您可以打印
lib
的值来查看这一点。

我已经添加了您的示例(已修改为您试图实现的功能)

请参见下面的说明中的注释。 注意

env=DefaultEnvironment() 
不是建议的用法。 请使用

env=Environment()
在我的机器上,新安装了MSVC 2019,SCons找到了编译器,默认情况下生成了X86_64二进制文件。(如果编译器支持“本机”arch,则SCON应默认为该arch,否则将尝试x86)

来自的msvc调试输出

set SCONS_MSCOMMON_DEBUG=%TEMP%\SCONS_MSVS_DEBUG.log
将有助于确定为什么您在SCON查找MSVC安装并正确配置它的本机功能方面遇到问题。 也请考虑加入我们的协助。 见:

SConstruct

# 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',])
附录c


为什么这个“os.environ['PATH']=env['env']['PATH']##表示“cl.exe”。。。不需要吗?请在上面的描述中添加您正在使用的msvc版本、python版本和SCON版本。我可以复制这个,但是发生了一些非常奇怪的事情。即使返回到
Library
而不是
SharedLibrary
,我也会在输出中看到一行意想不到的内容:
创建Library app.lib和object app.exp
。为什么会这样?@bdbaddog我正在使用VS2019和python 3.7。scons似乎找不到类似的
cl.exe
情况,如果您知道更好的方法,请告诉我,我使用的是scons v4.0.1版。如果没有这些,scons应该会找到它。请按照我的帖子从另一个问题,这样做,并附上结果。。设置SCONS\u MSCOMMON\u DEBUG=%TEMP%\SCONS\u MSVS\u DEBUG.log,该日志将输出有关SCONS如何尝试查找MSVC的信息,以便我们可以找出失败的原因。谢谢,但是如何链接SCONS中的库您可以将库的名称附加到
LIBS
env.Prepend(LIBS=“lib”)
。谢谢,它可以工作。而且
cl.exe
可用于SCON。那不是去年,所以我在我的环境中添加了
cl.exe
,并添加了
env.Append(env=os.environ)
。现在这是我代码中的一个bug,我删除了那一行,没有它的构建就成功了。啊。我打赌你一年前使用的版本不识别VS2019。此外,2019年的一些更新打破了scons msvc的检测。很高兴它起作用了!
# 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',])
#include<stdio.h>
__declspec(dllimport) int add(int a, int b);

int main() {
    printf("%i\n", add(1, 2));
    return 0;
}
__declspec(dllexport) int add(int a, int b);

int add(int a, int b) {
    return a + b;
}