BRAHMS-SystemML / brahms

BRAHMS is modular execution middleware
3 stars 3 forks source link

BrahmsConfig.h causing compile issues etc... (Actually - components can't link to brahms-engine) #11

Closed ajc158 closed 8 years ago

ajc158 commented 8 years ago

Hi Seb,

Just compiling against the CMake BRAHMS and there seem to be a few issues - mainly stemming from the fact that BrahmsConfig.h is setting a lot of stuff I'd rather it didn't... this includes a hard coded path. It would be better to have the code generation pass in this path instead, as hard coding it means that the self contained BRAHMS will only work in one directory - bad news for users.

Alex

sebjameswml commented 8 years ago

BrahmsConfig.h is generated from BrahmsConfig.h.in

Paths are set up in the main CMakeLists.txt file.

Which one is the problem?

ajc158 commented 8 years ago

Really the fact that paths are hard coded at compile time - is this necessary? -- it means we can't distribute a pre-compiled binary for Mac...

BTW - just noticed it wasn't clear in my initial comment: I'm talking about compiling components using the brahms headers...

On 25 February 2016 at 11:57, Seb James notifications@github.com wrote:

BrahmsConfig.h is generated from BrahmsConfig.h.in

Paths are set up in the main CMakeLists.txt file.

Which one is the problem?

— Reply to this email directly or view it on GitHub https://github.com/sebjameswml/brahms/issues/11#issuecomment-188753185.

Alex Cope Research Associate Behavioural and Evolutionary Theory Lab Department of Computer Science, University of Sheffield www.alexcope.co.uk

sebjameswml commented 8 years ago

It's a decision I made to compile in the main namespace path. I've not ruled out making the paths "overrideable" with SYSTEMML_INSTALL_PATH. In fact, from the readme: What may change in future?

I may re-instate SYSTEMML_INSTALL_PATH such that you can have a second installed Namespace, perhaps at $HOME/SystemML/Namespace which is referred to with SYSTEMML_INSTALL_PATH.

I may implement a scheme for saving the delayed values stored in connections which have some specified lag.

On 25 February 2016 at 12:05, Alex Cope notifications@github.com wrote:

Really the fact that paths are hard coded at compile time - is this necessary?

On 25 February 2016 at 11:57, Seb James notifications@github.com wrote:

BrahmsConfig.h is generated from BrahmsConfig.h.in

Paths are set up in the main CMakeLists.txt file.

Which one is the problem?

— Reply to this email directly or view it on GitHub <https://github.com/sebjameswml/brahms/issues/11#issuecomment-188753185 .

Alex Cope Research Associate Behavioural and Evolutionary Theory Lab Department of Computer Science, University of Sheffield www.alexcope.co.uk

— Reply to this email directly or view it on GitHub https://github.com/sebjameswml/brahms/issues/11#issuecomment-188755205.

Research Associate in Computational Neuroscience Adaptive Behaviour Research Group Dept. of Psychology

ajc158 commented 8 years ago

Extra Namespaces can be configured using brahms.xml or command line options, so that doesn't seem too important.

I've made progress - it doesn't seem that the .h file paths do anything - but I'm still having trouble as components try to link agains brahms-engine symbols, but since engine is statically linked into brahms-execute I can't link against it??

Undefined symbols for architecture x86_64: "_brahms_engineEvent", referenced from: std_2009_data_numeric_0::raiseError(unsigned long, char const*) in cckYGhHg.o std_2009_data_spikes_0::raiseError(unsigned long, char const*) in cckYGhHg.o std_2009_util_rng_0::raiseError(unsigned long, char const*) in cckYGhHg.o std_2009_data_numeric_0::get_structure(unsigned long, unsigned long) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, unsigned int, brahms::Dimensions const&) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, std_2009_data_numeric_0::Structure const&) in cckYGhHg.o std_2009_data_numeric_0::validate(unsigned long, unsigned long, unsigned int) in cckYGhHg.o ... "_xml_getAttribute", referenced from: brahms::XMLNode::getAttribute(char const*) in cckYGhHg.o brahms::DataMLNode::hasField(char const*) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode*) in cckYGhHg.o "_xml_getChild", referenced from: brahms::DataMLNode::getRaw(unsigned char*, unsigned char*) const in cckYGhHg.o brahms::DataMLNode::getField(char const*, unsigned int) const in cckYGhHg.o "_xml_getNodeName", referenced from: brahms::XMLNode::getAttribute(char const*) in cckYGhHg.o brahms::DataMLNode::hasField(char const*) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode*) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char*, unsigned char*) const in cckYGhHg.o "_xml_getNodeText", referenced from: brahms::DataMLNode::assign(brahms::XMLNode*) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char*, unsigned char*) const in cckYGhHg.o brahms::DataMLNode::getSTRING() in cckYGhHg.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status

