Q:

Compiling for global variables across multiple files in C to create a shared library

I am building a shared object (.so) file built from C, to be used from R. I am having problems linking/compiling the object with all the source codes, test codes and header files.
This .so file will be loaded using dyn.load() in R and the corresponding functions called.
This is the structure of the files:
C_header_file1.h // some support functions
C_src_file1.h    // some source code for support functions
C_header_file2.h // some other support functions
C_src_file2.h    // some source code for support functions
C_header_testfunctions.h // testing functions that are called from R for testing
C_src_testfunctions.c  // source code for test functions
C_file_with_main_calling_functions.c // main src file which takes functions from header files (not test header file) to do stuff
C_file_with_main_extern_vars.h // has extern global variables

The C_file_with_main_calling_functions.c file has a set of global variables (random number generator specifics) which can be accessed by C_file_with_main_calling_functions.c (when the main functions are called by the user from R) and by C_src_testfunctions.c (when testing functions are called in the testing phase by the user from R).
C_file_with_main_extern_vars.h looks like:
// random number generation set up
extern const gsl_rng *gBaseRand;       // global rand number generator
extern unsigned long randSeed;
extern const double lowest_double = -GSL_DBL_MAX;
extern const double highest_double = GSL_DBL_MAX;
extern FILE *fp = NULL;

Both C_file_with_main_calling_functions.c and C_src_testfunctions.c has #include "C_file_with_main_extern_vars.h". 
How do I create the shared object? It is giving me the following error:
R CMD SHLIB C_file_with_main_calling_functions.c ./../test/C_src_testfunctions.c ./../src/src_file1.c ./../src/src_file2.c ./../src/src_file3.c ./../src/src_file6.c ./../src/src_file5.c -lgsl -lgslcblas
gcc -std=gnu99 -I/usr/local/R.framework/Resources/include -DNDEBUG  -I/sw/include -I/usr/local/include    -fPIC  -g -O2  -c C_file_with_main_calling_functions.c -o C_file_with_main_calling_functions.o
In file included from C_file_with_main_calling_functions.c:35:
/mydir/C/include/C_file_with_main_calling_functions.h:15: warning: 'lowest_double' initialized and declared 'extern'
/mydir/C/include/C_file_with_main_calling_functions.h:16: warning: 'highest_double' initialized and declared 'extern'
/mydir/C/include/C_file_with_main_calling_functions.h:17: warning: 'fp' initialized and declared 'extern'
C_file_with_main_calling_functions.c: In function 'func2':
C_file_with_main_calling_functions.c:54: warning: implicit declaration of function 'func1'
C_file_with_main_calling_functions.c: At top level:
C_file_with_main_calling_functions.c:61: warning: conflicting types for 'func1'
C_file_with_main_calling_functions.c:54: warning: previous implicit declaration of 'func1' was here
C_file_with_main_calling_functions.c: In function 'C_file_with_main_calling_functionsC':
C_file_with_main_calling_functions.c:207: warning: passing argument 1 of 'func2' from incompatible pointer type
C_file_with_main_calling_functions.c:271: warning: passing argument 1 of 'gsl_rng_free' discards qualifiers from pointer target type
gcc -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/sw/lib -L/usr/local/lib -o C_file_with_main_calling_functions.so C_file_with_main_calling_functions.o ./../test/C_src_testfunctions.o ./../src/src_file1.o ./../src/src_file2.o ./../src/src_file3.o ./../src/src_file6.o ./../src/src_file5.o -lgsl -lgslcblas -F/usr/local/R.framework/.. -framework R -lintl -Wl,-framework -Wl,CoreFoundation
duplicate symbol _fp in:
    C_file_with_main_calling_functions.o
    ./../test/C_src_testfunctions.o
duplicate symbol _lowest_double in:
    C_file_with_main_calling_functions.o
    ./../test/C_src_testfunctions.o
duplicate symbol _highest_double in:
    C_file_with_main_calling_functions.o
    ./../test/C_src_testfunctions.o
ld: 3 duplicate symbols for architecture x86_64
collect2: ld returned 1 exit status
make: *** [C_file_with_main_calling_functions.so] Error 1

I also DO NOT want two separate shared objects (one for testing and one for use by an user) (this I have tried and works).

A:

In C language initialization is definition.
Lets consider simple example: decl.h file contains single declaration
#ifdef CORR
extern int i;
#else
extern int i = 5;
#endif

decl.c file contains definition:
#include "decl.h"
int i = 5;
int foo() { return i; }

Now compile with gcc -DCORR decl.c -c and you will see no problems, but if you will try to compile with initialization in extern declaration, you will get multiple definition error.
So your header file need to contain only declarations, and might look like:
extern const gsl_rng *gBaseRand;
extern unsigned long randSeed;
extern const double lowest_double;
extern const double highest_double;
extern FILE *fp;

And inside any C file, say C_file_with_main_calling_functions.c, you may put some definitions:
const gsl_rng *gBaseRand;       // global rand number generator
unsigned long randSeed;
const double lowest_double = -GSL_DBL_MAX;
const double highest_double = GSL_DBL_MAX;
FILE *fp = NULL;

Then everything should compile and link without errors.

