How to compile C Linux libraries for use in Windows? - c

I have a C program written on linux that I would like to be able to run and develop on window. The program has a few external dependencies on posix/linux libraries so I'm guessing I would need to somehow compile those libraries under windows too. I'm quite new to the linux workflow, and no expert in C and it's compiler make up either. I know something like cygwin and/or msys2 and/or mingw-w64 might be what I need but I'm not really sure how to get it working in a way that would make sense for me.
My program looks like this (only relevant parts shown), and currently runs under my ubuntu linux VM:
// Build:
// gcc -o disc-identifier main.c `pkg-config --cflags --libs glib-2.0 libmirage libisofs-1`
//
// Run:
// disc-identifier test_image.nrg
#include <glib.h>
#include <mirage/mirage.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <libisofs.h>
...
int main (int argc, char **argv)
{
...
}
My ideal goal is to be able to have this as a visual studio project that I can add to a solution and to be able to link the required dependencies (and compile) from within visual studio. I then want it to compile into a portable 32-bit x86 application (maybe with a few accompanying dll files), no bigger than a few MB. But from my understanding I would first need windows compatible versions of the used libraries (glib, libmirage, libisofs), which is where I am a bit lost as to how I would go about this.

I'm really not an expert of cross-platform development but I already build a cross-platform game (made with Irrlicht) mostly developped on Linux.
Have you heard or maybe already build your project with CMake ?
If not, I really invite you to check this very powerfull tool that CMake is.
Without entering in the details, CMake is a tool for cross-platform development that take care of many things and deliver to you ready-to-use build solutions, including for examples: Makefiles and Visual Studio solution files.
With little setups, you should be able to generate a .sln file for Visual Studio already ready to build your project for you (or require additional setups such as paths or DLL).
Sorry in advance if I misunderstand you question or if I'm not thorough technically.
Please let me know if you want for me to expand my answer ;)

Yes, you are right - if the libraries are not "header-only" you need a platform specific build. But this is really easy right now. For this purpose I can recommend vcpkg.
It supports msbuild and cmake integration - really nice.
To install for example glib you only need to open a cmd in your vcpkg folder and enter
vcpkg install glib
Visual studio supports both "msbuild" and "cmake" very well. Another option is to add dependencies via "NuGet" directly in Visual Studio.
If you use those tools, you don't need to compile the libraries yourself.
But what you have to check is if all your libraries support Windows. If not you can develop with Visual Studio and need to debug with "Remote Debugging". The easiest way is to use Windows Subsystem For Linux (WSL).

Related

How to configure vim for embedded programming?

I was wondering how to configure vim for embedded programming? Precisely, how to "replace" Atmel studio with vim (I do not want to install Atmel studio with wine)?
Imagine we have only a single main.c file, ALE says that these files cannot be found:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main() {
// nothing special
}
And of course it does not compile as compiler can't find those header files.
I think I installed all the necessary libraries. Maybe there is some problem with the path? How do I configure the path?
Actually Vim can replace any IDE regardless of type of programming, it doesn't matter whether it is embedded for AVR, embedded for ARM, C/C++, python, Java...
Vim is just a powerful text editor, so it is not its problem that You cannot compile your project for AVR. It is not the case of Vim. What kind of build system do You use? Is it Make or something else? Or maybe You don't use any of these and You compile straight from command line?
Provide us with more information :)
I was trying to compile main.c with gcc, but then I compiled it with avr-gcc instead. Warnings of "file not found" didn't go away, but it compiled successfully.

gtk.h missing in Visual Studio for Linux Development

