Discussion:
[CMake] How to link against a static lib under windows/minGW
Joachim Ziegler
2008-10-30 12:50:01 UTC
Permalink
Hello!

Maybe this has been asked here 100 times before, but I've searched
through the archives and could not find a solution to my problem:

I have a program that I want to link statically agains tthe NSPR libs,
and, if this is possible, against the Winsock2 libs.

So far, I have in

D:\nspr-4.6\lib

the files

libnspr4.dll
libnspr4.lib
libnspr4_s.dll

The following excerpt from my CMakeLists.txt works fine

if(CMAKE_HOST_WIN32)
INCLUDE_DIRECTORIES(D:/nspr-4.6/include)
LINK_DIRECTORIES(D:/nspr-4.6/lib)
ADD_EXECUTABLE(testPR PRifdefd.cpp ${BASEFILES})
TARGET_LINK_LIBRARIES(testPR nspr4 Ws2_32)
...

To run the executable, I have to copy the lib files libnspr4.dll and
libnspr4.lib into the build directory (where the executable testPR is
built). (Can I avoid this somehow?)

But now, what if I want to compile statically against NSPR (and maybe
Winsock2), so that I can give away my executable to a customer?

Greetings,
Joachim
Hendrik Sattler
2008-10-30 13:19:13 UTC
Permalink
Post by Joachim Ziegler
if(CMAKE_HOST_WIN32)
INCLUDE_DIRECTORIES(D:/nspr-4.6/include)
LINK_DIRECTORIES(D:/nspr-4.6/lib)
ADD_EXECUTABLE(testPR PRifdefd.cpp ${BASEFILES})
TARGET_LINK_LIBRARIES(testPR nspr4 Ws2_32)
...
To run the executable, I have to copy the lib files libnspr4.dll and
libnspr4.lib into the build directory (where the executable testPR is
built). (Can I avoid this somehow?)
I am pretty sure you do not have to copy them, at least no the .dll
file. Read the FIND_LIBRARY command help but LINK_DIRECTORIES as about
should work as well.
Post by Joachim Ziegler
But now, what if I want to compile statically against NSPR (and maybe
Winsock2), so that I can give away my executable to a customer?
ws2_32 is a system library, there's no sense in wanting to link that
statically.
If you put the libnspr4.dll (you do not need to ship the .lib file) into
the same directory as the executable, it will get used.

Additionally, if the .lib file is a static library, then you link
statically. If it is not, then you do not link statically. It is as easy
as this.

HS
Joachim Ziegler
2008-10-30 14:33:33 UTC
Permalink
Ok, I have the files
libnspr4.dll
libnspr4.lib
libnspr4_s.dll
where the last one should be the static library ("_s").
No. A DLL is a "dynamic link library". It may be linked statically
itself but that doesn't mean that you can link statically against it.
OK, then libnspr4_s.dll must be some other lib, maybe a debug version.

Anyway, changing the CMakeLists line
TARGET_LINK_LIBRARIES(testPR nspr4 Ws2_32)
(with which linking works fine)) just to
TARGET_LINK_LIBRARIES(testPR nspr4_s Ws2_32)

prevents the linker from finding the library:


D:\MinGW\bin\g++.exe CMakeFiles\testPR.dir\PRifdefd.cpp.obj -o
testPR.exe
-Wl,--out-implib,libtestPR.dll.a
-Wl,--major-image-version,0,--minor-image-version,0 -LD:\nspr-4.6\lib
-lnspr4_s -lWs2_32
D:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe:
cannot find -lnspr4_s

(?)
Werner Smekal
2008-10-30 14:47:44 UTC
Permalink
Post by Joachim Ziegler
Hi,
OK, then libnspr4_s.dll must be some other lib, maybe a debug version.
Anyway, changing the CMakeLists line
TARGET_LINK_LIBRARIES(testPR nspr4 Ws2_32)
(with which linking works fine)) just to
TARGET_LINK_LIBRARIES(testPR nspr4_s Ws2_32)
D:\MinGW\bin\g++.exe CMakeFiles\testPR.dir\PRifdefd.cpp.obj -o
testPR.exe
-Wl,--out-implib,libtestPR.dll.a -Wl,--major-image-version,0,--minor-
image-version,0 -LD:\nspr-4.6\lib
-lnspr4_s -lWs2_32
D:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin
\ld.exe: cannot find -lnspr4_s
That's because it tries to link to libnspr4_s.lib which doesn't exist.
Usually the naming conventions for MinGW libraries are:

libxxx.dll executable
libxxx.dll.a import library for dll
libxxx.a shared library.

Obviously the MinGW linker also tries for libxxx.lib, and that's the
reason why it works in the first case. But your .lib seems to be the
import library for the dll, so I don't think you have a static library
anyways.

Regards,
Werner
Post by Joachim Ziegler
(?)
_______________________________________________
CMake mailing list
http://www.cmake.org/mailman/listinfo/cmake
--
Dr. Werner Smekal
Institut fuer Allgemeine Physik
Technische Universitaet Wien
Wiedner Hauptstr 8-10
A-1040 Wien
Austria

email: ***@iap.tuwien.ac.at
web: http://www.iap.tuwien.ac.at/~smekal
phone: +43-(0)1-58801-13463 (office), +43-(0)1-58801-13469 (laboratory)
fax: +43-(0)1-58801-13499
Joachim Ziegler
2008-10-30 16:01:29 UTC
Permalink
Post by Werner Smekal
reason why it works in the first case. But your .lib seems to be the
import library for the dll, so I don't think you have a static library
anyways.

OK.

Now how can I tell CMake to include the (external) file

D:\nspr-4.6\lib\libnspr4.dll

(which is not created by the CMake compilation process) in the package
created by CPack? As the easiset solution, the library should just be
extracted in the same bin/ directory as my test program.

Joachim
Joachim Ziegler
2008-10-30 16:17:35 UTC
Permalink
Post by Joachim Ziegler
Now how can I tell CMake to include the (external) file
D:\nspr-4.6\lib\libnspr4.dll
I've got it:

INSTALL(FILES D:/nspr-4.6/lib/libnspr4.dll DESTINATION bin)

Thnaks,
Joachim

Loading...