Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ julia-base: julia-deps $(build_sysconfdir)/julia/juliarc.jl $(build_man1dir)/jul
@$(MAKE) $(QUIET_MAKE) -C base

julia-libccalltest:
@$(MAKE) $(QUIET_MAKE) -C test libccalltest
@$(MAKE) $(QUIET_MAKE) -C src libccalltest

julia-src-release julia-src-debug : julia-src-% : julia-deps
@$(MAKE) $(QUIET_MAKE) -C src libjulia-$*
Expand Down Expand Up @@ -202,7 +202,7 @@ $(build_bindir)/stringreplace: contrib/stringreplace.c | $(build_bindir)
JL_LIBS = julia julia-debug

# private libraries, that are installed in $(prefix)/lib/julia
JL_PRIVATE_LIBS = suitesparse_wrapper Rmath
JL_PRIVATE_LIBS = suitesparse_wrapper Rmath ccalltest
ifeq ($(USE_SYSTEM_FFTW),0)
JL_PRIVATE_LIBS += fftw3 fftw3f fftw3_threads fftw3f_threads
endif
Expand Down
8 changes: 7 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ $(BUILDDIR)/%.o: %.cpp $(HEADERS) $(shell which $(LLVM_CONFIG)) | $(BUILDDIR)
$(BUILDDIR)/%.dbg.obj: %.cpp $(HEADERS) $(shell which $(LLVM_CONFIG)) | $(BUILDDIR)
@$(call PRINT_CC, $(CXX) $(call exec,$(LLVM_CONFIG) --cxxflags) $(CPPFLAGS) $(CXXFLAGS) $(DEBUGFLAGS) -c $< -o $@)

libccalltest: $(build_shlibdir)/libccalltest.$(SHLIB_EXT)
$(build_shlibdir)/libccalltest.$(SHLIB_EXT): ccalltest.c
@$(call PRINT_CC, $(CC) $(CFLAGS) $(CPPFLAGS) $(DEBUGFLAGS) -O3 $< $(fPIC) -shared -o $@ $(LDFLAGS) -DCC="$(CC)")



$(BUILDDIR)/julia_flisp.boot.inc: $(BUILDDIR)/julia_flisp.boot $(FLISP_EXECUTABLE)
@$(call PRINT_FLISP, $(call spawn,$(FLISP_EXECUTABLE)) ./bin2hex.scm < $< > $@)

