使用cmake构build可执行文件和共享库,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.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.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 /应用/的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) 

现在,当我运行cmake并make,一切都会得到生成和没有错误,但是当我尝试执行二进制文件,它将失败,因为生成的库无法find。

但是:当我复制lib DLL到像应用程序的exe文件相同的目录,它会得到执行!

另外:如果我configuration库是静态的,它也会执行。

如何告诉运行时链接程序在哪里寻找我的DLL?

更新:

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

我打开了registry编辑器,然后导航到以下registry项:

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

,在这里我创build了一个新的密钥,名称为我的Applikation:

在这种情况下:TestProjectExecutable.exe

之后,将(默认)值设置为TestProjectExecutable.exe的完整path,包括文件名和扩展名。 然后,我创build了另一个名为“path”的string值,并将该值设置为该dll所在的文件夹:

在这里输入图像说明

你的问题不在于链接器或编译器,而在于Windows搜索DLL的方式。

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

在看:

  1. “特定于应用程序的路径”注册表项中列出的目录;
  2. 当前进程的可执行模块所在的目录;
  3. 当前目录;
  4. Windows系统目录;
  5. Windows目录;
  6. PATH环境变量中列出的目录;

因此,如果您不想使用特定于应用程序的dll混淆OS目录,那么您有两个合理的选项:

  1. 创建一个应用程序特定的路径注册表项(我会去这个选项) ;
  2. 把你的DLL放在你的EXE所在的文件夹中;
  3. 修改PATH变量(但为什么要这样做,如果你可以选择1的话)?

我更喜欢的解决方案是没有提到的,就是将你的shared-libs和你的可执行文件放在同一个目录下。 这往往是一个更简单的解决方案。

用cmake做到这一点的一个方法是

设置(CMAKE_RUNTIME_OUTPUT_DIRECTORY $ {CMAKE_BINARY_DIR} / bin)

或者你也可以根据构建风格设置输出目录。

看看我如何使cmake输出到“bin”目录?

我从接受的答案(通过pdeschain)尝试了选项1。 我甚至创建了一个cmake挂钩来自动注册链接库的路径

 function (xtarget_link_libraries target libs) # same as target_link_libraries but with additional improvements to allow windows find the library at runtime LIST(REMOVE_AT ARGV 0) SET(LIBS ${ARGV}) # this is to pass list into this function target_link_libraries(${target} ${LIBS}) # call standard routine if(WIN32) set(TFILE ".") get_property(slibs TARGET ${target} PROPERTY all_libs) # recall libs linked before set(LIBS ${slibs};${LIBS}) set_property(TARGET ${target} PROPERTY all_libs ${LIBS}) # save all libs FOREACH(lib ${LIBS}) # compose a list of paths set(TFILE "${TFILE};$<TARGET_LINKER_FILE_DIR:${lib}>") ENDFOREACH() #add reg key add_custom_command(TARGET ${target} POST_BUILD COMMAND reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${target}.exe" /v "Path" /d "${TFILE}" /f ) endif() endfunction() 

可以用作xtarget_link_libraries(test lib1 lib2) 。 应用程序将能够找到绝对路径上的动态库。

但是,这是一个很大的问题, App Paths机制https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx#appPaths

不允许为“Debug / test.exe”和“Release / test.exe”设置不同的条目。 所以对我来说这是一个糟糕的选择。

您可以添加以下行来填充Default键作为该文章中建议的程序的路径。

add_custom_command(TARGET ${target} POST_BUILD COMMAND reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${target}.exe" /ve /d "$<TARGET_FILE:${target}>" /f )

现在你可以享受从系统中的任何地方运行test.exe …我想我的下一个尝试将是选择

  1. 使用cmake创建符号链接到dll。