I'm currently trying to write an app for Raspberry Pi 3B under Rasbpian with aid of Linux Development plugin in Visual Studio 2017 Community. I managed to successfully deploy 'Blink' example, nobly attached by Microsoft folks, according to tutorial, and that went well. I even made some transmission over SPI thanks to wiringPi library. Then I would like to add some GUI to my app, so that one could, for example, make some transmission on click of a button on screen.
IntelliSense hinted me, that, in fact, there is gtk-3.0 library present in toolset. It seems that libraries are being copied from target device on every connection or so and I installed gtk on my Raspberry. So I added a simple line to this Blink example:
#include <gtk-3.0/gtk/gtk.h>
On compilation attempt, of course there was nearly 4k errors. Well, enough said, with a little hint from this old tutorial and a bit of trial and error, I managed to add this set of links under Debugging/Project properties/Configuration properties/VC++ directories/Header files directories:
Everything goes in promising direction, as errors number diminished from 4k to just one:
gtk-3.0\gtk\gtk.h: No such file or directory
No matter that this file is ACTUALLY in this location:
Regardless of combination of links in configuration above and using statement composition, compiler (?) can't find this damn file.
Please Halp
EDIT
I just confirmed, that it is indeed problem with target configuration. This is bad or good, depending on point of view. Good, because there is probably all good with VS setup. Bad, because I don't know a thing about compiling things under Linux.
On target (Raspberry Pi 3B) all ingredients for compilation are copied by Linux Development plugin. So in Terminal I executed line:
g++ main.cpp -o Blink2onRPi
and got
main.cpp:4:21: fatal error: gtk/gtk.h: no such file or directory
Now, I altered include line in main.cpp on target RPi, to this:
#include <gtk-3.0/gtk/gtk.h>
And now its missing <gdk/gdk.h>! When this change is made on host windows device - same result, but in VS.
As I dealt with similar problem in VS, upon setting links for IntelliSense (now apparently they're for this purpose), now probably similar dependencies have to be set somewhere on Raspbian. But where?
EDIT2
Upon execution of:
g++ main.cpp -o Blink2onRPi `pkg-config --cflags --libs gtk+-3.0`
on target RPi there is no more GTK-related errors, just wiringPi (also present in project) undefined references. It raises two possible questions:
1) How can I setup wiringPi on RPi so that the project could be manually compiled on target and
2) How/where add above line to Visual Studio, so it execute remotely with all GTK dependencies added properly on target
Researching stock present wiringPi library (as this is Blink led example for cross-compile Linux Development) I've found, that in Project Properties/Linker/Input/Library Dependencies there is mysterious entry:
wiringPi
Just that, nothing more. After removing this entry, on compilation pops out same errors as before on target (which apparently lacks proper wiringPi setup) - undefined references (not mensioned any missing headers). Can this be relevant for the case? If so, how could I add there such entry which would deal with missing GTK dependencies?
TL;DR
Use screenshot below to know where to add pkg-config calls in VS configuration so that it forwards it to the compiler and linker on the target.
Thanks to #zaguoba for providing these.
ORIGINAL ANSWER:
The list of directories to include is provided by pkg-config. For example pkg-config --cflags-only-I gtk+-3.0 will give you the list of include directories required. Those are the ones you need to add to the directories where VC++ wil look at include files. If you add the relative path you use in the #include, to one of those paths, you are able to find the file.
Example:
If you add to the directories C:\Program Files\foo\bar\gtk+-3.0
and have in your C file:
#include <gtk/gtk.h>
then the compiler will look for C:\Program Files\foo\bar\gtk+-3.0\gtk\gtk.h.
EDIT:
This all means the 'file not found' errors are because you're really building on the target and the target has no idea what C:\Program Files\... means. Those should be paths on the target filesystem, where the compiler is called. And this is exactly what pkg-config provides.
The copy of those files on the Windows machine filesystems is merely for Intellisense use, not for compiler use.
EDIT 2:
So that's that Visual Studio 2017 Community Linux Development plugin is what need to be undestood. It's not for cross compilation from Windows to Linux, istead it merely synchronizes code to the Windows host (for Intellisense use), but builds on the target. This means that all the paths and commands are Linux paths and commands, run on the target.
Here's the OP working configuration:
With that setup, you should
#include <gtk\gtk.h>
instead of
#include <gtk-3.0\gtk\gtk.h>
Alternatively remove all those VC++ directories/Header files directories, and just keep one of them that ends with include/ instead of listing up all the sub directiores.

Using fork() with VS 2013 and Cygwin

