Portable way to include malloc_np.h - c

I'm using a third-party library which includes malloc_np.h. From what I found over internet, this means that the code was supposed to compile under FreeBSD, although simply changing the include to malloc.h made it compilable under Linux (Ubuntu 13.10).
Now I'm writing a CMake script for this library to generate appropriate make files (including NMake makefiles for MSVC 2010).
What is the best way to achieve portability in such a scenario?
My current solution is to test for:
${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD"
in the CMake script. Depending on the result I issue a
add_definitions (-DINCLUDE_MALLOC_H="#include <malloc[_np].h>")
command and use this macro in the source file instead of #include <malloc_np.h>.
Is this a good practice?

Generate time
Use CheckIncludeFile* modules:
include(CheckIncludeFileCXX)
check_include_file_cxx("malloc.h" have_malloc)
if(have_malloc)
add_definitions(-DINCLUDE_MALLOC_H)
endif()
Compile time
Use boost.predef library to detect os specific features

Related

How can I make a binary that uses openmp and compiled with intel's C compiler portable?

Normally I compile code (all in a single file main.c) with the intel oneapi command prompt like so
icl.exe main.c -o binary_name
I can then run binary_name.exe without issue from a regular command prompt. However, when I recently exploited openmp multithreading and compiled like so.
icl.exe main.c -o binary_name /Qopenmp /MD /link libiomp5md.lib
Then, when I try to run it through an ordinary command prompt, I get this message:
I'd ultimately like to move this simple code around (say, to another computer with the same OS). Is there some procedure through a command prompt or batch file for packaging and linking a dynamic library? It is also looking like statically linking for openmp is not supported on windows
Either make a statically linked version, or distribute the dependency DLL file(s) along with the EXE file.
You can check the dependencies of your EXE with Dependency Walker.
As you correctly statedk statically linking for OpenMP is not supported on Windows. Depending on your use case you have a couple of options. The simplest one for simple testing is to just ship the Dynamic-Link Library with you executable and place it in the same directory in the target system. Having built a lot of systems using DLLs, this is typically what most developers do to ensure capability with their code in a production environment even.
If you are looking to do something more complex on the target system you can place the Dynamic-Link library in a shared location and follow the search order suggestions from the Microsoft Build site:
https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

Static build of GMP for MSVC (Windows)

Is it possible to build GMP for MSVC on Windows?
I need fully static solution (static library), without any DLL dependencies. So that my final EXE doesn't depend on any external (non-system) DLLs.
I'm alright if building GMP will need Cygwin or MSYS, as far as it can be used later in MSVC without any problems. But as far as I know at least Cygwin builds always depend on extra DLLs like cygwin1.dll which is not affordable for me, fully static-library solution is needed.
I'm aware there exists MPIR library that is more Windows friendly. But right now I need specifically GMP solution if possible.
Of course would be great if all optimizations and assembly is used when building for Windows. But if assembly is not possible then at least non-assembly (generic) variant of GMP is needed.
Of course I need 64-bit version.
If someone can post all steps needed to produce such static library for MSVC usage? Or maybe link some web-site that has such instructions?
I successfully managed to compile a working fully statically linked program with GMP using MSVC under Windows.
For that I used installation of MSYS, which is located in c:/bin/msys/ on my machine.
Then inside MSYS shell installed GMP packages mingw-w64-clang-x86_64-gmp and gmp-devel (pacman -S gmp-devel to install and pacman -Ss gmp to search).
In MSVC compiler I added include directory c:/bin/msys/clang64/include/.
Wrote an example of GMP usage program in C++, that implements Trial Division / Pollard's Rho / Pollard's P-1 factoring algorithms using long arithmetics. This program uses both mpz_...() C routines and mpz_class C++ wrapper class. For example this program is located in main.cpp.
To linker command line I added following libraries:
c:/bin/msys/clang64/lib/libgmp.a
c:/bin/msys/clang64/lib/libgmpxx.a
c:/bin/msys/mingw64/lib/gcc/x86_64-w64-mingw32/10.3.0/libgcc.a
c:/bin/msys/clang64/x86_64-w64-mingw32/lib/libmingwex.a
Also I had to add /FORCE flag (read about it here) to linker command, because libmingwex.a has some symbols overlapping with default MSVC's libraries, precisely without /FORCE I had following errors:
libucrt.lib(strnlen.obj) : error LNK2005: wcsnlen already defined in libmingwex.a(lib64_libmingwex_a-wcsnlen.o)
libucrt.lib(strnlen.obj) : error LNK2005: strnlen already defined in libmingwex.a(lib64_libmingwex_a-strnlen.o)
bin\win-msvc-m-64-release\drafts\gmp_int_msvc.exe : fatal error LNK1169: one or more multiply defined symbols found
All steps produced working (tested) final statically-linked program without any external DLL dependencies (of course except for default system DLLs of Windows).
It means MSYS's libraries .a are fully compatible with MSVC and link successfully in MSVC compilation.
Not to have /FORCE linker flag I also did extra following steps. Made a copy of c:/bin/msys/clang64/x86_64-w64-mingw32/lib/libmingwex.a library. Used c:/bin/msys/clang64/bin/objcopy.exe util, which probably was installed together with Clang. With objcopy renamed overlapping symbols:
objcopy --redefine-sym wcsnlen=msys_wcsnlen libmingwex.a
objcopy --redefine-sym strnlen=msys_strnlen libmingwex.a
which allowed me to successfully use this modified libmingwex.a library to link in MSVC without using /FORCE.

cmake and make build reproductibility

I'm evaluating the use of cmake to generate makefile for embedded FW. The cmakelists.txt will be shared in the team.
Can you confirm the makefile cannot be shared between different computers ?
Is this still true if project path is identical on both computers ?
Using cmake makefile generation and same version of compiler, will the generated binary be the same on all computers ?
Is this the same behavior as a makefile shared in the project ?
Why would you share a generated makefile anyway!? You usually share the cmake files.
Can you confirm the makefile cannot be shared between different computers ?
You should not share the makefile. It's generated only for you and includes local information as well as the cmake (cached) options and state. There's no serious reason to actually do this!
Is this still true if project path is identical on both computers ?
Yes, because cmake maintains a cache of settings, options etc. So the makefile may differ depending on paths, options and states. You also have to guarantee the paths for any dependency.
Using cmake makefile generation and same version of compiler, will the generated binary be the same on all computers ?
If environment (Compiler, libraries, …) and options (build type, project options, …) are same, Cmake will reliable produce exact the same binaries on all systems.
Is this the same behavior as a makefile shared in the project ?
No, CMake is much better: it's cross-platform. It doesn't depend on make, you can use any other system (like ninja or an IDE project) too – without touching your source or cmake code.
CMake does much more than just creating a makefile. You can even compile a CMake based project with several different compiler / cross-compiler without a single change.
TL;DR
Don't share generated Makfiles, share the Cmake sourcefiles instead – that's what CMake is used for.
In theory, if your project path, toolchain path, toolchain version, and the path to every external library used by the project is the same on different computers, then you can move the generated Makefile between them without regenerating. When you run make it might detect that things have changed and try to rerun CMake, though. I'm not sure why you'd want to do this, however, it seems like kind of bad practice.
If the compilers, libraries, and code are the same, the same code will get generated (unless your compiler has some sort of bug).

How can I create and use my own static library in C?

I want to my make own library and have it use the same syntax as the standard C libraries as in
#include<mylib.h>
So that it looks like #include and some of the libraries that are included with C.
Can I make the library static as opposed to linking so that I can compile it in GCC without additional arguments, as if I were using another library like stdio.h or string.h?
This seems simple enough.
Develop the library (create as many source files as you need).
Build the source files into a shared library (.so) using a tool like CMAKE (which i strongly recommend).
Copy that library to your library path (i.e. /usr/lib)
Later on, all you have to do is import your lib: (i) in the source using #include<mylib.h>; (ii) when building (also using CMAKE) or using the flag (-lmylib) in the GCC compiler: gcc -lmylib myfiles.c -o myoutput.
In addition to #include "mylib.h", you need to add -lmylib command line to the compiler (more specifically linker) when using the library. I assume that the your library archive created through ar command is named as libmylib.a.
Usually, we do not write 'manually' build instructions, but we rely on tool that generates build chains. There are quite a lot of them, the most know are probably autotools and cmake (under Linux).
I would suggest you to have a look to cmake examples and/or documentation to get your code built.
There are quite a lot of differences between static and dynamic libs, and you will also need to package somehow your lib if you really want to use it like 'standard' lib (like libxml2, openssl, etc.)
A lot to say about it, but you should first have a look to 'how to build' your lib, and then see how to make it easy to use, IMHO.

How do I install C packages on windows

I have to use LU decompostion to fit a simple model to some data (simulated) in C. An example of what I need to do is here:
However, I'm stuck with a more basic problem: how do I install packages in C and call them in my code?
I'm new in C and I'm used to R. But I have this assingment to do some tests about Matrix inversion, LU decomposision and the professor suggested using Lapack to easy things (thus, I don't need to code myself the LU decomposition etc.). But I don't know how to install the package and call it in my code, in order to use the functions of LAPACK.
I have a windows 7 64 bits and I'm using compiler Code Blocks 8.02
Thanks for any help.
Normally you don't "install" C libraries in that sense. Normally, in Windows you have three types of files. The header files, typically ending in .h, the dynamic library, .dll, and most likely some linker files (typically, .lib, .a or something). The linker and compiler will need to be able to find these files somewhere. Normally you set the include directory paths, and library directory paths.
E.g. Let's say you downloaded a library called foo, and you extract it to C:\foo.
In that folder, libfoo.a, foo.dll and foo.h reside. In Code::Blocks you will have to point include directory path to C:\foo and library path to C:\foo so that the linker and compiler know where to look for these files. Since you're linking against the foo library, you will also have to set -lfoo or something similiar in linker command line. This is GCC syntax, but I think Code::Blocks uses GCC compiler behind the scenes anyways.
In the C code you can just #include <foo.h> and the compiler will find it for you.
You need to install that library and it might actually supply a tool for that. Check their documentation (e.g. a file INSTALL or README in their distributed sources). If the library uses only headers you might only need to copy it's headers to some directory on your system, but their buildsystem might be able to do that for you.
Once that is done you would tell your IDE on where to look for the sources and if the library uses not just headers to link against the actual library file. See the documentation in the Code::Blocks Wiki on how this is done for some example cases and adapt for your library.
The simplest thing to do in your situation is to install Cygwin. You can use the setup.exe installer to install the GCC and the LAPACK libraries. When you want to use the LAPACK library, you will add the -llapack option to your GCC command line.

Resources