Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
Hi Vincent, Sorry for top posting. Perhaps is not easy visible for manual ( https://www.gnu.org/software/libtool/manual/html_node/Creating-object-files.html ) use of conditional code. In this case #ifdef PIC. Perhaps better solution is use of -export-symbols. Vincent Torri wrote: Hello I contribute to an autotools project. The tree is : src/lib/libfoo <--- the library, with libfoo.h declaring the public symbols src/bin/bar <-- the binary which uses libfoo and includes libfoo.h in its source files I want to create the library 'libfoo' on Windows. I also want to declare public symbols with __declspec(dllexport) and __declspec(dllimport) in a macro that I call MY_API in libfoo.h Thanks to DLL_EXPORT that libtool is passing to the preprocessor when compiling the library 'libfoo', there is no problem to compile libfoo. MY_API is correctly defined either when I build the static lib, or the shared lib, or both. The problem I am facing is when I build the 'bar' binary. On Windows: 1) if 'lifoo' is built as a shared library, when I include libfoo.h in 'bar' source files, MY_API must be defined as __declspec(dllimport) 2) if 'libfoo' is built as a static library, when I include libfoo.h in 'bar' source files, MY_API must be defined as nothing but, as far as I know, when I compile 'bar', I couldn't find a way to know if 'libfoo' has been compiled as a static library or as a shared library. I have looked at the 'bar' source files gcc calls, and they are the same in both cases (libfoo compiled as a static or shared lib). So I don't know how I can correctly define my macro MY_API. Here is, for now, my macro: #if defined(_WIN32) || defined(__CYGWIN__) # ifdef FOO_BUILD // defined when building 'libfoo' # ifdef DLL_EXPORT # warning "BUILD DLL" # define MY_API __declspec(dllexport) # else # warning "BUILD STATIC" # define MY_API # endif # else # warning "IMPORT DLL" # define MY_API __declspec(dllimport) # endif in the last #else, I don't know what to do to correctly manage MY_API for my problem above One solution would be : never compile 'lbfoo' as a static lib ("DLL are good on Windows"), but I would like to support both static and shared libraries. Does someone know how to solve my issue ? (I hope I've been clear enough...) thank you Vincent Torri Regards, Roumen Petrov
Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
On Tue, Aug 10, 2021 at 9:21 PM Roumen Petrov wrote: > > Hi Vincent, > > Sorry for top posting. > > Perhaps is not easy visible for manual ( > https://www.gnu.org/software/libtool/manual/html_node/Creating-object-files.html > ) use of conditional code. > In this case #ifdef PIC. > > Perhaps better solution is use of -export-symbols. As I have said, the problem is not the lib itself. There is no problem with the lib. The problem is with the binary : when I compile it, there is no way to know if the library, that the binary uses, is a static library or shared library (know == having a macro to distinguish shared lib and static lib) Vincent > Vincent Torri wrote: > > Hello > > > > I contribute to an autotools project. The tree is : > > > > src/lib/libfoo <--- the library, with libfoo.h declaring the public symbols > > src/bin/bar <-- the binary which uses libfoo and includes libfoo.h in > > its source files > > > > I want to create the library 'libfoo' on Windows. I also want to > > declare public symbols with __declspec(dllexport) and > > __declspec(dllimport) in a macro that I call MY_API in libfoo.h > > > > Thanks to DLL_EXPORT that libtool is passing to the preprocessor when > > compiling the library 'libfoo', there is no problem to compile libfoo. > > MY_API is correctly defined either when I build the static lib, or the > > shared lib, or both. > > > > The problem I am facing is when I build the 'bar' binary. On Windows: > > > > 1) if 'lifoo' is built as a shared library, when I include libfoo.h in > > 'bar' source files, MY_API must be defined as __declspec(dllimport) > > 2) if 'libfoo' is built as a static library, when I include libfoo.h > > in 'bar' source files, MY_API must be defined as nothing > > > > but, as far as I know, when I compile 'bar', I couldn't find a way to > > know if 'libfoo' has been compiled as a static library or as a shared > > library. I have looked at the 'bar' source files gcc calls, and they > > are the same in both cases (libfoo compiled as a static or shared > > lib). So I don't know how I can correctly define my macro MY_API. > > > > Here is, for now, my macro: > > > > #if defined(_WIN32) || defined(__CYGWIN__) > > # ifdef FOO_BUILD // defined when building 'libfoo' > > # ifdef DLL_EXPORT > > # warning "BUILD DLL" > > # define MY_API __declspec(dllexport) > > # else > > # warning "BUILD STATIC" > > # define MY_API > > # endif > > # else > > # warning "IMPORT DLL" > > # define MY_API __declspec(dllimport) > > # endif > > > > in the last #else, I don't know what to do to correctly manage MY_API > > for my problem above > > > > One solution would be : never compile 'lbfoo' as a static lib ("DLL > > are good on Windows"), but I would like to support both static and > > shared libraries. > > > > Does someone know how to solve my issue ? (I hope I've been clear enough...) > > > > thank you > > > > Vincent Torri > > > > Regards, > Roumen Petrov > >
Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
On Tue, 10 Aug 2021, Vincent Torri wrote: Perhaps better solution is use of -export-symbols. As I have said, the problem is not the lib itself. There is no problem with the lib. The problem is with the binary : when I compile it, there is no way to know if the library, that the binary uses, is a static library or shared library (know == having a macro to distinguish shared lib and static lib) This is a good point. For GraphicsMagick we just had to deal with it and provide an external way to know how the library was expected to have been compiled. This is fragile since it is possible/likely that both static and DLL are available at the same time and compiler will choose one of them according to its own rules, and especially if libtool is not used for linking against that library. Bob -- Bob Friesenhahn bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer,http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt
Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
On 2021-08-10, Vincent Torri wrote: [...] > As I have said, the problem is not the lib itself. There is no problem > with the lib. The problem is with the binary : when I compile it, > there is no way to know if the library, that the binary uses, is a > static library or shared library (know == having a macro to > distinguish shared lib and static lib) I'm not too familiar with shared libraries on Windows, but I think mingw solves this particular problem by generating static wrapper libs with stub functions that then call the real implementation in the dll. With such a wrapper, I suppose there is no difference (from the program's perspective) between linking against the real static archive versus linking against the wrapper. When using mingw and libtool simple libraries appear to "just work" at least. Without such a wrapper I suppose you will need to know at compile time which libraries will be used in the future at link time. I don't think libtool can make any assumptions here in general, as link options are not typically passed to compile mode commands (and in fact, many libtool options are overloaded to mean different things depending on whether you are running it in compile or link mode). It all seems very annoying indeed. I wonder how Windows users deal with this. Cheers, Nick
Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
On Tue, Aug 10, 2021 at 11:19 PM Nick Bowler wrote: > > On 2021-08-10, Vincent Torri wrote: > [...] > > As I have said, the problem is not the lib itself. There is no problem > > with the lib. The problem is with the binary : when I compile it, > > there is no way to know if the library, that the binary uses, is a > > static library or shared library (know == having a macro to > > distinguish shared lib and static lib) > > I'm not too familiar with shared libraries on Windows, but I think > mingw solves this particular problem by generating static wrapper libs > with stub functions that then call the real implementation in the dll. I guess that you are talking about the import library (which could be created with gcc on Windows). Import libraries can also be built with Visual Studio. > With such a wrapper, I suppose there is no difference (from the program's > perspective) between linking against the real static archive versus > linking against the wrapper. When using mingw and libtool simple > libraries appear to "just work" at least. > > Without such a wrapper I suppose you will need to know at compile time > which libraries will be used in the future at link time. I don't think > libtool can make any assumptions here in general, as link options are > not typically passed to compile mode commands (and in fact, many libtool > options are overloaded to mean different things depending on whether you > are running it in compile or link mode). ok, so no perfect solution > It all seems very annoying indeed. I wonder how Windows users deal with > this. Well, if you have a Visual Studio solution (either hand-written, or created with a meta build-system like cmake or meson), you explicitly write the link command. The only solution I can see is : forcing to have only one specific library. either static or shared, and throw an error if the wrong lib is chosen at configure time. And as I prefer DLL compared to static lib, I know what to do :-) thank you Vincent Torri
Re: Question about static and shared libraries and their usage in a binary on Windows in a autotools project
On Tue, Aug 10, 2021 at 10:38 PM Bob Friesenhahn wrote: > > On Tue, 10 Aug 2021, Vincent Torri wrote: > >> > >> Perhaps better solution is use of -export-symbols. > > > > As I have said, the problem is not the lib itself. There is no problem > > with the lib. The problem is with the binary : when I compile it, > > there is no way to know if the library, that the binary uses, is a > > static library or shared library (know == having a macro to > > distinguish shared lib and static lib) > > This is a good point. For GraphicsMagick we just had to deal with it > and provide an external way to know how the library was expected to > have been compiled. > > This is fragile since it is possible/likely that both static and DLL > are available at the same time and compiler will choose one of them > according to its own rules, and especially if libtool is not used for > linking against that library. I'll for DLL to be chosen thank you Vincent Torri