I am trying to write a C program that will use fork() and wait() in Visual Studio 2013. I have downloaded and installed Cygwin, but I am unable to configure Visual Studio to use the appropriate header files. I'm fairly new to the IDE and I was wondering if this community could help me figure out where I am making a mistake.
When starting a new project, this is what I do:
Create new Visual C++ Win32 Console Application
Add new main.c source file to the project
Right-click project properties and configure Include Directories to
include the Cygwin directory: C:\cygwin64
I've taken a screenshot of where I am trying to configure the properties in case this is where I am making my mistake:
My code is rather simple as I am just trying to get it to run at this point:
#include <unistd.h>
int main() {
int i;
i = fork();
if (i == 0) {
printf("I am the child.");
}
else {
wait(&i);
}
}
Here's a screenshot of the error message I receive when I try to build my project:
I apologize in advance if this is a silly question, but I do appreciate any help that you can offer. If there is anything that I can do on my end to help troubleshoot, please let me know.
The problem is that your current include path C:\cygwin64\bin is equivalent to unix /bin, which is for binaries (aka executables). To use unix headers, you need to use the equivalent of /usr/include, which, for your system, should be C:\cygwin64\usr\include.
Using fork() within a Win32 Console application is not going to work. It's a Unix system call. Cygwin is an emulation of the Linux environment that runs on top of Win32.
As others have said you need to be using the Cygwin toolchain to do your compile and builds.
There may be third party libraries to allow Visual Studio to cross-compile for Cygwin, but a Win32 console application is definitely not what you want if you re making Unix system calls.
Ok, there are lots of pieces here to do this, and there are also a lot of answers here with incorrect information.
First, as some have said, you need to modify your include path to contain your include folder from Cygwin, from your install that appears to be C:\Cygwin64\usr\include.
Next, there is an FAQ on this very thing on the Cygwin site. How do I use cygwin1.dll with Visual Studio or MinGW?
From the page:
Use the impdef program to generate a .def file for the cygwin1.dll (if
you build the cygwin dll from source, you will already have a def
file)
impdef cygwin1.dll > cygwin1.def
Use the MS VS linker (lib) to generate an import library
lib /def=cygwin1.def /out=cygwin1.lib
Create a file "my_crt0.c" with the following contents
#include <sys/cygwin.h>
#include <stdlib.h>
typedef int (*MainFunc) (int argc, char *argv[], char **env);
void my_crt0 (MainFunc f) {
cygwin_crt0(f);
}
Use gcc in a Cygwin prompt to build my_crt0.c into a DLL (e.g. my_crt0.dll).
Follow steps 1 and 2 to generate .def and .lib files for the DLL.
Download crt0.c from the cygwin website and include it in your
sources. Modify it to call my_crt0() instead of cygwin_crt0().
Build your object files using the MS VC compiler cl.
Link your object files, cygwin1.lib, and my_crt0.lib (or whatever you
called it) into the executable.
Note that if you are using any other Cygwin based libraries that you
will probably need to build them as DLLs using gcc and then generate
import libraries for the MS VC linker.

How do I link libraries in Xcode 4?

I'm a complete beginner to Apple's Xcode, but I have followed the Xcode documentation and the advice of a few related questions without success.
I installed GMP to /usr/local/bin, wrote a short program using the library, and compiled with gcc main.c -lgmp. It compiled with no warnings or errors, and the executable worked flawlessly.
I started a new Xcode project (Command Line Tool; Type: C), copied the code to the newly created main.c, and opened the project build settings. From there I set Linking > Other Linker Flags to -lgmp and Search Paths > Library Search Paths to /usr/local/bin. However, the build fails with the preprocessor error "Gmp.h: No such file or directory".
I have tried almost every header imaginable:
#include "gmp.h"
#include <gmp.h>
#include "gmp"
#include "libgmp.a" . . .
This has been my main obstacle over the last three months which has prevented me from learning C. Any help leading me to an eventual solution would be greatly appreciated.
There's a few things you have to set up in your Xcode project. For example, I have gmp installed in /opt/gmp/5.0.2 and I will use that as an example. The actual library is installed into /opt/gmp/5.0.2/lib and the header files into /opt/gmp/5.0.2/include. When installing the library setting the --PREFIX flag to /opt/gmp/5.0.2 would handle this automatically. If you don't set this flag the prefix is usually set to /usr/local by default.
The Other Linker Flags looks right, it should be the name of the library.
Set the Header Search Path to the include directory, in my case /opt/gmp/5.0.2/include.
Set the Library Search Path to the lib directory, in my case /opt/gmp/5.0.2/lib.
Since the header search path has been set, you should now be able to include the header file like this:
#include <gmp.h>
Of course, replace /opt/gmp/5.0.2 with the PREFIX path you used when you installed gmp.
Lastly, you typically don't install libraries to /usr/local/bin, you would install to /usr/localand let any binaries be installed into bin while libraries like these would be installed into lib. Of course any path scheme would work, I usually recommend /opt/<project-name>/<version-number> since it allows me to keep better track of what I have installed and have multiple versions of the same libraries and tools without having to deal with collisions.
I have updated my system from snow leopard to mountain lion and had to install gmp.
First of all I have installed Xcode CommandLineTools set.
Secondly, installed Homebrew. Then with it I have done steps in this topic: https://apple.stackexchange.com/questions/38222/how-do-i-install-gcc-via-homebrew
In my last step, made changes to an xcode project as colleague Marcus Karlsson told.
It's finally working! Very big Thank You :)

