I'm trying to load dynamic libraries in C++ with following codes
Handle = LoadLibrary(wstring2string(FullLibraryPath).c_str());
In the terminal of CLion, it was fine. The same to Git Bash.
But when I am testing in cmd.exe and powershell.exe.
The problem happened.
LoadLibrary() function returned a NULL value.
The error message is The specified module could not be found.
I thought it may be a problem with dynamic linking, so I tried to add -static -lpthread in the compile arguments.The CMakeList file just like
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
add_definitions("--static -lpthread -static-libgcc -static-libstdc++")
endif ()
add_library(io SHARED libio/library.cpp ${SRC_FILES})
add_library(string SHARED libstring/library.cpp ${SRC_FILES})
add_library(array SHARED libarray/library.cpp ${SRC_FILES})
add_library(thread SHARED libthread/library.cpp ${SRC_FILES})
add_library(fs SHARED libfs/library.cpp ${SRC_FILES})
add_library(sys SHARED libsys/library.cpp ${SRC_FILES})
Unfortunately, the problem still exists.
What's the cause of the problem? And, how can I fix it?
I've uploaded a example to my netdisk.
link
Thanks for Remy Lebeau's help. I've solve this problem with
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_SHARED_LINKER_FLAGS "-static")
endif ()
Just add it before add_library or add_executable in the CMakeFileLists of dynamic library.
Related
For my wxWidgets project, I am trying to make the switch from my self-written Makefile to Cmake. I develop on macOS.
When I was writing that Makefile I ran into an issue with libtiff. I wanted to statically link my application so that I don't have to distribute any dylibs myself or rely on my users to install them. I built wxWidgets as a static library but when I compiled my code and checked my binary with otool I always found that my binary required a local dylib.
/usr/local/opt/libtiff/lib/libtiff.5.dylib
Finally I found a solution on here. In essence, in the linking line of my Makefile I replaced wx-config –-libs with LDFLAGS. LDFLAGS looks like this:
WXCONFIGLIBS := $(shell wx-config --libs)
WXCONFIGLIBS := $(WXCONFIGLIBS:-ltiff=/usr/local/opt/libtiff//lib/libtiff.a)
# I am not sure whether the double slash is a typo but it works so I don't change it
LDFLAGS := $(WXCONFIGLIBS)
Basically, I search-and-replaced -ltiff with the path to my static libtiff library.
Now I've managed to compile my project using Cmake. However, I'm getting the same warning message as I did when I battled my original issue.
ld: warning: dylib (/usr/local/lib/libtiff.dylib) was built for newer macOS version (11.0) than being linked (10.11)
How do I fix this? My CMakeLists contains these sections pertaining to wxWidgets:
find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net)
include(${wxWidgets_USE_FILE})
...
add_executable(myapp ${SOURCES})
target_link_libraries(myapp ${wxWidgets_LIBRARIES})
set_property(TARGET myapp PROPERTY CXX_STANDARD 17)
I already tried running some search-and-replace shenanigans like
string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES ${wxWidgets_LIBRARIES})
But that doesn't work. It does replace -ltiff but also seems to remove the semicolons and whitespaces separating the different libraries.
I've been scouring the web for any clues as to what to do, but I don't seem to have a good enough grasp of libraries to fix this.
Any help would be greatly appreciated.
Set wxWidgets_USE_STATIC=ON before calling find_package(wxWidgets). See the documentation for wxWidgets here: https://cmake.org/cmake/help/latest/module/FindwxWidgets.html
option(wxWidgets_USE_STATIC "Link to wxWidgets statically" ON)
find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net)
include(${wxWidgets_USE_FILE})
...
add_executable(myapp ${SOURCES})
target_link_libraries(myapp PRIVATE ${wxWidgets_LIBRARIES})
target_compile_features(myapp PRIVATE cxx_std_17)
My search-and-replace idea turned out to be not so bad. I was able to achieve the same outcome with Cmake as with my Makefile.
My problem was not using double quotes in the appropriate place. So instead of this:
string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES ${wxWidgets_LIBRARIES})
I simply needed to write:
string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES "${wxWidgets_LIBRARIES}")
So to solve my actual problem, I am calling this string() command just before the target_link_libraries() command.
I'm new to cmake and I was wondering how to create a static library. In gcc, it can be done by:
ar rsv
Well, how do you do it using CMake?
add_library(mylib STATIC file1.cpp file2.cpp)
add_executable(myexe main.cpp)
target_link_libraries(myexe mylib)
This generates a static library (.a file) but how do you compile it without adding an executable?
if I remove add_executable(myexe main.cpp), it gives me an error. I only want this file:
mylib.a
and NOT
myexe.exe
mylib.a
add_library can be used by itself, without using add_executable at all. Simply remove line 2 to get rid of the executable. The error is most likely caused by line 3, which needs myexe to function. Line 3 should also be removed, because you are only building the library and not linking it.
My bad, I just need to remove:
add_executable(myexe main.cpp)
target_link_libraries(myexe mylib)
and this will work.
I have a cmake project where I am trying to link the executable to the shared library. But it is not getting linked. After searching enough and not finding any useful solutions, I'm posting my question here, please let me know if there are any obvious mistakes as I am not familiar with cmake
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# Set Project Name
set(PROJECT_NAME myproj)
project(${PROJECT_NAME})
# Tell Cmake to invoke gcc with specific flags. Use c++11 standard.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Include all headers
include_directories(${PROJECT_SOURCE_DIR}/../public/include)
# Driver Program
file(GLOB_RECURSE SOURCE_FILES
"${PROJECT_SOURCE_DIR}/src/*.cpp"
)
# Dont know what to do about this
#set( CMAKE_SKIP_BUILD_RPATH true)
link_directories(${CMAKE_SOURCE_DIR}/../relative/path/to/sharedlib) #contains libshared.so
# Generate Executable, trying to generate shared library to see if it generates # correct dependencies
# add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
#Link the libraries
target_link_libraries(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/../relative/path/to/sharedlib/libshared.so)
Here is the steps I have tried and some observations.
If I generate a shared library instead of an executable, it is able to find the dependent shared library(i.e libshared.so)
ldd myproj.so
libshared.so => full/path/to/sharedlib/libshared.so (0x00007fa26c263000)
I did not fully understand what it meant, but it is able to find the shared library is what I guessed.
If I try to generate an executable instead of shared library, I see undefined reference errors to the functions within the library.
I tried just target_link_libraries(${PROJECT_NAME} shared) as well and it gave same error.
Any clues as to how can I get the shared library linked to my executable? Thanks
I want to compile an example code from this site (at the bottom). I downloaded GLFW 3.0.4 source code and I built it in a custom location. I used a default settings and GLFW was built as a static library. My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 2.8)
project(glfw_test_project)
SET(CMAKE_CXX_FLAGS "-Wall -Werror -g -std=c++11")
find_package(OpenGL REQUIRED)
include_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/include)
link_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/build/src)
add_executable(glfw_test main.cpp)
target_link_libraries(glfw_test ${OPENGL_gl_LIBRARY})
target_link_libraries(glfw_test glfw3)
When I run make I get following info:
Linking CXX executable glfw_test
/usr/bin/ld: /home/user/MyLibs/OpenGL/glfw-3.0.4/build/src/libglfw3.a(x11_clipboard.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [glfw_test] Error 1
make[1]: *** [CMakeFiles/glfw_test.dir/all] Error 2
make: *** [all] Error 2
What is wrong ?
Edit1
When I build GLFW as a dynamic library everything works fine. Then the last line in my CMakeLists.txt have to be replaced with:
target_link_libraries(glfw_test glfw)
What is wrong when using a static library ?
I experienced the same problems on Ubuntu 14.04 LTS.
First: error adding symbols: DSO missing from command line shows a wrong order of linker command line parameters. This post made me realise that. You need to call $ make VERBOSE=1 to see the linker call and check it with your own eyes. Remember: TARGET_LINK_LIBRARIES() should be the last command in your CMakeLists.txt And have a look at this order explanation.
Second: if you build against static GLFW3 libraries all the X11 libraries are not automatically added to your linker call, as atsui already showed above. In the GLFW-Documentation you can find a cmake variable which should fit your needs: ${GLFW_STATIC_LIBRARIES}. To make use of it and enable a more automatic build process, let pkg-config find all dependencies for X11 libs:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(myProject)
FIND_PACKAGE( PkgConfig REQUIRED )
pkg_search_module( GLFW3 REQUIRED glfw3 ) # sets GLFW3 as prefix for glfw vars
# now ${GLFW3_INCLUDE_DIR}, ${GLFW3_LIBRARIES} and ${GLFW3_STATIC_LIBRARIES}
# are set
INCLUDE_DIRECTORIES( ${GLFW3_INCLUDE_DIR} )
ADD_EXECUTABLE( myProject mySource.cpp )
TARGET_LINK_LIBRARIES( myProject ${GLFW_STATIC_LIBRARIES} )
# they include X11 libs
Now check the linker lib parameters again with $ make VERBOSE=1 and you should find many more X11 libs like:
-lXrandr -lXi -lXrender -ldrm -lXdamage -lXxf86vm -lXext -lX11 and -lpthread.
Third: when linking against the shared library, the dependencies to X11 etc. are resolved dynamically. That is why you don't need to explicitly add X11 lib flags to the linker. In that case you only need:
TARGET_LINK_LIBRARIES( myProject ${GLFW_LIBRARIES} )
Fourth: it happened to me, that some glfwCommands had undefined reference to - linker errors. I found out, that I installed GLFW3 in /usr/local/lib but the linker was given only the LD_LIBRARY_PATH environment variable which was only set to /usr/lib32. Adding the parameter -L/usr/local/lib solved the reference problem. To avoid it in future I've set LD_LIBRARY_PATH=/usr/lib32;/usr/local/lib;.
Hint: to check what values are in your GLFW cmake variables, print them during build:
FOREACH(item ${GLFW3_STATIC_LIBRARIES})
MESSAGE(STATUS " using lib: " ${item})
ENDFOREACH()
It seems that you resolved your own issue by rebuilding GLFW as a shared library and linking the example code with that. Instead, I'll try to answer your followup question about why it doesn't work when you try to link the static library.
Basically, if you want to link against the static library libglfw3.a, you need to link all of the dependent X11 libraries. You get an error linking the static library because you didn't specify any additional libraries to link, and CMake doesn't know what these dependencies are. You don't get an error when you link the shared library libglfw.so because the X11 libraries are linked to the shared library, and CMake knows to pull those in for you automatically.
If you want to use the static library, you can determine the necessary libraries to link as follows. According to the .pc file in GLFW, you can type this in the command-line to find out what these are:
pkg-config --static --libs x11 xrandr xi xxf86vm gl
If you translate this into a CMake command, it would look like this:
target_link_libraries( glfw_test glfw3 Xrandr Xrender Xi GL m dl drm Xdamage X11-xcb xcb-glx xcb-dri2 xcb-dri3 xcb-present xcb-sync xshmfence Xxf86vm Xfixes Xext X11 pthread xcb Xau Xdmcp)
So if you add this to the CMakeLists.txt, the example code should build without an issue.
By the way, you can automatically find the X11 libraries using CMake in the following way:
find_package(X11 REQUIRED)
target_link_libraries( my_program ${X11_LIBRARIES} )
However, the set of libraries stored in the X11_LIBRARIES variable will only contain a subset of the libraries needed for statically linking GLFW.
I'm not really sure how to properly handle static/dynamic linking in CMake, but I hope this helps.
at the moment I am trying to create a shared library using kde4_add_library. Actually it does not matter if it is add_library or kde4_add_library but it seems that add_library makes no sense since it cannot handle classes with "Q_OBJECT" macros/moc files?! Unfortunately compiling says "undefined reference" for many methods from classes of shared libraries in sub directories which are linked against the kde4 lib target.
The error messages look like:
./wc3lib/src/editor/editor.cpp:71: undefined reference to `wc3lib::editor::BlpCodec::startup()'
For finding the packages I use the following macros:
if (EDITOR)
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
elseif (PLUGINS)
find_package(Qt4 COMPONENTS QtCore QtGui)
endif ()
if (${QT4_FOUND})
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
include_directories(${QT_INCLUDE_DIR})
endif ()
if (EDITOR)
find_package(KDE4 REQUIRED)
elseif (PLUGINS)
find_package(KDE4) # only for MPQ plugins
endif ()
if (${KDE4_FOUND})
include(KDE4Defaults)
add_definitions(${KDE4_DEFINITIONS})
include_directories(${KDE4_INCLUDE_DIR} ${KDE4_INCLUDES})
link_directories(${KDE4_LIB_DIR})
endif ()
find_package(OGRE COMPONENTS Paging Terrain REQUIRED)
if (${OGRE_FOUND})
include_directories(${OGRE_INCLUDE_DIRS})
link_directories(${OGRE_LIB_DIR})
endif ()
the sub directories are added after that:
if (BLP AND ${OGRE_FOUND})
add_subdirectory(Plugin_BlpCodec)
endif ()
if (MPQ AND ${KDE4_FOUND})
add_subdirectory(kio_mpq)
endif ()
if (BLP AND ${QT4_FOUND})
add_subdirectory(qblp)
endif ()
they contain targets without any KDE macros:
add_library(Plugin_BlpCodec SHARED ${wc3lib_EDITOR_PLUGIN_BLPCODEC_SRC})
target_link_libraries(Plugin_BlpCodec wc3libblp ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${GETTEXT_LIBRARIES})
now finally in the parent directory the KDE target is created:
kde4_add_library(wc3libeditor SHARED ${wc3lib_EDITOR_SRC} ${wc3lib_EDITOR_UI_H})
target_link_libraries(wc3libeditor ${wc3lib_CORE_LIBRARIES} ${GETTEXT_LIBRARIES} ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${QT_LIBRARIES} ${KDE4_KIO_LIBS} ${KDE4_KUTILS_LIBS} ${KDE4_KPARTS_LIBS} Plugin_BlpCodec qblp)
the CMake options like "EDITOR" are all enabled.
For the one linked library "qblp" I use some Qt stuff:
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
the other one simply uses "add_library" and has itself also system libs linked against it.
None of these dependencies fails to compile.
The methods are all defined.
I use
cmake_minimum_required(VERSION 2.8.4)
kdelibs-4.11.5
qtcore-4.8.5-r1
this is not the first time I have problems using Qt/KDE via CMake. Any help so far?
edit:
Note that "Target "wc3libeditor" has an INTERFACE_LINK_LIBRARIES property which
differs from its LINK_INTERFACE_LIBRARIES properties." appear for the wc3libeditor target. Is this related to the linking issues?
So the problem seems to be that
find_package(KDE4 REQUIRED)
adds various C++ flags. You can find all this in /usr/share/apps/cmake/modules/FindKDE4Internal.cmake
Some of these flags lead to the undefined reference errors.
A simple workaround might be adding
set(CMAKE_CXX_FLAGS "")
after the find_package statement which is kind of ugly.
More information can be found here:
http://lists.kde.org/?l=kde-buildsystem&m=132906487119016
and there is a better solution using the export macro:
https://forum.kde.org/viewtopic.php?f=64&t=89265
Another solution might be using KDE Frameworks (5) instead.
I've also created a bug report: https://bugs.kde.org/show_bug.cgi?id=338151