- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试使用 Swift 包管理器在库中使用 ncurses,我想使用特定版本的 ncurses,而不是 OS X 中包含的版本。为此,我使用 Homebrew 安装了更新版本 (6.1)。这就是我的 Package.swift
的样子:
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "NcursesExample",
products: [
.executable(name: "NcursesExample", targets: ["NcursesExample"]),
],
dependencies: [
],
targets: [
.systemLibrary(name: "Cncurses"),
.target(name: "NcursesExample", dependencies: ["Cncurses"]),
]
)
在 Sources 目录下,我有一个 Cncurses 的子目录,其中包含一个 module.modulemap
和 shim.h
文件:
module.modulemap
module Cncurses {
header "shim.h"
link "ncurses"
export *
}
shim.h
#include "/usr/local/Cellar/ncurses/6.1/include/ncurses.h"
但是,在编译时我遇到了几个提示类型冲突的错误,显然是因为 macOS SDK 也提供了 ncurses:
shim.h:1:10: note: in file included from shim.h:1:
#include "/usr/local/Cellar/ncurses/6.1/include/ncurses.h"
^
/usr/local/Cellar/ncurses/6.1/include/ncurses.h:60:10: error: 'ncursesw/ncurses_dll.h' file not found with <angled> include; use "quotes" instead
#include <ncursesw/ncurses_dll.h>
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "shim.h"
^
shim.h:1:10: note: in file included from shim.h:1:
#include "/usr/local/Cellar/ncurses/6.1/include/ncurses.h"
^
/usr/local/Cellar/ncurses/6.1/include/ncurses.h:674:45: error: conflicting types for 'keyname'
extern NCURSES_EXPORT(NCURSES_CONST char *) keyname (int); /* implemented */
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/curses.h:598:45: note: previous declaration is here
extern NCURSES_EXPORT(NCURSES_CONST char *) keyname (int); /* implemented */
...
我正在尝试使用以下方法编译包:
swift build -Xcc -I/usr/local/Cellar/ncurses/6.1/include/-Xlinker -L/usr/local/Cellar/ncurses/6.1/lib
我也采用了在包定义中指定 pkgConfig
的方法,结果相同。有人可以帮忙吗?
仅供引用值得一提的是,在通过 Homebrew 安装 ncurses 时,我收到以下警告,因为 OS X 已经提供了 ncurses:
ncurses is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have ncurses first in your PATH run:
echo 'export PATH="/usr/local/opt/ncurses/bin:$PATH"' >> ~/.zshrc
For compilers to find ncurses you may need to set:
export LDFLAGS="-L/usr/local/opt/ncurses/lib"
export CPPFLAGS="-I/usr/local/opt/ncurses/include"
For pkg-config to find ncurses you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/ncurses/lib/pkgconfig"
ncurses 的 Pkgconfig 看起来像这样
# pkg-config file generated by gen-pkgconfig
# vile:makemode
prefix=/usr/local/Cellar/ncurses/6.1
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/ncursesw
abi_version=6
major_version=6
version=6.1.20180127
Name: ncursesw
Description: ncurses 6.1 library
Version: ${version}
URL: https://invisible-island.net/ncurses
Requires.private:
Libs: -L${libdir} -lncursesw
Libs.private:
Cflags: -D_DARWIN_C_SOURCE -I/usr/local/Cellar/ncurses/6.1/include -I${includedir}
最佳答案
问题
主要问题是头文件的冲突,因为 ncurses 也在/Applications/Xcode.app/.../MacOSX10.14.sdk/usr/include 中提供。
在这种情况下,一种常见的纯 C 解决方案是仅使用 -I 和 -L 指定自定义包含和 lib 目录,它会起作用,请在此处查看我关于 C ncurses 的回答:https://stackoverflow.com/a/56623033/2331445
这种方法似乎不适用于 Swift 包管理器。但这并不意味着不费吹灰之力就不可能。
可能的解决方案
我们需要确保忽略 macOS SDK 提供的 ncurses 头文件。我们可以通过为 swift build 命令指定 -Xcc -D__NCURSES_H 参数来做到这一点。
这是有效的,因为在头文件中,有这样的典型:
#ifndef __NCURSES_H
#define __NCURSES_H
...
#endif
当然,问题在于我们使用 Brew 自定义安装的 ncurses 也会受到影响。但我们可以解决它:
#include <ncursesw/unctrl.h>
使用的形式是“#include "ncursesw/unctrl.h"”这实际上可以通过以下命令行命令完成:
cd Sources/Cncurses
cp -r /usr/local/Cellar/ncurses/6.1/include include
find . -name '*.h' -exec sed -i '' 's/__NCURSES_H/__CNCURSES_H/g' {} \;
find . -name '*.h' -exec sed -i '' -E -e "s/<(.*(`find . -name '*.h' -exec basename {} \; | paste -sd "|" -`))>/\"\1\"/g" {} \;
最后的陈述可能需要一些解释。在 echo 命令的帮助下,您可以查看生成的 sed 表达式,即如果您执行
echo "s/<(.*(`find . -name '*.h' -exec basename {} \; | paste -sd "|" -`))>/\"\1\"/g"
你得到以下输出:
s/<(.*(termcap.h|form.h|term.h|panel.h|ncurses.h|termcap.h|cursesp.h|cursesf.h|etip.h|form.h|cursesw.h|nc_tparm.h|unctrl.h|cursesapp.h|term.h|cursslk.h|panel.h|ncurses.h|tic.h|eti.h|ncurses_dll.h|term_entry.h|menu.h|cursesm.h|curses.h|curses.h|cncurses.h))>/"\1"/g
如您所见,它仅搜索和替换本地可用的包含文件。
测试
为了进行测试,我们需要一个简单的 ncurses 示例程序。它应该被构建,我们应该确保使用正确版本的库。
module.modulemap
我的头文件叫做 cncurses.h。 module.modulemap 看起来像这样:
module cncurses [system]
{
umbrella header "cncurses.h"
link "ncurses"
export *
}
cncurses.h
cncurses.h 是单行代码,它从本地包含文件夹导入我们复制和定制的 ncurses.h 文件:
#include "include/ncurses.h"
main.swift
在 NcursesExample 文件夹中,我们有 main.swift,我们有一个简单的 cncurses swift 应用程序:
import cncurses
initscr()
curs_set(0)
move(5, 10)
addstr("NCURSES")
move(10, 10)
addstr("Hello World!")
refresh()
select(0, nil, nil, nil, nil)
Package.swift
请注意此处的 pkgConfig: "ncurses"
在系统库目标中:
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "NcursesExample",
dependencies: [
],
targets: [
.systemLibrary(name: "cncurses", pkgConfig: "ncurses"),
.target(name: "NcursesExample", dependencies: ["cncurses"]),
.testTarget(
name: "NcursesExampleTests",
dependencies: ["NcursesExample"]),
]
)
构建
要使 pkg-config 正常工作,我们必须首先调用以下命令:
export PKG_CONFIG_PATH="/usr/local/opt/ncurses/lib/pkgconfig"
最后我们开始构建:
swift build -Xcc -D__NCURSES_H
所以首先我们应该测试是否使用了正确的 ncurses 库。我们可以这样做:
otool -L .build/x86_64-apple-macosx/debug/NcursesExample
除其他行外,输出包含以下内容:
/usr/local/opt/ncurses/lib/libncursesw.6.dylib (compatibility version 6.0.0, current version 6.0.0)
看起来很有希望。
最后调用二进制文件:
Xcode 项目
如果你想生成一个Xcode工程,使用下面的命令:
swift package generate-xcodeproj
然后在Xcode中加载项目
关于Swift 包管理器无法编译通过 Homebrew 安装的 ncurses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56251835/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!