--enable-static vs --disable-shared - libraries

I understand the importance of shared vs static libraries. However, several programs I have come across recommend compiling with
--enable-static
while other recommend
--disable-shared
Are these the same thing? And if not, what is the difference?
If possible, please give an example of when to use one as opposed to the other.

In the common case that these are switches to a "configure" script generated by Autoconf and Libtool, then they officially mean closely-related, but different, things. --enable-static means do build static libraries; --disable-shared means don't build shared libraries.
If you want to be sure to get only static libraries, no matter what, you need to give both options. However, often just --disable-shared will have that effect, because think about the possibilities: if the package builds only static libraries by default, then --disable-shared is a no-op; if it builds both static and shared libraries by default, then you just have to turn off the shared libraries to get what you want; and if it builds only shared libraries by default, then you might think you need both options, but if you just say --disable-shared, Libtool will usually notice that it's now being asked to build nothing, assume that that couldn't possibly be what you wanted, and flip the --enable-static switch for you.

Related

How to use meson to build glib

I need to upgrade glib for a specific project. It currently uses glib 2.28.8. I have three problems.
I've never used meson and ninja before, so I checked glib's INSTALL.in and it just said to run meson _build followed by ninja -C _build. So I ran meson _build and got the following output:
$ meson _build
The Meson build system
Version: 0.47.2
Source dir: /srv/devel/build/glib-2.65.0
Build dir: /srv/devel/build/glib-2.65.0/_build
Build type: native build
meson.build:227: WARNING: Identifier 'in' will become a reserved keyword in a future release. Please rename it.
meson.build:227:14: ERROR: Expecting eol got id.
if vs_crt_opt in ['mdd', 'mtd']
So the basic build doesn't work. Why?
For our purposes, we use the following configure command:
PKG_CONFIG_PATH=$(OUTPUT_DIR)/lib/pkgconfig ./configure --prefix=$(OUTPUT_DIR) --disable-dtrace --disable-selinux ac_cv_path_MSGFMT=/bin/true CPPFLAGS="-fPIC -I$(OUTPUT_DIR)/include" LDFLAGS="-L$(OUTPUT_DIR)/lib" --enable-static --disable-shared
How do I specify that in meson?
I will also need to build in Windows. Any gotchas there?
Thanks!
EDIT: I tried older versions of glib, going back to 2.62.0 and when I run meson _build I get the error meson.build:1:0: ERROR: Meson version is 0.47.2 but project requires >= 0.49.2.. So that's probably a big part of the problem for question (1). This is running on CentOS 6 & 7, so I'll probably have to get and install a current meson package.
So the basic build doesn't work. Why?
You correctly figured this out in your edit: GLib 2.64 requires Meson 0.49.2, and it seems that Meson 0.47.2 is so old as to not be able to correctly parse GLib’s meson.build.
It looks from your build output that you’re trying to build GLib 2.65.0. Note that 2.65 is an unstable release series. Even minor versions of GLib (2.62.x, 2.64.x, etc.) are stable; odd ones are unstable. Using an unstable release is fine, as long as you know what you’ve signed up for: it may contain bugs, and new APIs introduced in that unstable series may change or be removed before the first stable release (in the case of 2.65.x, the corresponding first stable release will be 2.66.0).
For our purposes, we use the following configure command:
You’ll want something like:
meson --prefix "$(OUTPUT_DIR)" -Dselinux=disabled -Ddefault_library=static _build
You can see from the b_staticpic option’s default value that -fPIC is the default for static libraries, so (I believe) doesn’t need to be explicitly specified.
There should be no need to disable dtrace support since it’s disabled by default. If you did need to disable it, you’d do that with -Ddtrace=false.
The custom -L and -I arguments should be covered by use of --prefix.
Overriding the msgfmt tool to disable internationalisation is not a supported way of building GLib and you’re on your own with that one.
There is some good documentation on the built-in options in Meson here and here.
I will also need to build in Windows. Any gotchas there?
That’s too broad a question to be answered on StackOverflow.

clang/llvm compile fatal error: 'cstdarg' file not found

