@@ -79,6 +79,9 @@ struct options_data_t {
7979 char * * comp_flags_prefix ;
8080 char * * link_flags ;
8181 char * * libs ;
82+ char * * libs_static ;
83+ char * dyn_lib_file ;
84+ char * static_lib_file ;
8285 char * req_file ;
8386 char * path_includedir ;
8487 char * path_libdir ;
@@ -100,6 +103,7 @@ static int default_data_idx = -1;
100103#define COMP_WANT_COMPILE 0x010
101104#define COMP_WANT_LINK 0x020
102105#define COMP_WANT_PMPI 0x040
106+ #define COMP_WANT_STATIC 0x080
103107
104108static void
105109options_data_init (struct options_data_t * data )
@@ -124,6 +128,10 @@ options_data_init(struct options_data_t *data)
124128 data -> link_flags [0 ] = NULL ;
125129 data -> libs = (char * * ) malloc (sizeof (char * ));
126130 data -> libs [0 ] = NULL ;
131+ data -> libs_static = (char * * ) malloc (sizeof (char * ));
132+ data -> libs_static [0 ] = NULL ;
133+ data -> dyn_lib_file = NULL ;
134+ data -> static_lib_file = NULL ;
127135 data -> req_file = NULL ;
128136 data -> path_includedir = NULL ;
129137 data -> path_libdir = NULL ;
@@ -149,6 +157,9 @@ options_data_free(struct options_data_t *data)
149157 opal_argv_free (data -> comp_flags_prefix );
150158 opal_argv_free (data -> link_flags );
151159 opal_argv_free (data -> libs );
160+ opal_argv_free (data -> libs_static );
161+ if (NULL != data -> dyn_lib_file ) free (data -> dyn_lib_file );
162+ if (NULL != data -> static_lib_file ) free (data -> static_lib_file );
152163 if (NULL != data -> req_file ) free (data -> req_file );
153164 if (NULL != data -> path_includedir ) free (data -> path_includedir );
154165 if (NULL != data -> path_libdir ) free (data -> path_libdir );
@@ -323,6 +334,16 @@ data_callback(const char *key, const char *value)
323334 opal_argv_count (options_data [parse_options_idx ].libs ),
324335 values );
325336 opal_argv_free (values );
337+ } else if (0 == strcmp (key , "libs_static" )) {
338+ char * * values = opal_argv_split (value , ' ' );
339+ opal_argv_insert (& options_data [parse_options_idx ].libs_static ,
340+ opal_argv_count (options_data [parse_options_idx ].libs_static ),
341+ values );
342+ opal_argv_free (values );
343+ } else if (0 == strcmp (key , "dyn_lib_file" )) {
344+ if (NULL != value ) options_data [parse_options_idx ].dyn_lib_file = strdup (value );
345+ } else if (0 == strcmp (key , "static_lib_file" )) {
346+ if (NULL != value ) options_data [parse_options_idx ].static_lib_file = strdup (value );
326347 } else if (0 == strcmp (key , "required_file" )) {
327348 if (NULL != value ) options_data [parse_options_idx ].req_file = strdup (value );
328349 } else if (0 == strcmp (key , "project_short" )) {
@@ -696,6 +717,13 @@ main(int argc, char *argv[])
696717 /* remove element from user_argv */
697718 opal_argv_delete (& user_argc , & user_argv , i , 1 );
698719 -- i ;
720+ } else if (0 == strcmp (user_argv [i ], "-static" ) ||
721+ 0 == strcmp (user_argv [i ], "--static" ) ||
722+ 0 == strcmp (user_argv [i ], "-Bstatic" ) ||
723+ 0 == strcmp (user_argv [i ], "-Wl,-static" ) ||
724+ 0 == strcmp (user_argv [i ], "-Wl,--static" ) ||
725+ 0 == strcmp (user_argv [i ], "-Wl,-Bstatic" )) {
726+ flags |= COMP_WANT_STATIC ;
699727 } else if ('-' != user_argv [i ][0 ]) {
700728 disable_flags = false;
701729 flags |= COMP_SHOW_ERROR ;
@@ -793,10 +821,66 @@ main(int argc, char *argv[])
793821
794822 /* link flags and libs */
795823 if (flags & COMP_WANT_LINK ) {
824+ bool have_static_lib ;
825+ bool have_dyn_lib ;
826+ bool use_static_libs ;
827+ char * filename ;
828+ struct stat buf ;
829+
796830 opal_argv_insert (& exec_argv , exec_argc , options_data [user_data_idx ].link_flags );
797831 exec_argc = opal_argv_count (exec_argv );
798832
799- opal_argv_insert (& exec_argv , exec_argc , options_data [user_data_idx ].libs );
833+ /* Are we linking statically? If so, decide what libraries to
834+ list. It depends on two factors:
835+
836+ 1. Was --static (etc.) specified?
837+ 2. Does OMPI have static, dynamic, or both libraries installed?
838+
839+ Here's a matrix showing what we'll do in all 6 cases:
840+
841+ What's installed --static no --static
842+ ---------------- ---------- -----------
843+ ompi .so libs -lmpi -lmpi
844+ ompi .a libs all all
845+ ompi both libs all -lmpi
846+
847+ */
848+
849+ filename = opal_os_path ( false, options_data [user_data_idx ].path_libdir , options_data [user_data_idx ].static_lib_file , NULL );
850+ if (0 == stat (filename , & buf )) {
851+ have_static_lib = true;
852+ } else {
853+ have_static_lib = false;
854+ }
855+
856+ filename = opal_os_path ( false, options_data [user_data_idx ].path_libdir , options_data [user_data_idx ].dyn_lib_file , NULL );
857+ if (0 == stat (filename , & buf )) {
858+ have_dyn_lib = true;
859+ } else {
860+ have_dyn_lib = false;
861+ }
862+
863+ /* Determine which set of libs to use: dynamic or static. Be
864+ pedantic to make the code easy to read. */
865+ if (flags & COMP_WANT_STATIC ) {
866+ if (have_static_lib ) {
867+ use_static_libs = true;
868+ } else {
869+ use_static_libs = false;
870+ }
871+ } else {
872+ if (have_dyn_lib ) {
873+ use_static_libs = false;
874+ } else {
875+ use_static_libs = true;
876+ }
877+ }
878+
879+ if (use_static_libs ) {
880+ opal_argv_insert (& exec_argv , exec_argc , options_data [user_data_idx ].libs_static );
881+ } else {
882+ opal_argv_insert (& exec_argv , exec_argc , options_data [user_data_idx ].libs );
883+ }
800884 exec_argc = opal_argv_count (exec_argv );
801885 }
802886
0 commit comments