How to compile a C program?

I haven't done C in a long time. I'd like to compile this program, but I have no idea how to proceed. It seems like the makefile refers to GCC a lot and I've never used GCC.
I just want an executable that will run on windows.
You may need to install either cygwin or mingw, which are UNIX-like environments for Windows.
http://www.mingw.org/
http://www.cygwin.com/
When downloading/installing either cygwin or mingw, you will have the option of downloading and installing some optional features; you will need the following:
gcc (try version 2.x first, not 3.x)
binutils
GNU make (or gmake)
If it requires gcc and you want it to run on Windows, you could download Cygwin.
That's basically an emulator for GNU/Linux type stuff for Windows. It works with an emulation DLL.
http://www.cygwin.com/
In order to compile this program you need a C compiler. It does not have to be gcc, although you are already given a makefile set up to use gcc. The simplest thing for you to do would be the following:
Install cygwin
Open the cygwin command prompt
go into the directory where you have your makefile
type 'make'
That should compile your program
If you are not comfortable with using command line tools then you can download the free version of MS Visual Studio and import the source files into a new Visual Studio project. This way you would not need to install cygwin and use gcc, but you would need to know how to create projects and run programs in Visual Studio.
You almost certainly don't need all of cygwin to compile using gcc. There are plenty of standalone gcc clones for Windows, like gcw.
If it's reasonably portable C code (I haven't looked at it), then you may be able to just ignore the included Makefile and feed the source into whatever compiler you do want to use. What happens when you try that?
Dev-C++ provides a simple but nice IDE which uses the Mingw gcc compiler and provides Makefile support. Here are the steps I used to build the above code using Dev-C++ (i.e. this is a "how-to")
After downloading the source zip from NIST, I
downloaded and installed the Dev-C++ 5 beta 9 release
created a new empty project
added all the .c files from sts-2.0\src
Then under Project Options
added -lm in the Linker column under Parameters
added sts-2.0\include to the Include Directories in Directories
set the Executable and Object directories to the obj directory under the Build Options
and then hit OK to close the dialog. Go to Execute > Compile and let it whirl. A minute later, you can find the executable in the sts-2.0\obj directory.
First, there is little chance that a program with only makefiles will build with visual studio, if only because visual studio is not a good C compiler from a standard POV (the math functions in particular are very poorly supported on MS compilers). It may be possible, but it won't be easy, specially if you are not familiar with C. You should really stick to the makefiles instead of trying to import the code in your own IDE - this kind of scienfitic code is clearly meant to be compiled from the command line. It is a test suite, so trying things randomly is NOT a good idea.
You should use mingw + msys to install it: mingw will give you the compilers (gcc, etc...) and msys the shell for the make file to run correctly. Contrary to one other poster, I would advise you against using gcc 2 - I don't see any point in that. I routinely use gcc 3 (and even 4) on windows to build scientific code, it works well when the code is unix-like (which is the standard platform for this kind of code).

Resources