sebjameswml commented 8 years ago

I changed the code so that the code which was previously part of libbrahms-engine.so (which was not much) is now inside the brahms executable.

So you should be able to remove the libbrahms-engine linking

On 25 February 2016 at 12:51, Alex Cope notifications@github.com wrote:

Extra Namespaces can be configured using brahms.xml or command line options, so that doesn't seem too important.

I've made progress - it doesn't seem that the .h file paths do anything - but I'm still having trouble as components try to link agains brahms-engine symbols, but since engine is statically linked into brahms-execute I can't link against it??

Undefined symbols for architecture x86_64: "_brahms_engineEvent", referenced from: std_2009_data_numeric0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_data_spikes0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_util_rng0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_data_numeric_0::get_structure(unsigned long, unsigned long) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, unsigned int, brahms::Dimensions const&) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, std_2009_data_numeric_0::Structure const&) in cckYGhHg.o std_2009_data_numeric_0::validate(unsigned long, unsigned long, unsigned int) in cckYGhHg.o ... "_xmlgetAttribute", referenced from: brahms::XMLNode::getAttribute(char const) in cckYGhHg.o brahms::DataMLNode::hasField(char const) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o "_xmlgetChild", referenced from: brahms::DataMLNode::getRaw(unsigned char, unsigned char) const in cckYGhHg.o brahms::DataMLNode::getField(char const, unsigned int) const in cckYGhHg.o "_xmlgetNodeName", referenced from: brahms::XMLNode::getAttribute(char const) in cckYGhHg.o brahms::DataMLNode::hasField(char const) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char, unsigned char) const in cckYGhHg.o "_xmlgetNodeText", referenced from: brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char_, unsigned char*) const in cckYGhHg.o brahms::DataMLNode::getSTRING() in cckYGhHg.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status

— Reply to this email directly or view it on GitHub https://github.com/sebjameswml/brahms/issues/11#issuecomment-188775654.

Research Associate in Computational Neuroscience Adaptive Behaviour Research Group Dept. of Psychology

ajc158 commented 8 years ago

I have done... On 25 Feb 2016 1:09 pm, "Seb James" notifications@github.com wrote:

I changed the code so that the code which was previously part of libbrahms-engine.so (which was not much) is now inside the brahms executable.

So you should be able to remove the libbrahms-engine linking

On 25 February 2016 at 12:51, Alex Cope notifications@github.com wrote:

Extra Namespaces can be configured using brahms.xml or command line options, so that doesn't seem too important.

I've made progress - it doesn't seem that the .h file paths do anything - but I'm still having trouble as components try to link agains brahms-engine symbols, but since engine is statically linked into brahms-execute I can't link against it??

Undefined symbols for architecture x86_64: "_brahms_engineEvent", referenced from: std_2009_data_numeric0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_data_spikes0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_util_rng0::raiseError(unsigned long, char const) in cckYGhHg.o std_2009_data_numeric_0::get_structure(unsigned long, unsigned long) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, unsigned int, brahms::Dimensions const&) in cckYGhHg.o std_2009_data_numeric_0::set_structure(unsigned long, unsigned long, std_2009_data_numeric_0::Structure const&) in cckYGhHg.o std_2009_data_numeric_0::validate(unsigned long, unsigned long, unsigned int) in cckYGhHg.o ... "_xmlgetAttribute", referenced from: brahms::XMLNode::getAttribute(char const) in cckYGhHg.o brahms::DataMLNode::hasField(char const) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o "_xmlgetChild", referenced from: brahms::DataMLNode::getRaw(unsigned char, unsigned char) const in cckYGhHg.o brahms::DataMLNode::getField(char const, unsigned int) const in cckYGhHg.o "_xmlgetNodeName", referenced from: brahms::XMLNode::getAttribute(char const) in cckYGhHg.o brahms::DataMLNode::hasField(char const) const in cckYGhHg.o brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char, unsigned char) const in cckYGhHg.o "_xmlgetNodeText", referenced from: brahms::DataMLNode::assign(brahms::XMLNode) in cckYGhHg.o brahms::DataMLNode::getRaw(unsigned char_, unsigned char*) const in cckYGhHg.o brahms::DataMLNode::getSTRING() in cckYGhHg.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status

