Qt .pro combine libraries - windows

I have a subdirs Qt project composed of :
an external (not made by me) lib
an internal (made by me) lib using the external lib
an application using the internal lib
I am on Windows using mingw as compiler
When compiling the libraries I have no issues, everything seems to work fine.
But when I compile the application, I get an ld error : undefined reference to external lib functions (called from internal libs function).
I think this is because when compiling the internal library these method are not called therefore not loaded and this is why it can't find them.
Is there a way to combine the 2 libraries (or at least to force the compiler/linker to resolve the symbols) when compiling the internal library ?

I found a way to fix my issue.
In the pro file of my internal lib :
I changed the TARGET value from internal_lib to internal_lib_unlinked.
I added a new line QMAKE_POST_LINK += ar crsT $$DESTDIR/libinternal_lib.a $$DESTDIR/libinternal_lib_unlinked.a path/to/libexternal_lib.a
This is hacky but it works.
Found thanks to How to combine several C/C++ libraries into one?

Related

cmake: using shared library while building when only headers exist

I would like to
build a binary that is relying on a shared library at runtime.
the library does not exist while compiling the binary.
the headers for the library are available
I would like to create a CMake project under those circumstances. Therefore I tried the following, but it will complain about the missing lib for sure:
cmake_minimum_required (VERSION 3.8)
project (example)
add_executable(${PROJECT_NAME}
main.c
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
# system libs
lib_that_does_not_yet_exist
)
When removing the link instruction to lib_that_does_not_yet_exist, then I will get a undefined reference error.
Question: Is there any way to accomplish what I need?
Background: I am crosscompiling the binary, the lib is therefore having the wrong architecture to install it on the host. I know there may be some ways around that issue, but I am mainly interested in the above question.

Library's CMake generates DLL. Application's CMake wants LIB

My library has minimal, straightforward CMake code with the pertinent lines
add_library(MyLib <sources>)
install(
TARGETS MyLib
LIBRARY DESTINATION ${destination}/lib
RUNTIME DESTINATION ${destination}/lib
COMPONENT Libraries)
install(
FILES mylib.h
DESTINATION ${destination}/include
COMPONENT Headers)
When executed under Windows, the system generates mylib.dll in ...\build\Release, and mylib.lib and mylib.exp (what's that?) in ...\build\lib\Release. It only installs mylib.dll.
My application has minimal, straightforward CMake code to search for my library:
find_path(MyLib_INCLUDE_DIR mylib.h)
find_library(MyLib_LIBRARIES NAMES MyLib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib DEFAULT_MSG MyLib_LIBRARIES MyLib_INCLUDE_DIR)
Which works under Linux, but under Windows results in
-- Could NOT find MyLib (missing: MyLib_LIBRARIES)
From experimentation I know that this error occurs whenever there is only a .DLL file, and no associated .LIB import library.
Shall I correct MyLib to install mylib.lib? How?
Or is it possible to modify my application so that it is satisfied with mylib.dll only? How?
Research done so far
This is not about static vs dynamic linking (DLL and LIB files - what and why?, cmake link against dll/lib): I want dynamic linking; if a .LIB file is required, it has nothing to do with static linking.
This link cmake : shared library : how to get the .lib name instead of .dll name? may be pertinent, but is not explicit enough. Two other questions CMake generated VS project expecting lib instead of dll, Linking dll/lib to a cmake project seem related, but have no answer.
Command install classifies .lib file for a shared library as ARCHIVE. This is explicitly stated in the documentation:
For DLL platforms (all Windows-based systems including Cygwin), the DLL import library is treated as an ARCHIVE target.
So you need to add ARCHIVE clause to install() for install .lib file as well:
install(
TARGETS MyLib
ARCHIVE DESTINATION ${destination}/lib
LIBRARY DESTINATION ${destination}/lib
RUNTIME DESTINATION ${destination}/bin
COMPONENT Libraries)
Not also, that RUNTIME DESTINATION is usually specified as bin, the same as destination for executables. This helps the executables on Windows to locate the shared libraries (.dll).

Why does OMNet++ compiler gets errors for a precompiled package?

I have included an external package callled SoPlex (a folder of .cpp and .h files and the library files) into my OMNet++ project. I have already tested the package in Code::Blocks IDE and it works fine besides some warnings it had: warning: explicit conversion operators only available with -std=c++11 or -std=gnu++11.
It certainly was working in Code::Blocks IDE. But when I want to use it in my OMNet++ project it gives a lot of errors for the SoPlex package like in the picture:
It gives a lot of errors for just the code of SoPlex and not my OMNet++ project code.
Any idea what may cause the problem?
I have used MinGW to compile SoPlex package in Code::Blocks IDE. When I use MinGW GCC in OMNet++ instead of GCC for OMNet++ as current toolchain there is this error fatal error: omnetpp.h: No such file or directory.
Regarding the errors with the 3rd party library. Depending where you put the library inside the src folder, at least that directory must be added as an include dir, otherwise the header files will not be found by the compiler.
As for the problem with the omnetpp.h: OMNeT++ has it's own makefile generator which automatically adds the required include folder (omnetpp_root/include). The generic MinGW GCC toolchain does not. If you want to avoid extra work, always use the omnet toolchain to build your models.

CMake with Xcode 5 : how to add external libraries as 'Target Dependencies' instead of linker flags?

We are building our software under OS X (10.8 at the moment). The project build is managed by CMake (2.8.12).
External dependencies (i.e. not target added by project's CMakeLists) are handled using what we undestood as the canonical way :
Calling find_package(${external_lib}) from a root CMakeLists.
If a given target needs to link against the previously found package, the target's CMakeLists calls target_link_libraries(${TARGET_NAME} ${${external_lib}_LIBRARIES})
The procedure works nicely from a building perspective (the target is actually linked against the external library). Yet the external library is actually given as an additional flag to the compiler, in Build Settings::Other Linker Flags, when it seems that Xcode native way for doing this would be to add the dirname to Build Settings::Library Search Path, and the basename to Build phases::Target Dependencies.
Is there a way to achieve this behavior (without breaking the behavior for other platforms) ?
The behavior of CMake was changed years ago to use full paths.
http://www.cmake.org/cmake/help/v3.0/policy/CMP0003.html
Why do you want to split it?

"ld: duplicate symbol" issue in XCode cross-compilation

I am trying to cross-compile a project for the iOS (which is written in windows) and is based on openCV. And then I am trying to use these cross-compiled openCV libs for a specific application (called testApp).
I was first able to successfully cross-compile openCV for the iOS. Then I used these libraries to created another library called testLib.a which was consumed by an application testApp (which also used some openCV functionality).
The testLib.a compiled successfully but, for the testApp I had to add dependency to both testLib.a and the openCV libs (.a files). When I try to compile testApp, I get the following error -
ld: duplicate symbol cv::split(cv::Mat const&, cv::Mat*) in
/Users/suri/Projects/testLib/lib/Debug/libopencv_core.a(convert.o) and
/Users/suri/Projects/testApp/libs/testLib.a(convert.o) for
architecture i386
I can see that this error is probably coming because the openCV libs are added by open testLib as well as testApp. My question is should I try and reorganize the project or is there some other way to fix this issue?
I tried to find where the "split" function might actually be used in testLib but it does not seem to be called. Also, I have checked and every .h in the testLib as well as testApp and they all have a "ifndef" macro.

Resources