使用cmake构建可执行文件和共享库,runtimelinker没有找到dll [英] Building of executable and shared library with cmake, runtimelinker does not find dll

查看:1876
本文介绍了使用cmake构建可执行文件和共享库,runtimelinker没有找到dll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用gcc(cygwin),gnu make,windows 7和cmake。



我的cmake testprojekt具有以下结构

  rootdir 
| - App
| | - app.cpp
| + - CMakeLists.txt
| - Lib
| | - lib.cpp
| | - CMakeLists.txt
| - MakeFileProject
+ CMakeLists.txt

rootdir / App / app.cpp:

 #include< string& 
void printThemMessageToScreen(std :: string input); // prototype
int main(int argc,char ** argv){
printThemMessageToScreen(this will be displayed by lib);
return 0;
}

rootdir / Lib / lib.cpp:

 #include< iostream> 
#include< string>

void printThemMessageToScreen(std :: string input){
std :: cout<<
}

rootdir / CMakeLists.txt:



cmake_minimum_required(VERSION 2.6)
project(TestProject)

add_subdirectory(App)
add_subdirectory(Lib)

rootdir / Lib / CMakeLists.txt:

  add_library(Lib SHARED lib.cpp)

rootdir / App / CMakeLists .txt:

 #确保编译器可以从我们的Lib库中找到包含文件。 
include_directories($ {LIB_SOURCE_DIR} / Lib)

#确保链接器在构建之后可以找到Lib库。
link_directories($ {LIB_BINARY_DIR} / Lib)

#添加从源文件构建的可执行程序TestProjectExecutable
add_executable(TestProjectExecutable app.cpp)

#将可执行文件链接到lib库。
target_link_libraries(TestProjectExecutable Lib)



现在,当我运行cmake和make时,生成&构建没有错误,但当我尝试执行二进制,它将失败,因为生成的库无法找到。



但是,当我将lib dll复制到相同的目录,像应用程序exe,它会被执行!



也:如果我将库配置为静态,它也将执行。



如何告诉运行时连接器在哪里查找我的dll?

UPDATE:



根据用户Vorren提出的方法的解决方案:



我打开了注册表编辑器,并导航到以下项:

  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows \CurrentVersion \App路径

,这里我创建了一个名为my Applikation :



在这种情况下:(TestProjectExecutable.exe



TestProjectExecutable.exe的完整路径,包括文件名和扩展名。然后我创建了另一个字符串值称为路径,并将值设置到dll所在的文件夹:



解决方案

编译器,但使用Windows搜索DLL的方式。



操作系统将使用以下算法来定位所需的DLL:



查找:


  1. 应用程序专用路径注册表项中列出的目录;

  2. 当前进程的可执行模块所在的目录;

  3. 当前目录;

  4. Windows系统目录;

  5. Windows目录;

  6. PATH环境变量中列出的目录;

因此,如果你不想将操作系统目录与你的应用程序特定的dll杂乱,你有两个合理的选择:


  1. 创建应用专用的路径注册表项(我会使用此选项);

  2. 将DLL放在与EXE相同的文件夹中;

  3. 修改PATH变量(但为什么要这样做,如果您可以使用选项1?);


I am working with gcc(cygwin), gnu make, windows 7 and cmake.

my cmake testprojekt has the following structure

rootdir
|-- App
|   |-- app.cpp
|   +-- CMakeLists.txt
|-- Lib
|   |-- lib.cpp
|   |-- CMakeLists.txt
|-- MakeFileProject
+ CMakeLists.txt

rootdir/App/app.cpp:

#include<string>
void printThemMessageToScreen(std::string input);//prototype
int main(int argc,char **argv){
 printThemMessageToScreen("this will be displayed by our lib");
 return 0;
}

rootdir/Lib/lib.cpp:

#include<iostream>
#include<string>

void printThemMessageToScreen(std::string input){
 std::cout<<input;
}

rootdir/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)
project(TestProject)

add_subdirectory(App)
add_subdirectory(Lib)

rootdir/Lib/CMakeLists.txt:

add_library(Lib SHARED lib.cpp)

rootdir/App/CMakeLists.txt:

# Make sure the compiler can find include files from our Lib library. 
include_directories (${LIB_SOURCE_DIR}/Lib) 

# Make sure the linker can find the Lib library once it is built. 
link_directories (${LIB_BINARY_DIR}/Lib) 

# Add executable called "TestProjectExecutable" that is built from the source files 
add_executable (TestProjectExecutable app.cpp) 

# Link the executable to the lib library. 
target_link_libraries (TestProjectExecutable Lib) 

Now, when i run cmake and make, everything will get generated & built with no errors, but when i try to execute the binary, it will fail because the library which was generated could not be found.

BUT: when i copy the lib dll into the same directory like the app exe, it will get executed!

also: if i configure the library to be static, it will also execute.

how to tell the runtime linker where to look for my dll?

UPDATE:

Solution according to the Method proposed by User Vorren:

I opened up the registry editor, and navigated to the following Key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

, here i created a new key with the name of my Applikation:

in this case : TestProjectExecutable.exe

after that, the (default) value was set to the full path of TestProjectExecutable.exe including the filename and extension. Then i created another String Value called "Path" and set the value to the folder where the dll was located:

解决方案

Your problem lies not with linker or compiler, but with the way Windows searches for DLL's.

The OS will use the following algorithm to locate the required DLL's:

Look in:

  1. The directories listed in the Application-specific Path registry key;
  2. The directory where the executable module for the current process is located;
  3. The current directory;
  4. The Windows system directory;
  5. The Windows directory;
  6. The directories listed in the PATH environment variable;

Thus you have two reasonable options if you don't want to clutter the OS directories with your app-specific dll:

  1. Create an app-specific Path registry entry (I would go with this option);
  2. Put your DLL in the same folder as your EXE;
  3. Modify the PATH variable (but why would you do that, if you can go with option 1?);

这篇关于使用cmake构建可执行文件和共享库,runtimelinker没有找到dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