— Reply to this email directly or view it on GitHub <https://github.com/sebjameswml/brahms/issues/11#issuecomment-188775654 .

Research Associate in Computational Neuroscience Adaptive Behaviour Research Group Dept. of Psychology

— Reply to this email directly or view it on GitHub https://github.com/sebjameswml/brahms/issues/11#issuecomment-188779448.

ajc158 commented 8 years ago

Yep, just confirmed - the issue is that the libbrahms-engine symbols are now in the executable, so when compiling a component the component cannot compile-time link against them. This leads to a failure to compile.

You can avoid the issue at compile time by preventing undefined symbols being flagged, but the library still fails to load at run-time with the same problem

sebjameswml commented 8 years ago

Is the a problem when you compile SpineML_2_BRAHMS components? Or do you see it when compiling BRAHMS itself?

ajc158 commented 8 years ago

Components (at the moment I'm working on tools/explicitList as it is more convenient)

BRAHMS compiles fine... which means the stdlib compiles... so really not sure what the issue is

sebjameswml commented 8 years ago

Ah, looks like I've left some library linking in Apple. See framework/engine/CMakeLists.txt:

add_library(brahms-engine-base ${BRAHMS_ENGINE_LINK_TYPE}
  ../channel/channel-common.cpp
  base/core.cpp base/ipm.cpp base/os.cpp base/text.cpp base/constants.cpp
  base/brahms_error.cpp base/brahms_math.cpp base/output.cpp base/thread.cpp
)
add_library(brahms-engine ${BRAHMS_ENGINE_LINK_TYPE}
  systemml/component.cpp systemml/event.cpp systemml/interface.cpp
  systemml/loggable.cpp systemml/process.cpp systemml/ systemml/system.cpp
  systemml/thread.cpp systemml/data.cpp systemml/identifier.cpp
  systemml/link.cpp systemml/port.cpp systemml/set.cpp
  systemml/utility.cpp
  support/environment.cpp support/execution.cpp support/loader.cpp
  support/os.cpp support/error.cpp
  support/helpers.cpp support/module.cpp support/register.cpp
  support/xml.cpp
  main/api.cpp main/api-engine.cpp main/engine.cpp
  main/engine-open.cpp  main/engine-execute.cpp  main/engine-close.cpp
  main/engine-walk.cpp main/engine-monitor.cpp 
  )

# Mac wants to be able to see libbrahms-channel-common in the above.
if(APPLE)
  target_link_libraries(
    brahms-engine brahms-engine-base brahms-gui
    ${CMAKE_THREAD_LIBS_INIT} ${LIB_RT} ${XAW_LDFLAGS}
    )
endif(APPLE)
ajc158 commented 8 years ago

So you are static linking the stdlibs?

sebjameswml commented 8 years ago

Just the internal libraries:

[seb@PSY0001622 15:42:23 ~]$ ldd /usr/local/bin/brahms-execute 
    linux-vdso.so.1 =>  (0x00007fffa92d8000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f53eef17000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f53eed0f000)
    libXaw.so.7 => /usr/lib/x86_64-linux-gnu/libXaw.so.7 (0x00007f53eea9d000)
    libXt.so.6 => /usr/lib/x86_64-linux-gnu/libXt.so.6 (0x00007f53ee837000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f53ee502000)
    libXmu.so.6 => /usr/lib/x86_64-linux-gnu/libXmu.so.6 (0x00007f53ee2e8000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f53ee0e4000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f53edde0000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f53edad9000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f53ed8c3000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53ed4fe000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f53ef16a000)
    libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f53ed2eb000)
    libXpm.so.4 => /usr/lib/x86_64-linux-gnu/libXpm.so.4 (0x00007f53ed0d9000)
    libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007f53eced1000)
    libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007f53eccb4000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f53eca95000)
    libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f53ec88f000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f53ec68b000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f53ec485000)
sebjameswml commented 8 years ago

See how everything is dynamically linked, but there's no libbrahms-engine.so etc

ajc158 commented 8 years ago

?

sebjameswml commented 8 years ago

ldd shows the linking of an executable - I showed the linking of brahms-execute. All the dynamically linked libs are listed.

sebjameswml commented 8 years ago

libbrahms-engine is compiled into libbrahms-engine.a and statically linked into brahms-execute.

However, there's something not working when we do this on Apple.

ajc158 commented 8 years ago

How does this work on Linux? The symbols are still stuck in an executable so components can't link to them

