passing CC/CFLAGS/LDFLAGS from Makefile to ./configure of Tk/Tcl - macos

I'm trying to compile one library (xcrysden, based on Make file) which during its compilation execute ./configure of an external dependencies - Tk and Tcl 8.5 - and compiles them.
So, the structure is roughly like this:
The main Makefile:
...
cd external/src; make;
external dependencies (pre-)makefile (Tk):
include ../Make.sys
cd /unix
./configure
make
make install
Make.sys included by external makefile:
...
CFLAGS =...
CC =...
The configure, obviously, produces another makefile in /external/src/unix to be used by Tk.
In Tk documentation it is written:
If you wish to specify a particular compiler, set the CC environment variable before calling configure. You can also specify CFLAGS prior to configure and they will be used during compilation.
But from the resulting Makefile i definitely see that neither the defined compiler (CC) nor flags (CFLAGS) are used. Does it qualify as 'environment variable' when it is set in another make file?
I actually have problems compiling Tk, so i try to pass not only compiler but linking info
LDFLAGS = -L/opt/local/lib -lfontconfig .
I want to do it in a neat way (that is, modifying only Make.sys of the library dependent on Tk). But then i face the problem that not only don't i know how to pass LDFLAGS to Tk configure, but even CC/CFLAGS are not there. I'm not sure if this is specific to particular library (Tk) using ./configure or I misunderstand the general usage of ./configure.
p/s/ i'm compiling on OS-X using gnu compilers.

The problem is that the variables you define in ../Make.sys are currently local to the shell that processes the include; the configure and make are run in subprocesses and don't find out that you've got any preferences. The right thing to do is to add:
export CFLAGS CC
between the include and the call to ./configure.
You could also put it inside Make.sys, or invoke configure as CFLAGS=$CFLAGS CC=$CC ./configure. You probably shouldn't set the values directly in the invocation of make though; setting the compiler can mean that different other flags are required as well.

Related

Configure compilation options and compiler autoconf

I'm working on a personal project with Rust and tcl but i still want to use the classic makefile structure.
I know that to compile multifile I just need to declare mod second on main.rs and rustc automatically connect the modules. So I use
$ rustc main.rs -o output -C debuginfo=2
Now I tried to integrate autoconf and automake because I want to make a configure script to check for tcl, rustup etc... But I don't know how to edit to compile with rustc and its options insead of cc and c options (like trying a .o that doesn't compile because they don't have a main function).
for the configure.ac i used:
AC_CONFIG_SRCDIR([source/main.rs])
AC_CONFIG_AUX_DIR(config)
# I manually checked for rustup and tclsh
AM_INIT_AUTOMAKE
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
for the Makefile.am:
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = output
SUBDIRS = sources
output_SOURCES = sources/main.rs
I have the main directory with configure.ac and Makefile.am and the sources directory with all the stuff (and also the config directory for autoconf)
Now I tried to integrate autoconf and automake because I want to make a configure script to check for tcl, rustup etc...
The configure script is the responsibility of Autoconf. It is not obligatory to use Automake together with Autoconf, and you should consider whether it would be sensible for you to use Autoconf alone. That would give you complete control over the generated Makefile, as you would write a Makefile.in directly instead of relying on Automake to do that for you. Presumably, you would write a much simpler Makefile.in than Automake generates, and that's fine.
Automake is not necessarily out of the question, but its manual has this to say about language support:
Automake currently only includes full support for C, C++ (see C++
Support), Objective C (see Objective C Support), Objective C++ (see
Objective C++ Support), Fortran 77 (see Fortran 77 Support), Fortran
9x (see Fortran 9x Support), and Java (see Java Support with gcj).
There is only rudimentary support for other languages, support for
which will be improved based on user demand.
Some limited support for adding your own languages is available via
the suffix rule handling (see Suffixes).
The referenced section about suffix rules shows how you might use such a rule to teach Automake how to build Rust programs. It might look something like this:
.rs:
$(RUSTC) $< -o $# $(AM_RUSTFLAGS) $(RUSTFLAGS)
SUFFIXES = .rs
That assumes that configure will identify the Rust compiler and export its name as RUSTC. AM_RUSTFLAGS is for defining compilation flags internally in your project (typically in your Makefile.am), and RUSTFLAGS is for the builder to add or override compilation flags at build time.
But since the compiler does not produce intermediate object files (or so I gather), I would expect that defining sources in output_SOURCES would not yield a working Makefile, and that you would probably need the name of the top-level Rust source to match the name of the wanted binary (i.e. output.rs instead of main.rs). The single-suffix rule should, then, get your binary built without any sources being explicitly specified. You would also want to name all contributing Rust sources in the EXTRA_SOURCES variable, else they would be omitted from distribution packages built via make dist.
Note, too, that the above does not define all the build dependencies that actually exist if you're building multifile programs. I would suggest doing that by adding an appropriate prerequisite-only rule, such as
output: $(output_extra_sources)
(with no recipe) in multifile cases. This will ensure that make will recognize when output needs to be rebuilt as a result of a modification to one of its sources other than output.rs.

