我正在使用 Microsoft Visual Studio 2013 Express for Windows Desktop,用 C++ 编写并使用 SDL 2.0.3 库。我正在尝试构建一个独立的.exe,它可以在其他计算机上运行而无需安装任何东西。
我已经按照TwinklebearDev 第 0 课:设置 SDL设置了我的项目。我链接到该库的 x86 版本,并将 x86 版本的 SDL2.dll 放置在 Debug 文件夹和 Release 文件夹中。这是源代码:
#include <iostream>
#include <SDL.h>
int main(int argc, char **argv){
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Quit();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这工作完美并返回 0,直到我尝试静态链接。我尝试通过右键单击项目并单击属性,然后设置以下内容来静态链接:
配置属性 > C/C++ > 代码生成 > 运行时库 > 多线程 (/MT)
然后我收到一堆错误:
警告 1 警告 LNK4098:defaultlib 'msvcrt.lib' 与其他库的使用冲突;使用 /NODEFAULTLIB:库 …
今天我在面试时被问到这个问题。不幸的是,我不确定我是否在这里正确地复制了它。我只记得,我不太理解它。问题可能是
“加载静态和动态编译的 dll 会导致什么问题?”
我不知道答案,但面试官告诉我,至少有两个主要问题:
运行时库:可能存在一些不兼容的内存分配和解除分配。
不幸的是,我们在这里被打断了,我们没有回到这个问题。
请您帮我理解这个问题可能是什么,以及答案是什么?
我对第一点也不太理解。malloc我以为一个程序中只能有一个,我错了吗?
我的目录中有一些自定义源文件,src以及我目录中Arduino项目的一些源文件src/base.
我obj使用以下make规则将所有源文件编译为存储在我的目录中的对象:
PATHOBJ := obj/
PATHSRC := src/
PATHBIN := bin/
PATHLIB := lib/
PATHTMP := tmp/
PATHARDUINO = $(PATHSRC)base/
enter code here
$(PATHOBJ)core_%.o : $(PATHARDUINO)%.c
@mkdir -p $(dir $@)
$(GCC) $(ALL_CORE_CFLAGS) -c $< -o $@
$(PATHOBJ)bot_%.o : $(PATHSRC)%.c
@mkdir -p $(dir $@)
$(GCC) $(CFLAGS)-c $< -o $@
Run Code Online (Sandbox Code Playgroud)
正如你可以看到它会编译src/tacho.c到obj/bot_tacho.o和src/base/wiring_analog.c到obj/core_wiring_analog.o.
在我的makefile中,我编译所有源文件没有任何问题.在其中一个文件(即src/tacho.c)中我添加了以下include:
#include "base/wiring.h"其中包含原型analogRead.
有趣的是,wiring.h只包含'analogRead'功能的原型.它甚至都没有包含实际定义函数的文件,但是一些注意事项使我发现函数的定义可以在其中找到src/base/wiring_analog.c.
我认为编译声明该函数的文件并将其与所有其他必要的Arduino目标文件链接到一个库就足够了.我随意选择了它的名字lib/core.a.我lib/core.a …
我正在尝试创建一个与静态版本的librt链接的共享库.目前我这样做:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
ADD_LIBRARY(memtrace SHARED memtrace.c)
ADD_LIBRARY(lib_real_time STATIC IMPORTED)
SET_TARGET_PROPERTIES(lib_real_time PROPERTIES IMPORTED_LOCATION /usr/lib/x86_64-linux-gnu/librt.a)
TARGET_LINK_LIBRARIES(memtrace lib_real_time)
Run Code Online (Sandbox Code Playgroud)
但我不想指定这样的路径.由于librt总是在标准路径中,我宁愿让cmake找到它.就像在gcc中一样,我只会指定-lrt.当我尝试使用此cmake文件执行此操作时:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
ADD_LIBRARY(memtrace SHARED memtrace.c)
TARGET_LINK_LIBRARIES(memtrace rt)
Run Code Online (Sandbox Code Playgroud)
它将memtrace链接到librt的动态版本,这不是我想要的!
如何在不提及完整路径的情况下链接librt的静态版本?
我正在尝试使用Xcode在Objective C和C++中为iOS编写一个简单的游戏引擎.
我做了一个游戏项目和一个游戏引擎项目.后者作为子项目添加到前者中.该引擎还作为目标依赖项添加,并作为二进制文件添加到游戏项目中.
我的引擎使用CADisplayLink所以我添加QuartzCore.framework了引擎项目的"链接二进制文件库列表"(在构建阶段中找到).
现在,当我尝试构建我的游戏项目(带有子项目的项目)时,我收到此错误:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_CADisplayLink", referenced from: objc-class-ref in libVoya-iOS.a
此错误仅在从游戏项目构建时发生 - 从引擎项目中执行此操作正常.如果我添加QuartzCore.framework到游戏项目建设工作正常.
它真的是真的我必须特别要求我的目标依赖项之一已经需要的框架吗?在这种情况下:我的引擎(子项目)已经链接了QuartzCore - 是否真的有必要在使用此引擎的项目中执行此操作?感觉就像无缘无故的双重工作.
或许我只是完全误解了什么?:)
我正在编写一个Go程序,它使用GNU readline库来创建一个花哨的命令行界面.为了简化安装过程而不用担心库版本和其他东西,我想静态链接它.
问题是我真的不知道该怎么做.如果我预编译库,我将不得不提供我的代码的几个版本,以及.a或.lib readline库的不同版本.为了避免这个问题,我考虑将当前的readline代码包含到我的go项目中,并让go工具在构建go项目时编译它.但是,要构建readline库,必须使用make.有没有办法告诉go工具如何构建C代码?
在Embarcadero RAD Studio XE3中链接C++项目(关闭使用运行时包)时,我有时会收到表单错误:
[ilink32 Error] Fatal: Unable to open file 'FOO.OBJ'
我明白是什么原因造成的.这是因为代码中有一个隐式引用(通常是通过a #pragma link)导致链接器需要该单元FOO.
如果我查看VCL源代码,我通常可以找到一个FOO.PAS编译成一个FOO.DCU.这是链接器正在寻找但无法找到的已编译单元.
我知道这个编译过的单元存在于一个VCL库中,但我不知道如何找出哪一个.例如,VCL.LIB和RTL.LIB和BCBIE.LIB(等等)包含哪些单位?
给定一个单元名称,我想知道哪个VCL库包含它.如果我知道,我可以将相应的.lib文件添加到LinkPackageStatics我的cbproj文件中的标记中,所有内容都可以正常链接.
如果只是在该单元的文档中显示它会很好,但它不存在.目前,我必须使用试验和错误来找到合适的库,但肯定有一个公开可用的列表,显示哪些VCL单元链接到哪些VCL库.
我在哪里可以找到这样的列表?
(顺便说一句,我知道在IDE的正常使用中,开发人员不需要知道这一点.IDE通常会为您解决这个问题.但是我发现当.cbproj合并错误时我偶尔会需要这些信息或者手动编辑不正确或出于超出IDE正常使用范围的其他一些原因.)
编辑:谢谢!tlib正是我所需要的.我在shell脚本上很糟糕,但我写了一个小shell脚本,它输出了它所包含的每个单元名称旁边的库名:
#!/bin/bash
while [ "$1" != "" ]; do
name=$(basename "$1")
tlib /L $name | grep size | awk -v name=$name '{print name, "\t", $1}'
shift
done
Run Code Online (Sandbox Code Playgroud)
然后我可以通过在我感兴趣的所有.libs上执行它来调用脚本,然后为我正在寻找的单元(如SysUtils)进行grepping:
find . -name "*.lib" -exec libunits.sh {} \; | grep SysUtils
Run Code Online (Sandbox Code Playgroud) 尝试构建运行http服务器的go程序的静态链接版本,并使用net包来确定和解析传入请求的IP地址.使用此构建语句:
CGO_ENABLED=0 go install -a -ldflags '-s' .
Run Code Online (Sandbox Code Playgroud)
这个序言在我的程序中:
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"net"
"net/http"
"path/filepath"
"strings"
"golang.org/x/blog/content/context/userip"
"github.com/oschwald/maxminddb-golang"
)
Run Code Online (Sandbox Code Playgroud)
这与build 1.3一起工作,生成一个静态链接的程序,但是没有使用go 1.4.2.构建成功,但程序没有静态链接.
有谁知道发生了什么?
我正在创建一个C++共享库,它链接到一些Boost库(本地机器上的Boost版本1.55).
我可以在我的机器上使用我的库,但由于未定义的引用,我无法在具有不同版本的Boost的另一个系统上使用它(假设为1.54).
我在使用CMake,这里是CMakeLists.txt文件:
cmake_minimum_required(VERSION 2.8)
project(my_library)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
FILE(GLOB_RECURSE INCLUDE_FILES "include/*.hpp")
FILE(GLOB_RECURSE SOURCE_FILES "src/*.cpp")
add_library(${PROJECT_NAME} SHARED ${INCLUDE_FILES} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} -pthread -lboost_filesystem -lboost_regex -lboost_system)
Run Code Online (Sandbox Code Playgroud)
我是图书馆创作的新手,我在这个问题上挣扎了好几天.我想知道我是否必须使用Boost创建一个静态库.但我希望我的图书馆尽可能小.
编辑:当我检查我的lib依赖项时,我得到了Boost正则表达式:
libboost_regex.so.1.55.0 => /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0 (0x00007fe228a27000)
是否可以更新此链接以针对特定版本的Boost进行链接?
我的可执行文件与许多静态库链接,在Linux上通常有50至100个存档。有时,这些档案中存在依赖性周期。这些库在链接命令行上出现的顺序很重要,请参见此处。尝试手动订购许多库至少要耗费大量时间,尤其是在存在循环的情况下。
问题:是否有实用程序或技术可以分析代码库并产生正确的链接命令行顺序?