sebjameswml commented 8 years ago

Yes, but that executable dynamically loads the component.so, and when it does that the symbols are all available.

ajc158 commented 8 years ago

Not on Mac - I can bypass the compile time error and it still falls flat... Why is there no compile time error on LInux, or do you use a similar trick to ignore the errors?

dlopen() failed with message "dlopen(/Users/alex/Documents/SpineML_2_BRAHMS/Namespace/dev/SpineML/temp/WU/OneToOneConnectionweight/brahms/0/component.dylib, 2): Symbol not found: _brahms_engineEvent Referenced from: /Users/alex/Documents/SpineML_2_BRAHMS/Namespace/dev/SpineML/temp/WU/OneToOneConnectionweight/brahms/0/component.dylib Expected in: flat namespace in /Users/alex/Documents/SpineML_2_BRAHMS/Namespace/dev/SpineML/temp/WU/OneToOneConnectionweight/brahms/0/component.dylib" E_FAILED_LOAD_MODULE: /Users/alex/Documents/SpineML_2_BRAHMS/Namespace/dev/SpineML/temp/WU/OneToOneConnectionweight/brahms/0/component.dylib

sebjameswml commented 8 years ago

Here's what I think you need to find an analogue for:

This is framework/execute/CMakeLists.txt:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${XAW_CFLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XAW_CFLAGS}")
message(STATUS "Flags for brahms-execute: " ${CMAKE_CXX_FLAGS})
add_executable(brahms-execute main.cpp info.cpp os.cpp tfs.cpp version.cpp)

# Some Linux systems have clock_gettime in librt, for others it's in libc
if(HAVE_CLOCK_GETTIME_IN_RT)
  set(LIB_RT rt)
endif(HAVE_CLOCK_GETTIME_IN_RT)

if(APPLE)
  target_link_libraries(brahms-execute
    brahms-engine brahms-engine-base brahms-gui
    ${CMAKE_THREAD_LIBS_INIT} ${LIB_RT} ${XAW_LDFLAGS} ${XMU_LDFLAG} ${CMAKE_DL_LIBS}
    )
else()
  target_link_libraries(brahms-execute
    # Alex: On Linux, for gcc, I had to do this: I think this is the trick. --whole-archive makes sure ALL Code gets linked into the executable EVEN if it is not made use of IN THE EXECUTABLE.
    ${BRAHMS_LINK_WHOLE_ARCHIVE} # adds -Wl,--whole-archive for static linking
    brahms-engine brahms-engine-base brahms-gui
    ${BRAHMS_NOT_LINK_WHOLE_ARCHIVE} # resets with -Wl,--no-whole-archive
    ${CMAKE_THREAD_LIBS_INIT} ${LIB_RT} ${XAW_LDFLAGS} ${XMU_LDFLAG} ${CMAKE_DL_LIBS}
    )
endif(APPLE)
sebjameswml commented 8 years ago

And see the root CMakeLists.txt for the content of BRAHMS_LINK_WHOLE_ARCHIVE

sebjameswml commented 8 years ago

-Wl,--whole-archive equivalent might be -all_load

ajc158 commented 8 years ago

That's what I'm trying!

ajc158 commented 8 years ago

Yay! So, in conclusion: We need -all_load in the CMake We need ONLY -arch x86_64 in the component compile line and NO arch-bits (the .h will handle that) We have to add -undefined dynamic_lookup to the component compile line

After that it works. Now I'll try and move over to the CMake BRAHMS and make sure the master SML_2_BRAHMS plays nicely with it... I've fixed up the CMake BRAHMS already and will create a new pull request (no need as it respects my new commit...)

sebjameswml commented 8 years ago

Ok, good stuff. In the root CMakeLists.txt, change:

set(BRAHMS_LINK_WHOLE_ARCHIVE "-Wl,--whole-archive")
set(BRAHMS_NOT_LINK_WHOLE_ARCHIVE "-Wl,--no-whole-archive")

for

if(APPLE)
  set(BRAHMS_LINK_WHOLE_ARCHIVE "-all_load")
  set(BRAHMS_NOT_LINK_WHOLE_ARCHIVE "") # or whatever it needs to be
else()
  set(BRAHMS_LINK_WHOLE_ARCHIVE "-Wl,--whole-archive")
  set(BRAHMS_NOT_LINK_WHOLE_ARCHIVE "-Wl,--no-whole-archive")
endif(APPLE)

then remove the if(APPLE) bit from framework/execute/CMakeLists.txt