Trying to convert a large gcc/makefile project into clang. Got it roughly working for x86, but now I'm trying to get cross compilation working.
The way it currently works is that we use Linaro's 7.1.1 arm compiler alongside its companion sysroot directory for base libraries/headers. I installed clang-6.0 and then the base clang(not sure if that mattered).
I used some commands I found to redirect clang to clang-6.0 and when I execute 'clang -v' and got
clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
....
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/9
....
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.5.0
....
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0
Candidate multilib: .;#m64
Selected multilib: .;#m64
It does not find the current compiler we use which is at
/usr/local/gcc-linaro-7.1.1-2017.08-i686_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++(also a directory for *x86_64*)
I only found references to setting --sysroot, but not to a specific compiler. Definitely still lost about the relationship between clang+llvm+other compilers. I even saw somewhere saying I needed to compile llvm before I could use it?
I very roughly made changes in our make files to get the following output, basically all I had to add was '-target arm-linux-gnueabuhf' and reordered the mcpu/mfloat/marm/march so they came after -target in case it mattered
clang --sysroot=/usr/local/sysroot-glibc-linaro-2.25-2017.08-arm-linux-gnueabihf -c -std=c++0x
-g -DDEBUG_ON -target arm-linux-gnueabihf -mcpu=cortex-a7 -mfloat-abi=hard -marm -march=armv7ve
-Wall -fexceptions -fdiagnostics-show-option -Werror .... -I/usr/local/gcc-linaro-7.1.1-2017.08-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/include .... and many more
I think the problem probably lies with the change I made which is the actual 'clang' call that replaced
/usr/local/gcc-linaro-7.1.1-2017.08-i686_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ ....
End up with
fatal error: 'cstdarg' file not found
#include <cstdarg>
As said before I can already cross-compile with gcc, so I've already come across issues with std libraries that require 'build-essentials', 'g++-multilibs', etc. So they're already installed.
Looked and really haven't found anything too useful to me, I'm on linux mint 18.3 and the closest things I found were issues people had on mac and windows.
So I came across some posts mentioning setting --gcc-toolchain=/your/choice/of/cross/compiler but they also mention it not working. I discovered that if you combine this with the installation of llvm-6.0-dev(or maybe llvm-6.0-tools, tools installed dev so not 100%) it at least worked for me.
Any compiler clang or gcc needs to know where a header file is defined. The standard headers, standard libraries, c-runtime, and libc are all packaged together for each target e.g., arm64, x86 in a directory called 'sysroot'. When we compile a program we need to pass the path to sysroot for a compiler to know where to look for standard headers during compilation, and where to look for common libraries (libc, libstdc++ etc) during linkage.
Normally when we compile a program for the same machine the compiler uses the standard headers available in '/usr/include' and libraries from '/usr/lib'. When cross-compiling programs we should supply the sysroot as compiler flag. e.g. gcc --sysroot="/path/to/arm64/sysroot/usr" test.cpp. Same for clang. Most often pre-packaged cross compilers come with a script/binary that has 'sysroot' path embedded into it. e.g., aarch64-linux-gnu-gcc (https://packages.ubuntu.com/xenial/devel/gcc-aarch64-linux-gnu).
... the closest things I found were issues people had on mac and windows.
On mac the clang compiler will have the similar configuration as linux. So the details you found there should be totally applicable to yours.
More details on sysroot and cross-compilation:
https://elinux.org/images/1/15/Anatomy_of_Cross-Compilation_Toolchains.pdf

run configure to generate shared libraries [Ubuntu]

I'm running a ./configure script and make to build a library. However, only .a libraries are generated. Is there an option to generate shared libs?
It's going to depend on the project you're trying to build. Run
./configure --help
to get a list of all options you can pass to ./configure, there may be a --shared option or something similar.

How to prepend CMAKE_INSTALL_PREFIX when its provided at build-time?

I have a few libraries that I build in succession. Some depend on others. For example:
libfoo.so depends on libbar.so
And, I don't want to have to deploy these things system-wide on the build machine. In my cmake file I have something like the following:
find_library(FOO_LIB foo /usr/lib64 /usr/lib /usr/local/lib)
On the build machine I normally give it a CMAKE_INSTALL_PREFIX flag at compile-time. Is there a way to do something like this:
find_library(FOO_LIB foo ${CMAKE_INSTALL_PREFIX}/lib /usr/lib64 /usr/lib /usr/local/lib)
if the flag is provided, but use the first version if it isn't provided?
please forgive my noobish-ness with respect to cmake
[clarification] Each library is built by a separate CMakeLists.txt file.
If you have one cmake-project which include other cmake-projects (with your libraries and applications), you can use target names to link libraries: target_link_libraries(app foo bar)
If you build your libraries cmake project separately - it's not good way, I think, but you still have two options:
deploy your libraries before build app;
put already built libraries to third_party catalog and find it them (e.g. writing specific FindXXXX.cmake file which try to locate your libraries in third_party catalog first).

I want to know how to make a makefile for iOS "fat" library

I want to create a (non-xcode) makefile to create a fat library (emulator + device(s)) that can be imported into an XCode project using a makefile that calls the basic command line tools directly (not running XCODE from the command line, but the MAC Gcc and it's related utilities) - this is for .m, .mm, .c, and .cpp source files.
Ideal would be to find an example that works for a simple library (not by calling a makefile generator that makes an almost non human readable makefile)
anyway anyone know of such a thing or appropriate mechanism for doing the same?
Also an ability to extract the complier flags from an XCode project would be real handy :)
The purpose is I want to add a module to my cross platform libraries so I can integrate them into an iOS project.
Thanks!!
You can extract the compiler flags by viewing the build details or, more simply, running xcodebuild from the command line.
To create a fat binary, you either take advantage of the compiler toolchain's built-in support on the Mac OS X platform by passing multiple -arch arguments, like so:
clang -arch i386 -arch x86_64 -framework Foundation simple.m -o simple
Alternatively, you build the binary once for each desired architecture, then wrap all those binaries into a single fat binary using lipo. This is handy when working with ported Unix software; just change the build result directory each time, then smash them all together after building with lipo. Assuming you have simple-i386 and simple-x86_64, you would then do:
lipo simple-i386 simple-x86_64 -create -output simple
This would create a fat binary named simple containing simple-i386 and simple-x86_64.
Ok - I found this which is a great HOWTO o building a fat library using XCODE that outlines the process and how to create the projects
http://blog.boreal-kiss.net/2011/03/15/how-to-create-universal-static-libraries-on-xcode-4/
being a newbie to XCode and iOS development I had to discover a few things.
you can view the actual command line output of a build to see what the gcc flags are.
View->Navigators->Log - then control click on the messages list to "expand all Transcripts"
to see what stdout and stderr from the chosen build's build output.
You can execute an "external build tool" with your .bashrc and .bash_profile environment settings by making the command and arguments a login shell: "bash --login -c 'mybuildtool [my tools args] $(ACTION)', and thus bypass having to deal with the hard to maintain MacOSX launchd settings etc. this works for things like using ruby and rake as well as make etc.

Resources