Avoiding header collisions when cross compiling - linux

I have a linux project I want to port to windows. Under Linux I did set up my makefile to run x86_64-w64-mingw32-g++ when I do call make ARCH=win
The problem is that some headers I need (tcl.h and friends) are located under '/usr/include' and if I pass that directory with the -I flag I will get a header collision for headers like stdlib.h which obviously are different for windows.
Is there a way around this besides copying the needed tcl headers into another location?

There is a sequentially order the compiler will look for header files. But no you cannot cherry pick the header file location.
A solution that you can try with this problem is using -I/usr and patch your project with the sed utility to convert the required headers like <tcl.h> to <include/tcl.h>. On top of that you can use the preprocessor to avoid patching every time your project.

Related

How to tell SCons to stop computing implicit dependencies in a particular directory?

My SCons project depends on a lot of third party libs, each providing dozens or hundreds of include files.
My understanding of how SCons works is that, on each build, it parses the source files of my project to find the #include directives, and it uses the value of env['CPPPATH'] to find these files and compute their md5 sum.
This scanning is costly, and thus I would like to optimize this process by teaching SCons that all the headers of my third party files will never change. This property is actually enforced by the tool that manages our third party libs.
I know there is a --implicit-deps-unchanged option that forces scons to assume that the implicit dependencies did not change, but it works globally. I did not find a way to restrict this option to a particular directory. I tried to find if the default Scanner of implicit C++ files can be configured, but found nothing. I think it is possible to avoid using CPPPATH, and instead only give the -I option to the compiler directly, but it is cumbersome.
Is there any way to optimize SCons by teaching him that files in a directory will never, ever change?
You can try pre-expanding the list of header file paths into CCFLAGS.
Note that doing so means they will not be scanned.
for i in list_of_third_party_header_directories:
env['CCFLAGS'].append('-I' + i)
In this case the contents of CPPPATH would be your source directories, and not the third-party ones which you assert don't change.
Note that changing the command line of your compile commands in any way (unless the arguments are enclosed in $( $)) will cause your source files to recompile.

automake Adding all c files in a directory

In automake's Makefile.am , the sources of a program is listed like
bin_PROGRAMS = os345v1
os345v1_SOURCES = os345.c os345interrupts.c os345semaphores.c
Instead of specifying individual files, How to add all c files in a specific directory and subdirectory ?
it's usually a bad idea to do use wildcards in automake.
for one thing, your automake project might be processed used with a non-GNU make implementation (which might not be able to use GNU-make extensions such as $(wildcard *.c)).
One of the strengts of autotools/automake is that it is agnostic of the target systems and their tool-chains.
More importantly, automake might need to actually know exactly which source files you want to be build.
This is important for instance when you want to make out-of-source-tree builds (e.g. with the source-code on read-only media, and the builds being "somewhere else): this is a common use-case for distributions (e.g. Debian) that allow to easily build multiple flavours (with different configure flags) from the same source in a single run.
And finally, not using wildcards protects your build against stray source code. E.g. having "foo.c" and a backup-file "foo_old.c" (e.g. because you are re-implementing "foo" and want to have check with the old implementation and want your editor to automatically enable syntax-highlighting) lying around in the same folder, might accidentally build both files resulting in multiple-definitions of the same symbols.
See also the automake documentation why automake does not support wildcards

Can configure generate .h files?

On Linux, when I execute ./configure it generates header files and also .c files (besides Makefiles), right? How can I get configure to do that?
You will probably want to create a configure.ac (but depend on the autoconf version), but read here, to give you an idea what should you create and what is auto generated. It has good covered on the autotools topic.
It's typically used to generate config header, that contains various defines (often libraries & function present or not). But this happens only if autotools were instructed to create configure doing that.
You define what goes to (and to which header exactly) in configure.ac (input file to autotools). See AC_CONFIG_HEADERS, AC_CHECK_HEADER, AC_CHECK_LIB and similar macros. See autoconf manual for details. Also read through complete tutorial jasonw linked. And see how things are done in some existing projects.

How to get a configure script to look for a library

I'm trying to write a configure.ac file such that the resulting configure script searches for a library directory containing a given static library e.g. libsomething.a. How can I do this? At the moment I have it check just one location with:
AC_CHECK_FILE([/usr/local/lib/libsomething.a],[AC_SUBST(libsomething,"-L/usr/local/lib -lsomething")],[AC_SUBST(libcfitsio,'')])
But I want it to try and find it automatically. And if the library isn't in one of the default locations, I'd like configure to say that the library wasn't found and that a custom location can be specified with --use-something=path as is usually done. So I also need to then check if --use-something=path is provided. I'm pretty new at creating configure files, and the M4 documentation isn't very easy to follow, so would appreciate any help.
Thanks!
It's not the job of configure to search where libraries are installed. it should only make sure they are available to the linker. If the user installed them in a different location, he knows how to call ./configure CPPFLAGS=-I/the/location/include LDFLAGS=-L/the/location/lib so that the tools will find the library (this is explained in the --help output of configure and in the standard INSTALL file).
Also --with-package and --enable-package macros are not supposed to be used to specify paths, contrary to what many third-party macros will do. The GNU Coding Standards explicitly prohibit this usage:
Do not use a --with option to
specify the file name to use to find
certain files. That is outside the scope
of what --with options are for.
CPPFLAGS and LDFLAGS are already here to address the problem, so why redevelop and maintain another mechanism?
The best way to figure this out is to look at other autoconf macros that do something similar. Autoconf macros are an amalgam of Bourne shell script and M4 code, so they can literally solve any computable problem.
Here's a link to a macro I wrote for MySQL++ that does this: mysql++.m4.

How to convert a makefile into readable code?

I downloaded a set of source code for a program in a book and I got a makefile.
I am quite new to Linux, and I want to know whether there is any way I can see the actual source code written in C?
Or what exactly am I to do with it?
It sounds like you may not have downloaded the complete source code from the book web site. As mentioned previously, a Makefile is only the instructions for building the source code, and the source code is normally found in additional files with names ending in .c and .h. Perhaps you could look around the book web site for more files to download?
Or, since presumably the book web site is public, let us know which one it is and somebody will be happy to point you in the right direction.
A Makefile does not contain any source itself. It is simply a list of instructions in a special format which specifies what commands should be run, and in what order, to build your program. If you want to see where the source is, your Makefile will likely contain many "filename.c"'s and "filename.h"'s. You can use grep to find all the instances of ".c" and ".h" in the file, which should correspond to the C source and header files in the project. The following command should do the trick:
grep -e '\.[ch]' Makefile
To use the Makefile to build your project, simply typing make should do something reasonable. If that doesn't do what you want, look for unindented lines ending in a colon; these are target names, and represent different arguments you can specify after "make" to build a particular part of your project, or build it in a certain way. For instance, make install, make all, and make debug are common targets.
You probably have GNU Make on your system; much more information on Makefiles can be found here.
It looks like you also need to download the SB-AllSource.zip file. Then use make (with the Makefile that you've already downloaded) to build.

Resources