我正在编写一个C++库(仅限标题),并使用CMake生成我的(Visual Studio)项目和解决方案文件.我也在编写一个测试套件,它是同一个CMake项目的一部分.
当我在代表我的仅头文件库的目标上调用target_include_directories()时,会出现问题,因此我的库的使用者可能会找到其头文件.我收到以下错误消息(即使生成没有中止).
CMake Error in CMakeLists.txt:
Target "Fonts" INTERFACE_INCLUDE_DIRECTORIES property contains path:
"D:/Projects/GPC/fonts/include"
which is prefixed in the source directory.
Run Code Online (Sandbox Code Playgroud)
(D:/ Projects/GPC/Fonts是我的库项目的顶级目录.如果我将头文件移动到顶层目录,问题仍然存在.)
我的CMakeLists.txt中的违规行是这个(为简单起见):
target_include_directories(Fonts INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
Run Code Online (Sandbox Code Playgroud)
我不明白我做错了什么.没有target_include_directories(),消费者项目的代码根本不能包含我的头文件(除非在已安装的形式,但我还没有达到这一点,并且无论如何我希望能够从其构建树中使用我的库,没有安装.)
我觉得我在这里缺少一些基本的东西; 但是我没有找到解决方案或解释就搜索了几个小时.
我有一个库需要携带从非源文件的内容(在这种情况下,OpenGL着色器代码)注入的一些常量数据.为了实现这一点,我正在使用add_custom_command()生成包含文件,然后我可以#include在我的代码中初始化const静态变量.
这与常规库(静态或共享)完美配合,但现在我想使我的库只有头.C++让静态方法返回静态数据而不会冒着在每个翻译单元中复制数据的风险("魔法静态")的能力使这成为可能.
然而问题是CMake似乎假设INTERFACE库(我用来创建仅头库的CMake功能)不需要构建 - 在这种情况下,这是错误的.
(我意识到我的库没有实际的义务是仅限标题.在这种特殊情况下,我想要的原因是我希望那个做OpenGL的库保持独立于任何特定的绑定库[比如GLEW或GLee或新手glbinding]通过保持我的图书馆仅标头,我可以离开这个选择用户-所有他需要做的是#include在绑定库的矿井前标题).
是否有人看到让CMake触发生成标题的自定义命令的方法,最迟在构建消费者项目时?
编辑:我刚刚意识到我可以拥有"两个世界中最好的",因为它保持我的库静态,但仍保留我的所有代码,除了头文件中的常量数据.这样,仍然不需要选择特定的OpenGL绑定库.但是,将库设置为仅限标题仍然有一些优点 - 使用简单 - 所以我将问题保持开放.
编辑#2:这是我的CMakeLists.txt文件的相关部分(我只删除了库依赖项 - 所有标题 - 从最后):
set(SHADER_FILES "src/vertex.glsl" "src/fragment.glsl")
add_library(libGPCGUIGLRenderer INTERFACE)
target_sources(libGPCGUIGLRenderer INTERFACE ${SHADER_FILES})
target_include_directories(libGPCGUIGLRenderer BEFORE
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# Embed shader files
source_group("Shader files" FILES ${SHADER_FILES})
set(GENERATED "${CMAKE_CURRENT_BINARY_DIR}/generated")
target_include_directories(libGPCGUIGLRenderer INTERFACE ${GENERATED})
# Find the GPC Bin2C utility
find_package(GPCBin2C REQUIRED)
# Add a custom target and a dependency for each shader file …Run Code Online (Sandbox Code Playgroud) 这将是一个自我回答的问题,因为它在整整一个星期的过程中让我疯狂,我希望让我的程序员免受我经历的挫折.
情况如下:您希望使用NVidia的NVEnc硬件编码器(分别在Kepler和Maxwell卡上提供,分别为GT(x)7xx和GT(x)9xx)来通过UDP流式传输图形应用程序的输出.这不是一条琐碎的道路,但它可以非常高效,因为它可以避免在编码阶段之前将帧从视频内存"下载"到系统内存,因为NVEnc能够直接访问视频内存.
我已经成功地完成了这项工作,只需要一帧又一帧地编写NVEnc的输出缓冲区来生成.h264 文件.VLC播放这样的文件没有问题,除了时间关闭(我没有尝试解决这个问题,因为我只需要该文件用于调试目的).
当我尝试通过UDP流式传输编码帧时出现问题:VLC和MPlayer都无法呈现视频.原来有两个原因,我将在答案中解释.
似乎CMake不支持定义导出或安装的目标的名称空间与相应库文件的名称之间的关系.
因此,例如,CMake可以轻松创建包含明确命名目标的包MyOrg::MyLibrary(例如使用和命令的NAMESPACE选项,但实际的.a,.lib,.so或.dll文件仍然可以全局分隔名称如:名称空间不进入库文件名.export(EXPORT ...)install(EXPORT ...)libMyLibrary.a
当然可以自己将命名空间应用于目标; 在上面的示例中,您可以命名目标MyOrgMyLibrary,从而导致库文件名,例如"libMyOrgMyLibrary.a".我认为这是好的,除了这使得该NAMESPACE选项基本上没用(或者你最终得到了命名的目标MyOrg::MyOrgMyLibrary),让我觉得我错过了什么.
有没有办法覆盖生成的库的名称?或者使用CMake确保库文件获得明确名称的"正确"方式是什么?
我正在尝试将cgmath库集成到我的第一个实验中glium,但我无法弄清楚如何将我的Matrix4对象传递给draw()调用.
我的uniforms目标是这样定义的:
let uniforms = uniform! {
matrix: cgmath::Matrix4::from_scale(0.1)
};
Run Code Online (Sandbox Code Playgroud)
这是我的draw电话:
target.draw(&vertex_buffer, &index_slice, &program, &uniforms, &Default::default())
.unwrap();
Run Code Online (Sandbox Code Playgroud)
无法使用该消息进行编译
error[E0277]: the trait bound `cgmath::Matrix4<{float}>: glium::uniforms::AsUniformValue` is not satisfied
Run Code Online (Sandbox Code Playgroud)
我是Rust的初学者,但我相信我自己也无法实现这个特性,因为它和它的Matrix4类型都与我的分开.
除了手动将矩阵转换为浮点数组数组之外,真的没有更好的选择吗?
在尝试使用NVEnc将OpenGL帧作为H264进行流式传输时,我碰到了一堵完整的砖墙.我已经在这个特殊问题上待了将近8个小时而没有任何进展.
问题是调用nvEncRegisterResource(),代码-23总是失败(枚举值NV_ENC_ERR_RESOURCE_REGISTER_FAILED,记录为"未能注册资源" - 感谢NVidia).
我正在尝试遵循奥斯陆大学本文档中概述的程序(第54页,"OpenGL互操作"),因此我知道这应该有用,但遗憾的是,该文档并未提供代码本身.
这个想法相当简单:
正如我所说,问题是第(3)步.以下是相关的代码片段(为简洁起见,我省略了错误处理.)
// Round up width and height
priv->encWidth = (_resolution.w + 31) & ~31, priv->encHeight = (_resolution.h + 31) & ~31;
// Allocate CUDA "pitched" memory to match the input texture (YUV, one byte per component)
cuErr = cudaMallocPitch(&priv->cudaMemPtr, &priv->cudaMemPitch, 3 * priv->encWidth, priv->encHeight);
Run Code Online (Sandbox Code Playgroud)
这应该分配设备上的CUDA内存("倾斜"类型,尽管我也尝试过非音调,但结果没有任何改变.)
// Register the CUDA buffer as an input resource
NV_ENC_REGISTER_RESOURCE regResParams = { 0 };
regResParams.version = NV_ENC_REGISTER_RESOURCE_VER;
regResParams.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR; …Run Code Online (Sandbox Code Playgroud) 我有以下情况:一个静态库MyStaticLib取决于 FFmpeg 项目(libavformat等)的几个库。
FFmpeg 库(不是由我)与“/SAFESEH:NO”选项链接,这意味着链接到它们的任何图像(通过它们的导入库)也必须与相同的选项链接(不这样做会使链接器因“LNK2026:模块对 SAFESEH 图像不安全”而中止)。
我已经尝试了所有我能想到的方法,但是我还没有找到一种方法可以将该选项附加到我的选项MyStaticLib中,从而使其传播给消费者。
这看起来很奇怪,因为 CMake 确实提供了将编译器选项传播给消费者的方法:target_compile_options()与该PUBLIC选项一起使用的命令正是这样做的。
链接器标志没有类似的功能吗?