Expand Down Expand Up @@ -157,7 +163,7 @@ $(BUILDDIR)/libjulia.a: julia.expmap $(OBJS) $(BUILDDIR)/flisp/libflisp.a $(BUIL
libjulia-release: $(build_shlibdir)/libjulia.$(SHLIB_EXT)

clean:
-rm -f $(build_shlibdir)/libjulia*
-rm -fr $(build_shlibdir)/libjulia* $(build_shlibdir)/libccalltest*
-rm -f $(BUILDDIR)/julia_flisp.boot $(BUILDDIR)/julia_flisp.boot.inc
-rm -f $(BUILDDIR)/*.dbg.obj $(BUILDDIR)/*.o *~ $(BUILDDIR)/*.$(SHLIB_EXT) $(BUILDDIR)/*.a *#
-rm -f $(BUILDDIR)/julia_version.h
Expand Down
70 changes: 29 additions & 41 deletions test/ccalltest.c → src/ccalltest.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
int verbose = 1;

#include "../src/support/platform.h"
#include "../src/support/dtypes.h"

#ifdef _P64
#define jint int64_t
Expand All @@ -26,7 +27,7 @@ int __declspec(noinline)
#else
int __attribute__((noinline))
#endif
testUcharX(unsigned char x) {
DLLEXPORT testUcharX(unsigned char x) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for other reviewers: this change shouldn't be necessary, since dllexport is the default for Mac, Linux, and Mingw64 compilers. However, it could perhaps be somewhat useful if dealing with MSVC in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msvc can't really build this file as it stands right now since it doesn't support C-style complex

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it should only really matter if msvc tried to link against the resulting file (even if mingw compiled it), which is even less likely however. and none of that matters unless you are also going to create the lib.a file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dll visibility matters for ccall - the default with mingw is only to export everything if there are no export attributes present. If you have a single dllexport that is explicitly specified, then only that function gets exported (unless you link with -Wl,--export-all-symbols). So it either needs to be nowhere or on everything you want to use.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the reason I added these DLLEXPORT things is because on Linux, with GCC, the symbols weren't accessible. nm showed them as 't' instead of 'T' which apparently means "local", but I'm honestly a little fuzzy as to what exactly that means. It's possible that what Tony just said is the culprit; something else was getting exported which caused everything else to be non-visible, but at least things are more explicit this way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CFLAGS has a special meaning inside of src/Makefile due to an override at the top

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point; I've removed CFLAGS and replaced it with CPPFLAGS now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should still have CFLAGS as well, to accommodate where-ever the user's environment is injecting the flags

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I thought that since we're setting CFLAGS to JCFLAGS, we didn't want to pass them. I'll reinstate CFLAGS alongside CPPFLAGS then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it contains a lot of unnecessary cruft, but it might contain user flags

return xs[x];
}

Expand All @@ -45,57 +46,57 @@ typedef struct {
jint imag;
} complex_t;

complex_t ctest(complex_t a) {
DLLEXPORT complex_t ctest(complex_t a) {
a.real += 1;
a.imag -= 2;
return a;
}

complex double cgtest(complex double a) {
DLLEXPORT complex double cgtest(complex double a) {
//Unpack a ComplexPair{Float64} struct
if (verbose) fprintf(stderr,"%g + %g i\n", creal(a), cimag(a));
a += 1 - (2.0*I);
return a;
}

complex double* cgptest(complex double *a) {
DLLEXPORT complex double* cgptest(complex double *a) {
//Unpack a ComplexPair{Float64} struct
if (verbose) fprintf(stderr,"%g + %g i\n", creal(*a), cimag(*a));
*a += 1 - (2.0*I);
return a;
}

complex float cftest(complex float a) {
DLLEXPORT complex float cftest(complex float a) {
//Unpack a ComplexPair{Float32} struct
if (verbose) fprintf(stderr,"%g + %g i\n", creal(a), cimag(a));
a += 1 - (2.0*I);
return a;
}

complex float* cfptest(complex float *a) {
DLLEXPORT complex float* cfptest(complex float *a) {
//Unpack a ComplexPair{Float64} struct
if (verbose) fprintf(stderr,"%g + %g i\n", creal(*a), cimag(*a));
*a += 1 - (2.0*I);
return a;
}

complex_t* cptest(complex_t *a) {
DLLEXPORT complex_t* cptest(complex_t *a) {
//Unpack a ComplexPair{Int} struct pointer
if (verbose) fprintf(stderr,"%lld + %lld i\n", (long long)a->real, (long long)a->imag);
a->real += 1;
a->imag -= 2;
return a;
}

complex_t* cptest_static(complex_t *a) {
DLLEXPORT complex_t* cptest_static(complex_t *a) {
complex_t *b = (complex_t*)malloc(sizeof(complex_t));
b->real = a->real;
b->imag = a->imag;
return b;
}

// Native-like data types
char* stest(char *x) {
DLLEXPORT char* stest(char *x) {
//Print a character Array
if (verbose) fprintf(stderr,"%s\n", x);
return x;
Expand Down Expand Up @@ -203,55 +204,55 @@ typedef struct {
char z;
} struct_big;

struct1 test_1(struct1 a) {
DLLEXPORT struct1 test_1(struct1 a) {
//Unpack a "small" struct { float, double }
if (verbose) fprintf(stderr,"%g + %g i\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct1 add_1(struct1 a, struct1 b) {
DLLEXPORT struct1 add_1(struct1 a, struct1 b) {
// Two small structs
struct1 c;
c.x = a.x + b.x;
c.y = a.y + b.y;
return c;
}

struct2a test_2a(struct2a a) {
DLLEXPORT struct2a test_2a(struct2a a) {
//Unpack a ComplexPair{Int32} struct
if (verbose) fprintf(stderr,"%" PRId32 " + %" PRId32 " i\n", a.x.x, a.y.y);
a.x.x += 1;
a.y.y -= 2;
return a;
}

struct2b test_2b(struct2b a) {
DLLEXPORT struct2b test_2b(struct2b a) {
//Unpack a ComplexPair{Int32} struct
if (verbose) fprintf(stderr,"%" PRId32 " + %" PRId32 " i\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct3a test_3a(struct3a a) {
DLLEXPORT struct3a test_3a(struct3a a) {
//Unpack a ComplexPair{Int64} struct
if (verbose) fprintf(stderr,"%" PRId64 " + %" PRId64 " i\n", a.x.x, a.y.y);
a.x.x += 1;
a.y.y -= 2;
return a;
}

struct3b test_3b(struct3b a) {
DLLEXPORT struct3b test_3b(struct3b a) {
//Unpack a ComplexPair{Int64} struct
if (verbose) fprintf(stderr,"%" PRId64 " + %" PRId64 " i\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct4 test_4(struct4 a)
DLLEXPORT struct4 test_4(struct4 a)
{
if (verbose) fprintf(stderr,"(%" PRId32 ",%" PRId32 ",%" PRId32 ")\n", a.x, a.y, a.z);
a.x += 1;
Expand All @@ -261,7 +262,7 @@ struct4 test_4(struct4 a)
}


struct5 test_5(struct5 a)
DLLEXPORT struct5 test_5(struct5 a)
{
if (verbose) fprintf(stderr,"(%" PRId32 ",%" PRId32 ",%" PRId32 ",%" PRId32 ")\n", a.x, a.y, a.z, a.a);
a.x += 1;
Expand All @@ -273,7 +274,7 @@ struct5 test_5(struct5 a)
}


struct6 test_6(struct6 a)
DLLEXPORT struct6 test_6(struct6 a)
{
if (verbose) fprintf(stderr,"(%" PRId64 ",%" PRId64 ",%" PRId64 ")\n", a.x, a.y, a.z);
a.x += 1;
Expand All @@ -282,31 +283,31 @@ struct6 test_6(struct6 a)
return a;
}

struct7 test_7(struct7 a)
DLLEXPORT struct7 test_7(struct7 a)
{
if (verbose) fprintf(stderr,"(%" PRId64 ",%" PRId8 ")\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct8 test_8(struct8 a)
DLLEXPORT struct8 test_8(struct8 a)
{
if (verbose) fprintf(stderr,"(%" PRId32 ",%" PRId8 ")\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct9 test_9(struct9 a)
DLLEXPORT struct9 test_9(struct9 a)
{
if (verbose) fprintf(stderr,"(%" PRId32 ",%" PRId16 ")\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct10 test_10(struct10 a)
DLLEXPORT struct10 test_10(struct10 a)
{
if (verbose) fprintf(stderr,"(%" PRId8 ",%" PRId8 ",%" PRId8 ",%" PRId8 ")\n", a.x, a.y, a.z, a.a);
a.x += 1;
Expand All @@ -317,15 +318,15 @@ struct10 test_10(struct10 a)
return a;
}

struct14 test_14(struct14 a) {
DLLEXPORT struct14 test_14(struct14 a) {
//The C equivalent of a ComplexPair{Float32} struct (but without special complex ABI)
if (verbose) fprintf(stderr,"%g + %g i\n", a.x, a.y);
a.x += 1;
a.y -= 2;
return a;
}

struct15 test_15(struct15 a) {
DLLEXPORT struct15 test_15(struct15 a) {
//The C equivalent of a ComplexPair{Float32} struct (but without special complex ABI)
if (verbose) fprintf(stderr,"%g + %g i\n", a.x, a.y);
a.x += 1;
Expand All @@ -334,7 +335,7 @@ struct15 test_15(struct15 a) {
}

#define int128_t struct3b
int128_t test_128(int128_t a) {
DLLEXPORT int128_t test_128(int128_t a) {
//Unpack a Int128
if (verbose) fprintf(stderr,"0x%016" PRIx64 "%016" PRIx64 "\n", a.y, a.x);
a.x += 1;
Expand All @@ -343,7 +344,7 @@ int128_t test_128(int128_t a) {
return a;
}

struct_big test_big(struct_big a) {
DLLEXPORT struct_big test_big(struct_big a) {
//Unpack a "big" struct { int, int, char }
if (verbose) fprintf(stderr,"%lld %lld %c\n", (long long)a.x, (long long)a.y, a.z);
a.x += 1;
Expand All @@ -352,25 +353,12 @@ struct_big test_big(struct_big a) {
return a;
}

int main() {
fprintf(stderr,"all of the following should be 1 except xs[259] = 0\n");
a = 3;
b = 259;
fptr = (int (*)(unsigned char x))&testUcharX;
if ((((size_t)fptr)&((size_t)1)) == 1) fptr = NULL;
fprintf(stderr,"compiled with: '%s'\nxs[3] = %d\nxs[259] = %d\ntestUcharX(3) = %d\ntestUcharX(%d) = %d\nfptr(3) = %d\nfptr(259) = %d\n",
xstr(CC), xs[a], xs[b], testUcharX(a), b, testUcharX((unsigned char)b), fptr(a), fptr(b));
fprintf(stderr,"misc tests:\n");
struct1 a = {352.39422e23, 19.287577};
a = test_1(a);
}

//////////////////////////////////
// Turn off verbose for automated tests, leave on for debugging
void set_verbose(int level) {
DLLEXPORT void set_verbose(int level) {
verbose = level;
}

void *test_echo_p(void *p) {
DLLEXPORT void *test_echo_p(void *p) {
return p;
}
10 changes: 1 addition & 9 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,5 @@ perf:

clean:
@$(MAKE) -C perf $@
-rm -f libccalltest.$(SHLIB_EXT) ccalltest

.PHONY: $(TESTS) perf clean libccalltest

all ccall libccalltest: libccalltest.$(SHLIB_EXT)
libccalltest.$(SHLIB_EXT): ccalltest.c
@$(call PRINT_CC, $(CC) $(CFLAGS) $(DEBUGFLAGS) -O3 $< $(fPIC) -shared -o $@ $(LDFLAGS) -DCC="$(CC)")

ccalltest: ccalltest.c libccalltest.$(SHLIB_EXT)
@$(call PRINT_CC, $(CC) $(CFLAGS) $(DEBUGFLAGS) -O3 $< -o $@ $(LDFLAGS) -DCC="$(CC)")
.PHONY: $(TESTS) perf clean
2 changes: 1 addition & 1 deletion test/ccall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Base.copy, Base.==
const verbose = false
const libccalltest = joinpath(dirname(@__FILE__), "libccalltest")
const libccalltest = "libccalltest"
ccall((:set_verbose, libccalltest), Void, (Int32,), verbose)

# Test for proper argument register truncation
Expand Down
Loading