automake: distcheck with CPPFLAGS

I am looking for something like DISTCHECK_CONFIGURE_FLAGS but more flexible.
I am using an external package in my program. Let's say foo and on my laptop it's installed to ${HOME}/soft/foo.
configuring with the autotools is simple:
./configure CPPFLAGS=-I${HOME}/soft/foo/include LDFLAGS=-L${HOME}/soft/foo/lib
but distcheck is giving me headaches. When distcheck unpacks and configures, how do I tell it to use my CPPFLAGS and LDFLAGS?
DISTCHECK_CONFIGURE_FLAGS is close, but incorrect: other maintainers might have the foo library installed under /opt/ or /software/random/whatever or /usr/local/foo-master and I don't want to impose my environment on other maintainers.
The answer is to not hard-code anything in the Makefile.am. Automake will inherit several environment variables from autoconf.
All one needs to do is pass the CPPFLAGS and LDFLAGS used to configure the package:
DISTCHECK_CONFIGURE_FLAGS = CPPFLAGS=${CPPFLAGS} CFLAGS=${CFLAGS}\
${CXXFLAGS}=${CXXFLAGS} LDFLAGS=${LDFLAGS}
and now 'make distcheck' will use the requested flags and find the headers and libraries for the desired package.

GCC and linking environment variables and flags

The following link in the official documentation for GCC:
https://gcc.gnu.org/onlinedocs/gcc/gcc-command-options/environment-variables-affecting-gcc.html
Explains the following environment variables:
LANG
LC_CTYPE
LC_MESSAGES
LC_ALL
TMPDIR
GCC_COMPARE_DEBUG
GCC_EXEC_PREFIX
COMPILER_PATH
LIBRARY_PATH
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
OBJC_INCLUDE_PATH
DEPENDENCIES_OUTPUT
SUNPRO_DEPENDENCIES
But I have also heard/read before about these other compiling flags:
For compiling C code: CC, CFLAGS
For compiling C++ code: CXX, CPPFLAGS
And linking flags:
For the linking stage: LDFLAGS
After the code is compiled: LD_LIBRARY_PATH
What is the meaning of CC, CFLAGS, CXX, and CPPFLAGS? Why aren't they included in the official list of environment variables for gcc?
To begin with, all the variables you mentioned: CC, CFLAGS, CXX, CXXFLAGS, LDFLAGS, LD_LIBRARY_PATH, are originated from Unix OS family. These variables have nothing to do with GCC in the first place, that's why you see no trace of them in the manuals.
The only meaningful variable (which has no direct connection with GCC too) among these is LD_LIBRARY_PATH. You'll probably find this variable to be defined out-of-the-box on any modern Unix-like OS. Here is the the LD.SO(8) man-page from Linux Programmer's Manual which mentions LD_LIBRARY_PATH and its purpose. Here is one more extract:
The LD_LIBRARY_PATH environment variable contains a colon-separated list of directories that are searched by the dynamic linker when looking for a shared library to load.
The directories are searched in the order they are mentioned in.
If not specified, the linker uses the default, which is /lib:/usr/lib:/usr/local/lib.
As you can see LD_LIBRARY_PATH is nothing but an OS-specific environment variable for proper loading of shared libraries. Windows has similar environment variable in this regard: PATH. Windows will scan directories listed in it when searching for dynamic-link library (DLL, a counterpart of SO on Linux) too.
Concerning the rest of the variables (CC, CFLAGS, CXX, CXXFLAGS, LDFLAGS), you see them so often due to the historical reasons. Since the rise of Unix era, software projects were built using Make (scroll down and look at the examples of typical makefiles) — one of the pioneering build tools. These variables were so extensively used in makefiles that eventually they became sort of a convention (see Implicit Rules, for instance). That's why you can even see them defined out-of-the-box on, for example, Linux, and most likely pointing to GCC (as it is considered to be the native toolchain for Linux).
To conclude, the point is: don't scratch your head over CC, CFLAGS, CXX, CXXFLAGS, LDFLAGS, and friends, as they are just a blast from the past. ;)
BONUS
Using plain old Make directly to build complex software today quickly becomes tedious and error-prone. As a result, numerous sophisticated build system generators like GNU Automake or CMake have been developed. In brief, their goal is to provide (arguably) more readable, easy-to-maintain, and high-level syntax to define an arbitrarily complex build system for an arbitrary software project to be built. Typically, before actually building the project, one has to generate a native build system (which could also be represented by plain old makefiles, for example, for portability reasons, but not necessarily) out of this high-level definition using the corresponding set of tools. Finally, one has to build the project with the tool(s) corresponding to the generated (native) build system (for example, Make in case of plain old makefiles, but not necessarily).
Since you are asking these questions, I suspect that you are about to dive into native software development with C or C++. If so, I would strongly recommend you to pick a modern build system (CMake would be my personal recommendation) in the first place, play with it, and learn it well.
In simple terms CC, CFLAGS, LDFLAGS etc are gnu Makefile variables. If defined, these will be used by implicit rules even without actually being mentioned in commands/rules
You can definitely use environment variable with GCC for CFLAGS and CC (and anything else). You just have to pass the variables to the the compile line, with slight differences depending on the operating system.
Linux set CFLAGS environment variable:
export CFLAGS="-g -Wall -std=c89 -pedantic"
Compile on Linux using CFLAGS
gcc $CFLAGS - o progname progname.c
Windows set CFLAGS environment variable:
set CFLAGS=-g -Wall -std=c89 -pedantic
Compile on Windows using CFLAGS
gcc %CFLAGS% - o progname progname.c
You can even setup a temporary compile string at a variable and call it to compile as you're testing.
set BUILD=gcc -g -Wall -std=c89 -pedantic - o progname progname.c
and call it like...
%BUILD%
One thing to remember when setting and using the variables on Linux (as most programmers know), the variables are case sensitive so $cflags would simply be ignored. On Windows case doesn't matter.
On both systems the above only works until the terminal (or command prompt) session is terminate. To make them permanent you need to set the variables in their respective settings files.

