Linking math library in CMake file on windows and linux - c

I have been able to write a CMakeLists.txt file that is able to build my C project on Linux, however, I have been having a lot of trouble to build the project on windows. The cmake .. call succeeds, and Visual Studio 2017 project files are generated, but the build then fails siting:
Error LNK1104 cannot open file 'm.lib'. In the CMakeLists.txt file I am using target_link_libraries(MY_EXECUTABLE m) to try and link the math library, which works on linux, but the above error occurs on windows. After some research, it seems to me that math is handled by the mscvr library on windows, not libm as on linux, but I'm not sure how to configure the CMake file so that I can build on both operating system.
Does anyone have an idea on how I could set this up to be able to build in both environments?

Visual Studio does not need or want you to explicitly request linking the math library. You must avoid adding it as a link library when building for Windows. Instead of unconditionally doing target_link_libraries(MY_EXECUTABLE m), then, you might use:
IF (NOT WIN32)
target_link_libraries(MY_EXECUTABLE m)
ENDIF()

Related

MSYS2 and SDL2, distributing binary?

I just compiled a SDL2 program in MSYS2 and would like to distribute a binary copy of the program in a ZIP file.
But to run the program in "Normal" Windows I have to copy a long list of DLLs from /mingw64/bin.
Is there a better way of doing this? maybe linking statically?
How would the license work either way?
My own program is BSD 3 clause.
I'm using SDL2, SDL2_image, SDL2_ttf and all their dependencies.
You can build statically. The licensing situation in your case makes no difference between static/dynamic linkage.
I'm not sure how you build but here is an example with CMake: CMake - Compile in Linux, Execute in Windows
(In the example the binary is cross-compiled but the static stuff is the same for native compilation as well).
I just found out that all library licenses are located in /mingw64/share/licenses
So it's pretty easy to copy the needed licenses to the ZIP file.

Having Difficulty Integrating JSON Library with My AVR Microcontroller Code

I am a relatively inexperienced C developer with no previous experience in integrating libraries made by other developers into existing projects.
Basically, I need a means of parsing JSON data in an AVR microcontroller for a university project. To this end I attempted to download and integrate jansson (https://github.com/akheron/jansson) into my existing build of the microcontroller code. I am working with Atmel Studio in Windows 10, but I have also installed Code::Blocks with MinGW GCC (on the same Windows 10 installation) for the purpose of building the library, and to attempt to integrate the library into a native Windows application. So far, neither has been successful, and I get the same errors. All of the online resources I've found so far have been to basic to be useful, or well beyond my comprehension.
This is what I have done thus far:
I began by attempting to build the software and then integrate it into an existing project per the instructions in https://jansson.readthedocs.io/en/2.11/gettingstarted.html. I installed CMake, built the project files for Code::Blocks with cmake.exe -G “CodeBlocks - MinGW Makefiles”, then opened the project and built everything. A few of the targets (I believe related to testing) failed to build, but jansson itself built and output libjansson.a to the \lib\ directory, so I didn’t think too much of it.
That is as far as I’ve been able to get. In both Atmel Studio and Code::Blocks, I do the same thing: add jansson.h to the relevant include paths, add #include “jansson.h” to all of the relevant files, and add libjansson.a as a library in each IDE’s respective linker options. I’ve tried various things like adding and removing flags to the linker, but the output is always “cannot find -ljansson”, “undefined reference to ‘json_object_seed’” (which is a function in the API I’m calling for no reason other than to see if the project has built properly) and/or “ld returned 1 exit status”.
I cannot help but feel as if the issue is with the line “cc -o prog prog.c -ljansson” in the documentation linked above. I really just don’t understand how to set up the linker properly to get the project to build.
If anyone could give some insight into what I’m doing wrong/the correct way to link this library I would appreciate it a lot.
The library itself should be built with appropriate toolchain. I assume that you built your library twice, one version using MinGW toolchain and other with avr-gcc toolchain.
If you compile target application and linker cannot find library, then try to add path of directory that contains *.a file of library to linker settings (linker search path). Let's say you have: /path/to/lib/libjansson.a
In Code::Blocks: Project → Build options → Search directories → Linker add /path/to/lib/. Then it should link with include path set, for example: cc -o prog prog.c -ljansson -L/path/to/lib/
In Atmel Studio when you add a library in Solution Explorer → Libraries → Add Library it should automatically add library search path to linker options. If you check Project → Properties → AVR/GNU Linker there should be (between other options): -Wl,-ljansson -Wl,-L"/path/to/lib/"
If you copied library files (libjansson.a and jansson.h) to your application's project directory, it will be convenient to use relative paths to library files.

Missing libgcc_s_dw2-1.dll

I have a Windows 7 64bit system with the latest MinGW (32bit) installed along with the Qt 5.5 SDK (again 32bit) which also ships with its own MinGW. Due to the fact that I'm not the only one using the system I can't remove the standalone MinGW.
My project is using qmake and is a plain C project (not C++). Everything builds fine but when I try to execute my binary in the command line I get that the application was unable to start due to a missing libgcc_s_dw2-1.dll on the system.
After looking into the issue I found that both the standalone MinGW and the one shipped alongside the Qt SDK have the mentioned DLL.
Standalone MinGW - libgcc_s_dw2-1.dll is located inside the bin subdirectory of the MinGW installation where the binaries are located (gcc, g++, gdb etc.)
Qt MinGW - libgcc_s_dw2-1.dll is located inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\lib subdirectory while the MinGW components' binaries are inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\bin.
I would like to know how to properly set my PATH variable so that:
The application starts properly
No conflicts with the standalone MinGW installation occur
Just a side-note: I've already checked other posts here on SO but was unable to find a solution (perhaps I've missed it). I have also tried LIBS += -static but the result is the same.
You just need to copy this dll with your executable, i.e.:
cp <path-to-qt-install-dir>\qt5.7.0\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll <path-to-dest-dir>
You mat find that you have other dependencies, to see which other deps you have you can use: ldd <your-executable>. You only need to copy the qt specific dlls you can see these by:
ldd <executable> | grep -i qt
note
You can statically link it with:
linker commands like -static-libgcc or -static, but I think you start to hit LGPL issues and also you may need to statically compile qt from source - can't recall for this particular file.
note2
Sorry ldd is for linux, just realized you have windows, in which case you can use one or both of:
dependency walker: from here
<path-to-qt-bin-folder>\windeployqt.exe <path-to-your-executable>
I have mixed results with windeployqt, but if you have any plugins its quiet good for getting that part sorted.

