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?
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:
The bar for clean CMake code is significantly higher for a library than for an application because the CMake code itself affects end users. For an application, some ugliness is tolerable because it doesn't propagate through the dependency tree (you don't typically link to executables).
However, executables usually don’t need a link interface, so it would make more sense to use the PRIVATE keyword here. this creates a myexec that contains not just the code for main.cpp as hoped, but also the code from the shared library mylibA. This would mean that mylibA is a static library, not a shared one.
Certainly for a single target, it is totally illegal to link to both at the same time. This means we don't need to support mixing both types in a single directory. The bar for clean CMake code is significantly higher for a library than for an application because the CMake code itself affects end users.
Since various package management systems (like vcpkg, Nuget, APT, etc.) have different standards for where to place CMake package config scripts, we create a cache variable, SomeLib_INSTALL_CMAKEDIR, to allow our users to control where those scripts go. We pick a common, safe default. Now we'll add the logic to install our libraries and headers:
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:
Thus you have two reasonable options if you don't want to clutter the OS directories with your app-specific dll:
A solution I prefer that hasn't really been mentioned, is build your shared-libs into the same directory as your executables. This tends to be a much simpler solution.
One way to do this with cmake is
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
Or you can also set output directories based on build flavours.
See how do I make cmake output into a 'bin' dir?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With