我正在使用Visual Studio 2008 SP1(专业版,适用于32位和64位版本).我正在寻找一种解决方法,我认为这是Visual Studio中一个非常无益的" 限制 ".
我觉得很奇怪,在Visual Studio连接器和编译器不以DLL文件的创建时间这一权利,自动扫描所有导出的符号所有指定的静态库中所示的相同的方式构建一个导入库和导出文件,并在一StackOverflow评论.我确认仅仅在组成静态库的文件中应用__declspec(dllexport)和__declspec(dllimport)属性类,函数和数据声明是不够的
.
链接器不扫描导出符号的所有静态库,因此不会将它们拉入DLL文件(符号必须由.objDLL链接命令行上的文件或我在下面显示的其他方式引用).如果没有对每个导出符号的显式引用,仍可能会创建DLL文件,但不会创建其关联的导入库文件.
根据我的收集,Microsoft建议使用LIB.EXE 来创建DEF文件,但不幸的是,LIB.EXE页面应用了一个约束:
请注意,如果您在创建导入库之前创建导入库,则在构建导入库时,必须在构建导入库时
.dll传递相同的目标文件集.dll.
鉴于我在新的构建环境中也使用了CMake,这是一个不幸的约束.CMake隐藏了实际传递给链接器的细节(我认为这在99%的时间里都是好事),但在这种情况下我需要在CMake执行时访问一些信息,而不是然后使用手工制作的脚本或其他脆弱的skulduggery.
如何强制DLL链接器解析构成DLL文件的所有静态库中的所有导出符号,这不会导致脆弱性和额外的构建逻辑维护工作?在这里考虑全自动化,并记住我需要多次为多个不同的DLL执行此操作.
我的问题是:
如何仅使用CMake语法获取最终DLL链接命令行上使用的目标文件和静态库集?
有没有更好的方法来解决这个问题,在调用最终链接之前不需要调用单独的实用程序,例如LIB.EXE ?我担心LIB.EXE链接本身之外的额外构建开销会再次重新扫描所有静态库 ,即使它只是在单独的执行中写出来.
以下是我现在无法考虑的解决方案:
在原始文件.h或.cpp文件之外的任何地方手动指定未引用的符号,因为每次开发人员忘记更新列出(很可能是名称错位的)符号名称的文件时,这样做会中断.并且它将打破关于未解析符号的非用户友好链接器错误,这对于开发人员来说将是昂贵的调试.这个非答案包括以下方法:
明确地将.obj文件添加到DLL链接命令行中(其中的变体包括添加"假" .obj文件,这些文件具有对未引用但导出的符号的虚拟引用(并注意这是我的旧构建环境今天所做的,并且它很臭) ),和,
手工制作DEF文件以包含未引用但导出的符号,以及 …
我试图在IDE和命令行中在Visual Studio 2008 Express Edition Service Pack 1(之后安装了一些相关的Windows SDK)下构建64位本机C++应用程序.这是在Windows XP Professional x64 Edition版本2003 Service Pack 2计算机上.
我知道专业版可能提供真正的VS IDE集成,但我特别希望在Visual Studio 2008 Express Edition中实现这一点.
但是,我在Visual Studio 2008 Express IDE的项目配置中遇到了一些麻烦,我希望有人可以回答可能出现的问题.关键目标是能够从IDE本身以及命令行中通过执行vcvarsall.bat类似批处理文件或类似批处理文件来构建64位本机应用程序.
这是我到目前为止尝试的内容:
我安装了带有SP1的Visual Studio 2008 Express Editions,它安装了某种类型的SDK,但我认为不是包含64位编译器的正确版本(但当时并不知道它).
我构建了一个hello world Win32 Console应用程序,并查看为可执行文件生成的清单文件.我在清单文件中找到了"x86",这不是64位AFAICT,所以我做了更多研究.
我发现Visual Studio 2008 Express Edition中有什么"缺失"?.我看到了一些回复,其中一个回复中有一个缺少功能的列表,其中包含"64位Visual C++工具"作为缺少的功能之一.
但是,在维基百科条目中,我们看到:
可以将64位编译器真正集成到Visual C++ 2008 Express Edition中,但仍然很麻烦.9
所以,我尝试了上面给出的9个链接中的指令.该链接实际上是指如何:将Visual C++项目配置为目标64位平台.我浏览了该页面上的各个步骤,但他们指示您执行以下操作:
单击"类型"或选择新平台下拉箭头,然后选择64位平台.
但下拉列表中没有条目.
我再次提到维基百科上的SDK页面,特别是64位开发部分,其中指出:
最近发布的适用于Windows Server 2008和.NET …
理由:在我的日常C++代码开发中,我经常需要回答一些基本问题,例如谁在一个经常变化的非常大的C++代码库中调用了什么.但是,我还需要有一些自动方法来准确识别代码在特定代码区域内所做的工作.诸如Cscope之类的"grep"工具很有用(我已经大量使用它们),但不是C++ - 语言感知:它们没有任何方法来识别给定类型的词汇环境的类型和种类或者以一种有利于自动化的方式运行(即使所述自动化仅限于"只读"操作,例如代码浏览和导航,但我要求的不仅仅是下面的内容).
问题:是否已存在基于C/C++的开源库(本机,非托管,非Microsoft或Linux特定),可以静态扫描或分析大型C++代码树,并且可以生成可回答的结果集详细问题如:
结果集应该提供某种"句柄".我应该能够将该句柄反馈给库以执行以下类型的内省:
答案应符合以下要求:
与使用cmake将目标文件链接到lib.xxxx.a文件相关,但不完全相同,我使用CMake 2.8.x使用VS2008 SP1在Windows上构建了几个静态库.有没有办法通过CMake单独将所有现有静态库中的所有.obj文件重新链接到一个更大的单片库中,最好是通过add_libraryCMake函数或其他类似的构造?
我认为答案是"不",因此我考虑通过常规add_custom_command+ add_custom_target方法通过自定义命令滚动自己,通过在调用时提供所有其他库.obj文件,只需手动构建库LINK.EXE.但我发现这种方法存在一些问题:
LINK.EXE可执行文件的完全限定路径.然后,我必须以某种方式推导出LINK.EXE使用脆弱启发式的路径:在不同的Visual Studio版本可能将LINK.EXE文件定位在不同目录中的意义上它是脆弱的,我需要这个工作用于32位和64位位Windows编译器条件,并且能够抵御VS2008与未来编译器修订版之间的升级.LINK.EXE,以便将它们添加到命令行,因此FILE(GLOB...)在这种情况下,构造将是我最好的第二种选择.LINK.EXE通过:来调用LINK.EXE /OUT:monolithic.lib lib1.lib lib2.lib ...,但也许并不是所有的.obj都会被包括在内(编辑:我已经确认LINK.EXE省略了一些.obj文件lib1.lib lib2.lib ...而没有任何诊断消息解释原因,所以这种方法是非首发的); 关于LINK.EXE这一点,在线文档尚不清楚.有没有LINK.EXE以这种方式使用的经验?谢谢,
黑雁
PS,我知道如何使用CMake创建DLL,但我特别不想在此时构建DLL.
如何列出 conda 可用的软件包版本有一些有用的答案,其中之一在/sf/answers/3345709041/使用两个等号。 conda search -h没有完全说明 MatchSpec 语法允许的内容,只给出了一些简单的例子。
例如,我想查看最新版本的python 下存在哪些包,对于一个名为jedi. 我不得不求助于实验和猜测来找到正确的语法,因为上面缺少 MatchSpec 语法的详细文档。我结束了:
$ condaw search 'jedi[build=py37*]' --json | grep '"build"'
"build": "py37_1",
"build": "py37_0",
"build": "py37_0",
"build": "py37_0",
"build": "py37_0",
$
Run Code Online (Sandbox Code Playgroud)
使用上面的--json选项只是为了让我可以找出哪些关键字(例如)build可能是语法的一部分。
那么,MatchSpec 语法在哪里有正式和完整的文档,这样我就不必猜测了?我现在得出的结论是-h输出是唯一的。
将其添加到emacs .org文件中:
#+BEGIN_SRC sh :results verbatim
#!/bin/bash
exec 2>&1 # <-- Because Emacs treats stderr output as an error and doesn't show it in the RESULT
echo before
# This nohup should just run in the background and continue to exit
# the script, but emacs hangs and waits on it anyhow:
nohup sleep 10 &
# Failed attempts at working around the hang are:
# setsid nohup sleep 10 &
# nohup sleep 10 </dev/null &
# Do see …Run Code Online (Sandbox Code Playgroud) 我有一个Bash脚本,它在前台运行一个长时间运行的进程.当它收到SIGQUIT信号时,它应该执行各种清理操作,例如查杀自身及其所有子进程(通过杀死进程组等).应该捕获信号的最小脚本如下所示(称为test_trap.sh):
#!/bin/bash
trap 'echo "TRAP CAUGHT"; exit 1' QUIT # other required signals are omitted for brevity
echo starting sleep
sleep 11666
echo ending sleep
echo done
Run Code Online (Sandbox Code Playgroud)
我想将SIGHUP信号发送到test_trap.sh脚本的进程.但是,向该SIGHUP发送test_trap.sh不会触发陷阱表达式,但只有当我将信号发送到子sleep 11666进程时才会触发陷阱.下面是一个bash会话,展示了这一点:
bash-4.1$ test_trap.sh &
[1] 19633
bash-4.1$ starting sleep
bash-4.1$ kill -s SIGQUIT 19633
bash-4.1$ jobs
[1]+ Running test_trap.sh &
bash-4.1$ ps -ef --forest --cols=10000 | grep '11666\|test_trap.sh' | grep -v grep
theuser 19633 12227 0 07:40 pts/4 00:00:00 \_ /bin/bash ./test_trap.sh
theuser 19634 …Run Code Online (Sandbox Code Playgroud) 假设我们有以下代码:
#if !defined(__cplusplus)
# error This file should be compiled as C++
#endif
#include <stdio.h>
#include <string>
//#define USE_CXX_CLASS
#ifdef USE_CXX_CLASS
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}
std::string GetSomeString()
{
// case #1
}
};
#endif // USE_CXX_CLASS
int foo()
{
// case #2
}
int
main (int argc, char *argv[])
{
(void)argc;
(void)argv;
#ifdef USE_CXX_CLASS
SomeClass someInstance;
someInstance.GetSomeString();
#endif // USE_CXX_CLASS
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并且假设它是使用选项从GCC版本4.2.1编译C++编译器(而不是C编译器)-Wreturn-type -Werror=return-type.如果上面的代码是按原样编译而没有先取消//#define USE_CXX_CLASS上面的行,那么你会看到一个警告但没有错误:
.../gcc-4.2.1/bin/g++ -g -fPIC …Run Code Online (Sandbox Code Playgroud) 下面,result1和result2变量值报告不同的值,具体取决于您是使用-g还是使用-O在GCC 4.2.1和GCC 3.2.0上编译代码(我还没有尝试过更新的GCC版本) :
double double_identity(double in_double)
{
return in_double;
}
...
double result1 = ceil(log(32.0) / log(2.0));
std::cout << __FILE__ << ":" << __LINE__ << ":" << "result1==" << result1 << std::endl;
double result2 = ceil(double_identity(log(32.0) / log(2.0)));
std::cout << __FILE__ << ":" << __LINE__ << ":" << "result2==" << result2 << std::endl;
Run Code Online (Sandbox Code Playgroud)
result1和result2 == 5仅在使用-g进行编译时,但如果使用-OI进行编译,则得到result1 == 6和result2 == 5.
这似乎与编译器完成优化的方式不同,或者内部与IEEE浮点表示有关,但我很好奇这种差异究竟是如何发生的.我希望尽可能避免看汇编程序.
以上是用C++编译的,但我认为如果使用printfs将其转换为ANSI-C代码,则会保持相同.
上述差异发生在32位Linux上,但不适用于64位Linux.
谢谢bg
为什么 Rust 编程语言的设计者要求宏名称必须以感叹号结尾?
请注意,我并不是说这种设计选择是错误的。我只是好奇。
使用 Python 3.5.x,没有比这更高的版本。
/sf/answers/2117818601/是正确的答案,但没有提供内置于 Python 的解决方案,而是需要从头开始编写代码:
我需要一个值为“-”的字符串来表示标准输入,或者它的值是我想要读取的文本文件的路径。我想使用with运算符打开这些文件中的任何一种,而不使用条件逻辑来检查脚本中的“-”。我有一些有用的东西,但它似乎应该是内置在 Python 核心中的东西,而不需要我推出自己的上下文管理器,如下所示:
from contextlib import contextmanager
@contextmanager
def read_text_file_or_stdin(path):
"""Return a file object from stdin if path is '-', else read from path as a text file."""
if path == '-':
with open(0) as f:
yield f
else:
with open(path, 'r') as f:
yield f
# path = '-' # Means read from stdin
path = '/tmp/paths' # Means read from a text file given by this value
with read_text_file_or_stdin(path) …Run Code Online (Sandbox Code Playgroud)