Dealing with static libraries when porting C code from one operating system to another

I have been working on some C code on a windows machine and now I am in the process of transferring it to a Linux computer where I do not have full privileges. In my code I link to several static libraries.
Is it correct that these libraries need to be re-made for a Linux computer?
The library in question is GSL-1.13 scientific library
Side question, does anyone have a pre-compiled version of the above for Linux?
I have tried using automake to compile the source on the Linux machine, but no makefile seems to be created and no error is output.
Thanks
Yes, you do need to compile any library again when you switch from Windows to GNU/Linux.
As for how to do that, you don't need automake to build GSL. You should read the file INSTALL that comes inside the tarball (the file gsl-1.16.tar.gz) very carefully. In a nutshell, you run the commands
$ ./configure
$ make
inside the directory that you unpacked from the tarball.

How to build gnu `libiconv` on & for windows?

I want to build a static library (*.LIB file) GNU libiconv on windows to be used with other libraries in Visual C++. Other libraries I'm using are built with "MultiThreaded DLL" (/MD) Runtime option. So, I need to build libiconv with the same option.
Problem is the libiconv uses GNU build system and I want to compile with /MD option. You can see the source structure of libiconv here:
http://cvs.savannah.gnu.org/viewvc/libiconv/?root=libiconv
Mr. Zlatkovic maintains the windows port of GNU libiconv for libxml2
you can see them here:
ftp://xmlsoft.org/libxml2/win32/iconv-1.9.2.win32.zip
I cannot use his port. I need to build from the latest version of libiconv-1.13. I wonder how this guy has ported it? Can some one please tell me how to build *.lib from this and compile it using MSVC?
EDIT:
Actually, I need to build few more gnu libraries with same settings. So, if I get solution for one library. I can do the same for all others.
I found PARK Youngho's How to Build libiconv with Microsoft Visual Studio over at The Code Project to be complete and clean (for VS2010 and GNU libiconv 1.14).
A little addition to your answer.
I had the same issue and found that the MinGW + MSYS solution was perfect.
Though, I needed to go a little further and generate also the .lib file in order to be able to link with the resulting dll.
This is what I found:
generate a .def file from the dll with dumpbin (a Visual Studio tool).
generate the .lib file from the .def with the lib program (Visual Studio tool too)
This allows you to specify some link flags if appropriate.
Everything detailed here (I'm not the author of this method):
http://wiki.videolan.org/GenerateLibFromDll
I also realized that this lib/dll couple can be linked with both MD and MDd libraries.
Hope that can help people that find this post, like it helped me.
-David
I'm the OP. MSYS is the exact thing what I was looking for.
Just install MinGW & MSYS which contains shell sh.exe & make.exewith which you can configure and generate a Makefile after that you can use make.exe to run it.
Its as simple as that.
compile them using MinGW using Msys for the environment if needed. MinGW's .a files are apparently, according to the mailing list, the same format as .lib files (just do a rename). You might want to check first to see if the iconv static library is included already in the MinGW download / filesystem.
Edit: it's in msys (C:\msys\1.0\lib), along with:
libiconv.a
libiconv.dll.a
libiconv.la
and additionally
libiconv-2.dll (in C:\msys\1.0\local\bin)
Edit: is it in here, the libiconv you need? these versions seem to have MSVC makefiles :) http://www.opensource.apple.com/source/libiconv/

Resources