我正在使用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 / 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并制作时,所有内容都会生成&amp;没有错误地构建,但是当我尝试执行二进制文件时,它将失败,因为找不到生成的库。
但是:当我将lib dll复制到app app这样的目录中时,它会被执行!
另外:如果我将库配置为静态,它也将执行。
如何告诉运行时链接器在哪里查找我的dll?
根据User Vorren提出的方法解决方案:
我打开了注册表编辑器,导航到以下密钥:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
,在这里我创建了一个名为my Applikation的新密钥:
在这种情况下:TestProjectExecutable.exe
之后,(默认)值设置为TestProjectExecutable.exe的完整路径,包括文件名和扩展名。然后我创建了另一个名为&#34; Path&#34;的字符串值。并将值设置为dll所在的文件夹:
答案 0 :(得分:9)
您的问题不在于链接器或编译器,而在于Windows搜索DLL的方式。
操作系统将使用以下算法来查找所需的DLL:
查看:
因此,如果您不想使用特定于应用的dll来混淆操作系统目录,那么您有两个合理的选择:
答案 1 :(得分:9)
我更喜欢没有提到真正的解决方案是将您的shared-libs构建到与可执行文件相同的目录中。这往往是一个更简单的解决方案。
使用cmake执行此操作的一种方法是
设置(CMAKE_RUNTIME_OUTPUT_DIRECTORY $ {CMAKE_BINARY_DIR} / bin)
或者您也可以根据构建风格设置输出目录。
答案 2 :(得分:1)
我发现(相信会是)一种很好的处理方式。它遵循将.dll添加到与.exe相同目录的方法。您可以像这样在CMake中完成它:
if (WIN32)
# copy the .dll file to the same folder as the executable
add_custom_command(
TARGET <app-target> POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
$<TARGET_FILE_DIR:<lib-target>>
$<TARGET_FILE_DIR:<app-target>)
endif()
其中app-target
是您要构建的应用程序或库的名称(通过add_executable
或add_library
创建),lib-target
是{ {1}}。
find_package
答案 3 :(得分:0)
我尝试了接受答案的选项1(通过pdeschain)。 我甚至创建了一个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&#39;和&#39;发布/ test.exe&#39;。所以对我来说这是一个糟糕的选择。
您可以添加以下行来填充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 ...我想我的下一次尝试将是选项