how to add a flag in any make file

I have a program and I want to measure it performance but using gprof.now I want to add a -pg flag in it. I have many different files makefile.am makefile.in configure
I install the program using following steps
./configure
make
make install
Now I have read somewhere that:
automake gererates Makefile.in from Makefile.am
configure generates Makefile from Makefile.in
I am totally confused and want to ask two question
In which file and where do I add -pg flag? In makefile.in or makefile.am as they both have different types of flag options?
If configure generates makefile from makefile.in and automake generates makefile.in from makefile.am then shoud'nt we be using make before ./configure? what the hierarchy?
man gcc:
-pg Generate extra code to write profile information suitable for the
analysis program gprof. You must use this option when compiling
the source files you want data about, and you must also use it when
linking.
It says it needs to be in CPPFLAGS (used for both C and C++ code) and LDFLAGS (unless non-standard variables are used). The standard way is to pass flags to configure script:
$ ./configure CPPFLAGS=-pg LDFLAGS=-pg

Passing a gcc flag through makefile

I am trying to build a pass using llvm and I have finished building llvm and its associated components. However, when I run make after following all the steps to build a pass including the makefile, I get the following
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
After tyring to find a fix by googling the error message, I came to know that this is not specific to llvm. A few solutions suggested that I should use "--enable-shared" while running configure but that didn't help my case. Now I want to re-build llvm using fPIC, as the error says. But how do I do this using the makefile?
Looks like you could add the -fPIC (for position-independent code, something you want for a shared library that could be loaded at any address) by setting shell variables:
export CFLAGS="$CFLAGS -fPIC"
export CXXFLAGS="$CXXFLAGS -fPIC"
Looking at Makefile.rules, these will be picked up and used. Seems strange that it wasn't there to begin with.
EDIT:
Actually, reading more in the makefiles, I found this link to the LLVM Makefile Guide. From Makefile.rules, setting either SHARED_LIBRARY=1 or LOADABLE_MODULE=1 (which implies SHARED_LIBRARY) in Makefile will put -fPIC in the compiler flags.
If you are moderately convinced that you should use '-fPIC' everywhere (or '-m32' or '-m64', which I need more frequently), then you can use the 'trick':
CC="gcc -fPIC" ./configure ...
This assumes a Bourne/Korn/POSIX/Bash shell and sets the environment variable CC to 'gcc -fPIC' before running the configure script. This (usually) ensures that all compilations are done with the specified flags. For setting the correct 'bittiness' of the compilation, this sometimes works better than the various other mechanisms you find - it is hard for a compilation to wriggle around it except by completely ignoring the fact you specified the C compiler to use.
Another option is to pass -fPIC directly to make in the following way:
make CFLAGS='-fPIC' CXXFLAGS='-fPIC'

Resources