ihedvall / mdflib

Implementation of the ASAM MDF data file.
https://ihedvall.github.io/mdflib/
MIT License
73 stars 30 forks source link

linking error on Ubuntu 24.04 #98

Closed csavorgn closed 2 months ago

csavorgn commented 2 months ago

Hi, I tried to compile the library but I got the following error: [100%] Linking CXX shared library libmdflibrary.so /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libz.a(zutil.o): warning: relocation against z_errmsg' in read-only section.text' /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libz.a(deflate.o): relocation R_X86_64_PC32 against symbol `z_errmsg' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: bad value collect2: error: ld returned 1 exit status make[2]: [mdflibrary/CMakeFiles/mdflibrary.dir/build.make:100: mdflibrary/libmdflibrary.so] Error 1 make[1]: [CMakeFiles/Makefile2:142: mdflibrary/CMakeFiles/mdflibrary.dir/all] Error 2 Best Carlo

csavorgn commented 2 months ago

Hi, I just realized that it is not a problem from mdflib but the way Ubuntu compiles zlib...

ihedvall commented 2 months ago

@csavorgn The MdfLib is a C++ static library while the MdfLibrary is a .NET assembly that may be compiled as a shared library (so/dll). I have successfully compiled the MdfLib as a shared library as well. There is a CMAKE magic trick needed with some positional code compiling. So if you need a libmdflib.so instead of the libmdflibrary.so, I can fix this. This -fPIC flag have something to do with the above and it's mess with Windows shared DLL.

csavorgn commented 2 months ago

Hi @ihedvall I managed to compile the MdfLib with CMake by setting MDF_BUILD_SHARED_LIB=OFF. My plan was to write a Linux (or FreeBSD) executable to write real-time data to an MDF4 file using mdf::MdfWriter. Should I use the MdfLib directly? Thank you Carlo

ihedvall commented 2 months ago

@csavorgn It is recommended to use the C++ MdfLib directly without any wrappers. I normally link the MdfLib into a static library but you can also build it as a shared library (so/dll).

You should have the BUILD_SHARED_LIBS to ON (shared) or OFF (static) and the MDF_BUILD_SHARED_LIB to OFF. I made some minor changes in the mdflib/cmakelist.txt but I have only tested it on Windows. You may also select the VCPKG triplet static or shared. Yes, it is a lot of choices and bad naming. Sorry about this.

ihedvall commented 2 months ago

@csavorgn I did an upgrade from Ubuntu 22.04 to 24.04 and the Ubuntu started normal at first boot but now it doesn't boot anymore. I need to start with a fresh 24.04 installation so I will be doing that today so I can't help you with link in 24.04 issues for some day(s).

Writing MDF files are little bit more challenging than reading. Unlike the MdfReader, the MdfWriter are designed for a specific purpose. It exist basically 3 version of the writer, MdfBasic, MdfBusLogger and MdfConverter.

If you are lucky and want to log (CAN) bus messages, the MdfBusLogger shall be used see also the CreateBusLogConfiguration() function will do most of the job. The MdfBasic converter is more general, requiring you to do most of the channel configuration. The MdfConverter shall be used in converter application i.e. your samples/values comes from a non-live source as a file. You may check the unit tests (testwrite.cpp) for examples.

If you need any MS Team meeting or similar, you can contact me in LinkedIn.

ihedvall commented 2 months ago

@csavorgn I'm up with Ubuntu 24.04. Please let me know if you still have compile/link problem.

csavorgn commented 2 months ago

@ihedvall Thank you for all the tips! What I want to do is saving data not coming from CAN, so I started modifying the code I found in the unit tests and I manage to write my first MDF file using mdflib! :) I need to figure out only one thing. I have quite big files to write and I'd like to save them with multiple saves to disk. How can I achieve this? Thank you again!

ihedvall commented 2 months ago

@csavorgn If you not saving bus messages, then it's no short cut regarding the MDF configuration but lets ignore this for the moment. The DG/CG/CN/CC block configuration is done before the InitMeasurement() call. That call saves the configuration to the disc and then starts an internal cache. The internal cache is used to temporary store sample records (defined by CG block) and also to handle the pre-trig time. Suppose that pre-trig time is set to 60 seconds. When you call StartMeasurement(), the 60 second cache + all new samples are stored onto the disc. Note that the MDF is opened, flushed sample and closed each 10 second, enabling another application to read the file.

The StopMeasurement() function just flush out the remaining samples to the disc and stops the cache. You should call the FinalizeMeasurement(). Optionally, you may attach video stream files and modify some configuration.

A sample is defined by a channel group (CG) and it's channels (CN). Each channel group normally have a master time channel defined (X-axis). In your code you should for each sample, set all CG channel values and the call the SaveSample() function with the sample (absolute) timestamp (nano-seconds since 1970). This timestamp is recalculated into a relative time , setting the master channel value, before saving it onto the disc.

There are some design issues to solve regarding large files.

  1. The current MDF should be created on a local drive and when its done, copied (rename actually) to a destination places. I assume that the destination is some sort of NAS drive. Writing direct to a NAS file fails 1 out of 10 times due to some write optimization. You need a block mode drive (SSD/SATA/iSCSI).
  2. Many MDF viewers read in the whole file into primary memory before actually parsing it. >10 GB files causes crashes for many GUI applications.

You can create large files with the MDF lib(rary) but files larger than 1-10 GB is not recommended. Enable compression storage is recommend. This give 1/5 of the file sizes. One measurement (DG) may have several channel groups i.e different time base.

csavorgn commented 2 months ago

@ihedvall I missed this part of the documentation of the MdfWriter class: "If compression is used the data is saved at the 4MB size or a 10 minute max. If not using compression, the samples are saved each 10 second." Everything I need is already done! I also read some of the code for MdfWriter and the writing is done by a separate thread. Perfect! Thanks again Carlo