I'm trying to compile a Fortran program that uses the PLASMA libraries. Compilation fails with undefined reference to `__plasma_MOD_plasma_init'. Inside plasma.h (which i assume plasma.mod is the interface for), plasma_init is defined with one argument whereas it is called with two in the Fortran program. When removing the second argument though, i get Error: Missing actual argument for argument ‘info’ at (1). I haven't been able to make sense of this, so hopefully someone here can.
I'm using PLASMA 2.8.0 and gcc 6.3.0 20170516.
Here's the makefile. I tried including the pkgconfig which contains plasma.pc because i thought the function's implementation was missing.
#LIB_ROOT = path to the lib
INCLUDE_PLASMA := $(LIB_ROOT)/plasma_2.8.0/include
LIB_PLASMA := $(LIB_ROOT)/plasma_2.8.0/lib/pkgconfig
example: example.f90
gfortran -o example example.f90 -I$(INCLUDE_PLASMA) -L$(LIB_PLASMA)
Here's the minimal Fortran code :
program example
use plasma
implicit none
integer :: a = 1
integer :: info = 1
call plasma_init(a, info)
end program
In plasma.h, plasma_init is defined as:
int PLASMA_Init(int cores);
I solved my issue by correctly linking to the required libraries, here's the new makefile:
PLASMA_BUILD = [some directories]/plasma-installer_2.8.0/build
LIB_PLASMA := $(PLASMA_BUILD)/plasma_2.8.0/lib # contains libplasma.a, libcoreblas.a and libcoreblasqw.a
LIB_QUARK := $(PLASMA_BUILD)/plasma_2.8.0/quark # contains libquark.a
LIB_LAPACK := $(PLASMA_BUILD)/lapack-3.6.0 # contains liblapack.a and liblapacke.a
PLASMA_INTERFACE = $(PLASMA_BUILD)/plasma_2.8.0/control # contains plasma.mod
example: example.f90
gfortran -o example example.f90 -lpthread \
-L$(LIB_PLASMA) -lplasma -lcoreblas -lcoreblasqw \
-L$(LIB_QUARK) -lquark \
-L$(LIB_LAPACK) -llapacke -llapack \
-I$(PLASMA_INTERFACE)
Related
For example, we have a code:
#include <stdio.h>
int main()
{
printf("Hello, Stack Overflow!\n");
return 0;
}
And we want to get statically linked executable:
$ gcc -o main main.c -static
Everything is going well, but there is one nuance:
$ du -h main
768K main
Isn't it too much for such simple program? Let's take a list of symbols, that used in executable:
$ nm main
00000000004010f4 T abort
00000000004aec70 B __abort_msg
0000000000444be0 t add_alias2.part.0
000000000047e240 t add_fdes
000000000040163a t add_fdes.cold
0000000000444c70 t add_module.constprop.0
0000000000463570 t add_name_to_object.isra.0
0000000000462e30 t add_path.constprop.0.isra.0
00000000004adb28 d adds.1
000000000044fb70 T __add_to_environ
0000000000474210 t add_to_global_resize
00000000004741f0 t add_to_global_resize_failure.isra.0
0000000000474080 t add_to_global_update
0000000000409f50 t adjust_wide_data
00000000004af150 V __after_morecore_hook
0000000000405bd0 t alias_compare
0000000000481358 r aliasfile.0
00000000004166d0 W aligned_alloc
00000000004af178 b aligned_heap_area
0000000000461b40 T __alloc_dir
00000000004117b0 t alloc_perturb
00000000004af9c8 b any_objects_registered
0000000000486c40 r archfname
00000000004af520 b archive_stat
00000000004af500 b archloaded
00000000004af5c8 b archmapped
0000000000413780 t arena_get2.part.0
0000000000413ea0 t arena_get_retry
000000000045f8a0 T __argz_add_sep
000000000045f8a0 W argz_add_sep
000000000045f7c0 T __argz_create_sep
000000000045f7c0 W argz_create_sep
0000000000408c30 T ___asprintf
0000000000408c30 T __asprintf
0000000000408c30 W asprintf
0000000000402cd0 T __assert_fail
0000000000402b70 T __assert_fail_base
00000000004010e0 t __assert_fail_base.cold
000000000047fca0 t base_of_encoded_value
0000000000401658 t base_of_encoded_value.cold
0000000000417e60 i bcmp
0000000000495330 r blanks
00000000004953a0 r blanks
0000000000462250 T __brk
0000000000462250 W brk
00000000004ae230 B __bss_start
00000000004609d0 T __btowc
00000000004609d0 W btowc
00000000004afa00 b buf
...
In my case nm main | wc gives 1726 lines, almost of which relate to libraries like libc. So, how we can eliminate unused code in statically linked files?
There is already a similar question, but instructions in it answers work only for functions, used in project, not for libraries functions.
So, how we can eliminate unused code in statically linked files?
GLIBC is not optimized for static linkinig. If you want small statically linked binaries, use some other libc, e.g. dietlibc. See this comparison of available options.
While it could be argued that your sample program does use printf, and therefore linking all the associated support code is justified, the same can not be said for this program:
int main() { return 0; }
And yet that program (when statically linked) weights in at 765KiB on my system using Debian GLIBC 2.31-13:
$ gcc tt.c -static
$ ls -l a.out
-rwxr-x--- 1 user user 782648 Aug 19 08:28 a.out
Using nvcc I created an object file from my project with the following bash script:
nvcc -Xcompiler -std=c99 -dc src/interface.cu src/functions.cu
nvcc -dlink interface.o functions.o -o obj/link.o
In my obj folder I get a link.o file. I need to link this file to my Ada project using gprbuild. I can compile an Ada-Cuda project perfectly if I don't use the separate compilation mode of nvcc. But now, as I need the separate compilation mode, I have to find a way to link link.o with the rest of the project. This is the .gpr file:
project Test is
for Languages use ("Ada");
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Exec_Dir use ".";
for Main use ("main.adb");
for Create_Missing_Dirs use "True";
package Linker is
for Default_Switches("Ada") use (
"-L/usr/local/cuda/lib64",
"-lcuda",
"-lcudart",
"-lcudadevrt",
"-lstdc++",
"-lm");
for Leading_Switches("Ada") use (
"link.o" -- Doesn't work
);
end Linker;
end Test;
This is the error I get
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
/usr/local/opt/gnat-19.1-x86_64/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.3.1/ld: main.o: in function `_ada_main':
main.adb:(.text+0x5): undefined reference to `bind_say_hello'
/usr/local/opt/gnat-19.1-x86_64/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.3.1/ld: link.o: in function `__cudaRegisterLinkedBinary_45_tmpxft_0000404a_00000000_11_interface_cpp1_ii_f804fc64':
link.stub:(.text+0x50): undefined reference to `__fatbinwrap_45_tmpxft_0000404a_00000000_11_interface_cpp1_ii_f804fc64'
/usr/local/opt/gnat-19.1-x86_64/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.3.1/ld: link.o: in function `__cudaRegisterLinkedBinary_45_tmpxft_0000404a_00000000_13_functions_cpp1_ii_e57d67fc':
link.stub:(.text+0x96): undefined reference to `__fatbinwrap_45_tmpxft_0000404a_00000000_13_functions_cpp1_ii_e57d67fc'
collect2: error: ld returned 1 exit status
gprbuild: link of main.adb failed
gprbuild: failed command was: /usr/local/opt/gnat-19.1-x86_64/bin/gcc main.o link.o b__main.o -L/usr/local/cuda/lib64 -lcuda -lcudart -lcudadevrt -lstdc++ -lm -L/home/cir_eti/Documents/test/multi_cu_file/obj/ -L/home/cir_eti/Documents/test/multi_cu_file/obj/ -L/usr/local/opt/gnat-19.1-x86_64/lib/gcc/x86_64-pc-linux-gnu/7.3.1/adalib/ -static-libgcc /usr/local/opt/gnat-19.1-x86_64/lib/gcc/x86_64-pc-linux-gnu/7.3.1/adalib/libgnat.a -ldl -Wl,-rpath-link,/usr/local/opt/gnat-19.1-x86_64/lib/gcc/x86_64-pc-linux-gnu/7.3.1//adalib -Wl,-z,origin,-rpath,/usr/local/cuda/lib64:$ORIGIN/obj:/usr/local/opt/gnat-19.1-x86_64/lib/gcc/x86_64-pc-linux-gnu/7.3.1/adalib -o /home/cir_eti/Documents/test/multi_cu_file//main
I'm doing an interface to a DLL and the interface they give is via a C header-file, I have an autogenerated package from the spec; I'm adding the post-conditions and, in the private portion of the package, I put this Linker_Options pragma which instructs the linker to interface with the DLL. -- IIUC, you could use this to address your problem.
Package import_example is
Bad_Return : Exception;
SUCCESS : constant := 20007;
NOT_INITIALIZED : constant := 20008;
ERROR : constant := 20009;
INVALID : constant := 20010;
Function Return_Report (Name : String; Value : unsigned ) return String is
(Name & " should not return" & unsigned'Image(Value) & '.') with Inline;
function item_1 return unsigned -- some_c_header.h:249
with Import => True,
Convention => C,
External_Name => "item_1",
Post => item_1'Result in
SUCCESS | NOT_INITIALIZED | ERROR | INVALID
or else raise Bad_Return with
Return_Report("item_1", item_1'Result)
;
function wait return unsigned -- some_c_header.h:250
with Import => True,
Convention => C,
External_Name => "wait",
Post => wait'Result in
SUCCESS | NOT_INITIALIZED | ERROR
or else raise Bad_Return with
Return_Report("wait", wait'Result)
;
Private
Pragma Linker_Options( "-lsmcex" );
End import_example;
When I try to compile the following with g++:
const int zero;
int main()
{
return 0;
}
I get an error about an uninitialized const 'zero'. I thought that global variables were default initialized to 0 [1] ? Why isn't this the case here?
VS compiles this fine.
[1] For example, see https://stackoverflow.com/a/10927293/331785
My gcc is slightly more verbose:
$ g++ zeroconst.c
zeroconst.c:1:11: error: uninitialized const ‘zero’ [-fpermissive]
We see that -fpermissive option will allow this to compile.
See this question on uninitialized const for a reference to C++ standard (the problem is C++-specific).
As cited at GCC wiki:
As mandated by the C++ standard (8.5 [decl.init], para 9 in C++03,
para 6 in C++0x), G++ does not allows objects of const-qualified type
to be default initialized unless the type has a user-declared default
constructor. Code that fails to compile can be fixed by providing an
initializer...
G++ requires that you initialize your constant during definition.
I'm in the process of cross-compiling GTK+ 3.4.4 for Windows. I have already cross-compiled all of the build dependencies for GTK (ATK, Cairo, GDK Pixbuf, and Pango) and installed them to /usr/i686-w64-mingw32/.
Attempting to compile GTK itself, however, results in the following error:
In file included from gdkrgba.c:31:0:
fallback-c89.c:40:1: error: expected identifier or '(' before 'sizeof'
fallback-c89.c:40:1: error: expected ')' before '==' token
Line 34 - 44 of gdk/fallback-c89.c contains:
34. #ifndef HAVE_ISINF
35. /* Unfortunately MSVC does not have finite()
36. * but it does have _finite() which is the same
37. * as finite() except when x is a NaN
38. */
39. static inline gboolean
40. isinf (double x)
41. {
42. return (!_finite (x) && !_isnan (x));
43. }
44. #endif
I haven't the slightest idea where GCC is finding 'sizeof' or '=='. Why is the compiler throwing such a cryptic error message and how can I fix it?
Edit: here is the actual command line:
/usr/bin/i686-w64-mingw32-gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I..
-DG_LOG_DOMAIN="Gdk" -DGDK_COMPILATION -I.. -I../gdk -I..
-DG_DISABLE_CAST_CHECKS -mms-bitfields
-I/usr/i686-w64-mingw32/include/pango-1.0
-I/usr/i686-w64-mingw32/include/glib-2.0
-I/usr/i686-w64-mingw32/lib/glib-2.0/include
-I/usr/i686-w64-mingw32/include/cairo -I/usr/i686-w64-mingw32/include/pixman-1
-I/usr/i686-w64-mingw32/include -I/usr/i686-w64-mingw32/include/freetype2
-I/usr/i686-w64-mingw32/include/libpng15
-I/usr/i686-w64-mingw32/include/gdk-pixbuf-2.0 -O2 -Wall -mms-bitfields -MT
gdkrgba.lo -MD -MP -MF .deps/gdkrgba.Tpo -c gdkrgba.c -DDLL_EXPORT -DPIC -o
.libs/gdkrgba.o
Further edit: after compiling with the -E option, I captured the following pre-processed output... which explains the strange sizeof:
# 39 "fallback-c89.c"
static inline gboolean
((sizeof (double x) == sizeof (float) ? __fpclassifyf (double x) : sizeof double x)) == (0x0100 | 0x0400))
{
return (!_finite (x) && !_isnan (x));
}
I can only conclude that isinf is already a defined macro. It is merely being expanded when used in the function declaration above.
My question now becomes... why is HAVE_ISINF not defined? Is it a problem with the configure script?
Yet another edit: okay, so I decided to search for everything in the build tree that contained the string 'HAVE_ISINF' and came across the following instances:
autom4te.cache/traces.1
m4trace:configure.ac:740: -1- AH_OUTPUT([HAVE_ISINF], [/* Define to 1 if you
have the `isinf\' function. */
#%:#undef HAVE_ISINF])
config.h.in
/* Define to 1 if you have the `isinf' function. */
#undef HAVE_ISINF
config.h
/* Define to 1 if you have the `isinf' function. */
/* #undef HAVE_ISINF */
Surprisingly, there is nothing in config.log mentioning `HAVE_ISINF'.
(Possibly) final edit: I did some more investigation and found the string 'isinf' in autom4te.cache/output.0 here: http://paste.ubuntu.com/1154478/
This code made a reference to ac_fn_c_check_func, so I dug up the source for that function and compiled the .c sample that the script generates:
test.c:25:6: warning: conflicting types for built-in function ‘isinf’
[enabled by default]
/tmp/ccLYd1R8.o:test.c:(.text+0xc): undefined reference to `_isinf'
collect2: ld returned 1 exit status
This is odd since my explanation above would suggest that isinf is simply a macro.
I finally found this. In summary:
"The isnan() and isinf() are C99 macros not functions so use AC_CHECK_DECL instead of AC_CHECK_FUNCS for those."
So it looks like I'll be patching the source.
I want to use gcc to do some compile-time checking on function inputs if the compiler knows that they are constants.
I have a solution that very almost works, and as far as I can see, it should work.
Note: __builtin_constant_p(expression) is supposed to returns whether an expression is known to be a constant at compile time.
Assuming we want to check whether port<2 when calling uart(port), the following code should work:
#include <stdio.h>
void _uart(int port) {
printf("port is %d", port);
}
#define uart(port) \
static_assert(__builtin_constant_p(port)? port<2: 1, "parameter port must be < 2"); \
_uart(port)
int main(void) {
int x=1;
uart(x);
}
This works when calling uart(). Unfortunately, it doesn't quite work for non-constant x. For some reason static_assert can't handle the case where x is not a constant, even though in theory __builtin_constant_p() won't even pass it a constant. The error message I get is:
c:\>gcc a.cpp -std=c++0x -Os
a.cpp: In function 'int main()':
a.cpp:13: error: 'x' cannot appear in a constant-expression
Any ideas?
Your code works with g++ (GCC) 4.8.2.
- but not with optimization, as you correctly noted.
If only we could use
static_assert(__builtin_choose_expr(__builtin_constant_p(port), \
port<2, 1), "parameter port must be < 2")
- but unfortunately the __builtin_choose_expr construct is currently only available for C.
However, there is a C++ patch which sadly didn't make it into the release yet.
You can try the trick used in the Linux kernel:
What is ":-!!" in C code?
The (somewhat horrible) Linux kernel macro is less strict about what kinds of expressions are allowed in the parameter.