calling multi DLL interactivity - dll

I'm using Dev-c++. My main.cpp calling functions in both a.dll and b.dll which works perfectly. Now, new requirement I need b.dll call function foo() in a.dll.
I included a.header file in bmain.cpp, Put lib file of a in linker. re-build b.dll successfully.
Next, I included both a.header & b.header in main.cpp, put lib files of both a & b in linker. After compile, I got error message "undefined reference to foo()". How to solve this situation?
tried merge tow .dll, but got multi definition error.

Related

Linking problem when Calling/Including subroutines defined on separated files on Fortran using CMake

We have a quite large Fortran program that's developed and builded using Visual Studio and Ifort for Windows. On the linux side, we used to get the .dep generated on windows side, proccess it using a script, and create a command line call with the files on the order needed for the compilation. Now, I'm trying to rewrite the linux build using CMake.
After many solved problems (casing, enconding, ...) I've encountered some errors on the linking part. We have some subroutines defined on separated files that get called straight from other files like: CALL SUBROUTINE_NAME ()
I guess VisualStudio is somehow handling this linking but when I try to compile it using CMake on linux i get an error "undefined reference to SUBROUTINE_NAME".
My first tought was trying to include the file where this routine is defined but the subroutines are defined on multiple directories and, as far I understand, unless I put all this places on the include path for the compiler they can't be found.
Another option would be rewriting all this as modules and using them where needed. I guess this would be a cleaner solution but also a lot of work that I'm not sure I'd have the time for now.
First of all, I'd like to make sure my reasoning seems right and then what would be the best or some alternatives way to deal with this, like a way to manually include the paths for each occurrence or if there's a way to make CMake work like VisualStudio and resolve this references for example.
Thanks in advance for any insight and don't hesitate to get in touch and ask for more information if needed.
Edit to add more CMake info as requested:
CMakeLists.txt:
file(GLOB_RECURSE sources ./src/*.for)
add_executable(program_name ${sources}
target_include_directories(program_name PUBLIC "./src/includes")
I've managed to manually compile the file passing the .o of the separated subroutine but couldn't get CMake to include it as needed.
My subroutine file is been processed by CMake and a .o file is been generated for it, as I'm passing it as source.
Whenever I use a module, CMake can automatically add the module as a dependency for the file. But on this cases, where I'm calling the subroutine directly it doesn't generate the correct dependency for the Makefile.

Cmake executable can not link with the new interface library depending on another library

I have the following dependencies:
add_library(lib)
add_library(ilib INTERFACE)
add_dependencies(ilib lib)
target_link_libraries(ilib INTERFACE
"-Wl,--whole-archive $<TARGET_FILE:lib> Wl,--no-whole-archive")
add_executable(exe ilib)
When I changed some source codes of lib, the lib as expected was compiled and built again. However, exe did not link the new lib. If I use add_executable(exe lib), then exe will always link the new lib. (The reason why I use the ilib is that I need to process lib before using it.)
You expect lib to be propagated when one links with ilib.
But command add_dependencies doesn't add properties for propagation. You need
# Linking with `ilib` will transitively link with a `lib`
target_link_libraries(ilib INTERFACE lib)
When need to use --whole-archive option for linker, it could be done in the following way:
target_link_libraries(ilib INTERFACE "-Wl,--whole-archive" lib "Wl,--no-whole-archive")
When parse arguments for given function, CMake will finds argument lib to be a target name, and will add proper file-level dependency. With that dependency the executable will be relinked whenever the library file has been changed.

Link errors when building shared library even though source files are included

I am specifying a shared library build from source files in my CMakeLists.txt file like so:
# Library setup
file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Source/*.cpp)
file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Source/*.h)
Inside the source directories contain all my .h and .cpp files required to build my shared library. So I then do something like this:
add_library(mylibrary SHARED ${SOURCES} ${HEADERS} )
I also link a bunch of other .libs with mylibrary later on as well (Could there be a clashing issue?). The problem arises when I try to build mylibrary. I receive linking errors such as:
Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol __imp_cosf mylibrary ***.obj 1
even though the symbol is defined in my source files that I have included. I am not exactly sure what to do in order to properly let my project find those symbols. The funny thing is is that when I build as a static library it is fine. However, when I try to build as a dynamic library, these errors appear.
So, I'm not exactly sure why this worked. But there was a conflict warning between linking to MSVRCT and libcmt. It said something like this in the output log:
Resolving LNK4098: defaultlib 'MSVCRT' conflicts with ...
This is because libcmt is a static library for release build and uses \MT flags. MSVRCT is a release DLL version and compiled with \MD flag. Because of this conflict, I had to change my compiler flags to be:
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
Then the symbols were able to be found. If anyone has any comments/corrections to why this worked please add.

Correctly Building Fortran Libraries And Using Them To Build Applications

I found a few previous questions regarding this, but was unable to find something specific for advice on correctly associating libraries and module files *.mod in a Makefile.
I have a project directory named project where all source files for a library are in project/src, all compiled *.mod files are placed in project/include, and static libraries are created into the directory project/lib using the following:
ar rc myLibrary.a module1.o module2.o module3.o
Following this, I create an application code (a Fortran program that uses these libraries) in the directory project/applications. I have now, at the root level (that is, inside project) created a simple shell script that can build the application. This part is where I cannot get the process to work.
Here is what I am doing:
INCLUDELIB='./include'
LINKLIB='./lib'
INCLUDEOTHER=<include directories for other math libraries>
LINKOTHER=<link directories and link flags for other math libraries>
COMPILER='ifort'
COMPOPTS=<compiler flags, currently I use none>
# building the application:
$COMPILER $COMPOPTS -c ./applications/application.f90 -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER
$COMPILER $COMPOPTS application.o -I$INCLUDELIB $INCLUDEOTHER -L$LINKLIB $LINKOTHER -o application.out
This procedure does not work, and it gives Error in opening the compiled module file. Check INCLUDE paths.
I tried a few variants of the above from my readings on the web about this, and I hope that it is not some minor/silly error that I am overlooking that is leading to this.
Any help or advise will be much appreciated.
This is the message you get when things were not done right with the library (it's not your fault!).
*.mod files are compiler-specific, but not *.o files : *.mod files of gfortran are not compatible with *.mod files of ifort. Therefore, when you build a library, you should put all your API functions and subroutines outside of the modules. For example:
don't do this:
module x
...
contains
subroutine sub_x
...
end subroutine sub_x
end module
but do this instead:
module x
...
end module
subroutine sub_x
use x
...
end subroutine sub_x
In this way you don't require the users to use mod files, and you can distribute your library as a .a or a .so archive.
In your case, the library you use was almost surely compiled with gfortran, so you are stuck with gfortran. The solution is to write another library as a wrapper around the original library. For example, do this
for each function/subroutine you need:
subroutine wrapped_sub_x(arguments)
use x
call sub_x(arguments)
end
Then, you compile your wrapper library with gfortran in a .a archive, and you link it to your project with ifort. In your project, don't forget to call your wrapper library instead of the original library.

MSVC 2008 - Unresolved External errors with LIB but only with DLL, not with EXE project

I have a DLL that I am trying to link with a libjpeg LIB using MSVC 2008 that is generating Unresolved External Symbol errors for the libjpeg functions. I also have a test project that links with the exact same libjpeg library file and links without error and runs fine too.
I have triple-checked my LIB path and dependent LIBS list settings and literally copy and pasted them from the EXE project to the DLL project. I still get the errors. I do have the libjpeg include headers surrounded by extern "C" so it is not a name mangling issue and the unresolved external warnings show the "missing" libjpeg functions as undecorated (just a leading underscore and the # sign parameter byte count suffix after each name).
What could make the linker with the DLL project be unable to find the functions properly when the test EXE project has no trouble at all? I'm using the pre-compiled 32-bit static multi-threaded debug library which I downloaded from ClanLib.
Thanks,
Robert
After a lot of experimentation I found the solution. It turns out the problem was due to a difference in the calling convention used by the DLL and the LIB projects (In MSVC 2008 this is set on the Project Properties, "Configuration Properties -> C/C++ -> Advanced" setting. The DLL project was set to __stdcall and the LIB was __cdecl. Recompiling LIBJPEG with __stdcall fixed the problem.