I have compiled tesseract for using it in xcode following: http://iphone.olipion.com/cross-compilation/tesseract-ocr
I obtain the .a file, import it as framework in the iphone project, and update the header search path for tesseract header files.
So now I need a simple example in order to get start.
I can't find anything in http :// code.google.com/p/tesseract-ocr/ or by googling.
Anyone can help me give me a starting point (a code snippet)..?!
Many ThankS!
--
Later i found this code:
#include "baseapi.h"
TessBaseAPI::InitWithLanguage(NULL, NULL, language, NULL, false, 0, NULL);
char* text = TessBaseAPI::TesseractRect(imagedata, bytes_per_pixel,
bytes_per_line, 0, 0,
width, height);
TessBaseAPI::End();
but when I try to compile for device (only inserting include statement without the code above) i get the following:
error:syntax error before 'PAGE_RES'
warning:type defaults to 'int' in declaration of 'PAGE_RES'
warning:data definition has no type or storage class
and so on with BLOCK_LIST, IMAGE etc.
if compile for simulator i get
error: expected '=',',',','asm' or 'attribute' before 'PAGE_RES'
and so on with BLOCK_LIST, IMAGE and TessBaseAPI
--- Other Update:
I found solution for include problem:
Where the include occurs must be rename the file.m in .mm extension because we have to tell xcode that we have to use objective-c and c++ together.
http://github.com/nolanbrown/Tesseract-iPhone-Demo
OCRDemo is a demo application that utilizes the Tesseract library (http://code.google.com/p/tesseract-ocr/) as a static library compiled under Mac OS 10.6 using the shell script found at http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884.
The program is only meant to provide a demonstration of the OCR library and it’s abilities on the iPhone, the program is not optimized in any way...
you'll need to update SDKROOT, CPPFLAGS and CXX
variables. For example, here's the relevant part of my build script,
modified to work with 4.0:
export SDKROOT=$DEVROOT/SDKs/iPhoneOS4.0.sdk
export PATH=$DEVROOT/usr/bin:$PATH
# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/arm-apple-darwin10/4.0.1/
include/ -I$SDKROOT/usr/include/ -miphoneos-version-min=4.0"
export CFLAGS="$CPPFLAGS -arch armv6 -pipe -no-cpp-precomp -isysroot
$SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"
Dynamic library location generated by the Unix package
LIBPATH=$LIBFILE.dylib
LIBNAME=`basename $LIBPATH`
export LDFLAGS="-L$SDKROOT/usr/lib/ -Wl,-
dylib_install_name,#executable_path/$LIBNAME"
Static library that will be generated for ARM
LIBPATH_static=$LIBFILE.a
LIBNAME_static=`basename $LIBPATH_static`
# TODO: add custom flags as necessary for package
./configure CXX=$DEVROOT/usr/bin/arm-apple-darwin10-g++-4.0.1 CC=
$DEVROOT/usr/bin/arm-apple-darwin10-gcc-4.0.1 LD=$DEVROOT/usr/bin/ld --host=arm-apple-darwin
Related
I am currently learning STM32F103 with Eclipse. I am facing a problem in linker stage, that I got linker error : undefined reference to `HAL_TIM_Base_Init'
Building target: TimerTest.elf
Invoking: GNU ARM Cross C++ Linker
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -Wall -Wextra -g3 -T "C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\SW4STM32\WS2812_TimerTest\STM32F103C8Tx_FLASH.ld" -Xlinker --gc-sections -L"C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Src" -L"C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Drivers\STM32F1xx_HAL_Driver\Src" -L"C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Drivers\STM32F1xx_HAL_Driver\Inc" -L"C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Inc" -Wl,-Map,"TimerTest.map" -Xlinker --cref --specs=nano.specs -o "TimerTest.elf" ./Src/WS2812.o ./Src/main.o ./Src/stm32f1xx_hal_msp.o ./Src/stm32f1xx_hal_tim.o ./Src/stm32f1xx_it.o ./Src/system_stm32f1xx.o ./Src/usb_device.o ./Src/usbd_cdc_if.o ./Src/usbd_conf.o ./Src/usbd_desc.o ./SW4STM32/startup_stm32f103xb.o ./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.o ./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.o ./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.o ./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.o ./Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.o
./Src/WS2812.o: In function `WS2812Init':
C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Debug/../Src/WS2812.c:30: undefined reference to `HAL_TIM_Base_Init'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:64: TimerTest.elf] Error 1
Here is my code:
main.c
#include "main.h"
#include "WS2812.h"
#include "stm32f1xx_hal.h"
#include "usb_device.h"
int main(void)
{
WS2812Init();
while (1)
{
}
}
WS2812.h:
#ifndef INC_WS2812_H_
#define INC_WS2812_H_
#include <stm32f1xx_hal_gpio.h> // use gpio output
#include <stm32f1xx_hal_rcc.h>
#include <stm32f1xx_hal_tim.h> // use timer
// adopt gpio port & pin for following section
#define WS2812_GPIO_PORT GPIOB
#define WS2812_GPIO_PIN GPIO_PIN_12
#define ENABLE_GPIO_RCC() do{\
if(!__HAL_RCC_GPIOB_IS_CLK_ENABLED())\
__HAL_RCC_GPIOB_CLK_ENABLE();\
}while(0U)
static GPIO_InitTypeDef SW2812Pin = {
.Pin = WS2812_GPIO_PIN,
.Speed = GPIO_SPEED_FREQ_LOW,
.Mode = GPIO_MODE_OUTPUT_PP
};
#define SYS_CLOCK
// adopt timer configuration for following section
#define WS2812_SELECTED_TIMER TIM4
static TIM_HandleTypeDef ws2812TimerConfig;
void WS2812Init(void);
#endif /* INC_WS2812_H_ */
WS2812.c:
#include "WS2812.h"
void WS2812Init(void)
{
// init GPIO as output
ENABLE_GPIO_RCC();
HAL_GPIO_WritePin(WS2812_GPIO_PORT, WS2812_GPIO_PIN, GPIO_PIN_RESET);
HAL_GPIO_Init(WS2812_GPIO_PORT, &SW2812Pin);
// init timer
uint16_t targetFrequency = 1000; // 1kHz
const uint16_t preScaler = 360;
const uint16_t period = SystemCoreClock / (preScaler*targetFrequency);
// clear status register
__HAL_RCC_TIM4_CLK_ENABLE();
ws2812TimerConfig.Instance = WS2812_SELECTED_TIMER;
ws2812TimerConfig.Init.Prescaler = preScaler - 1;
ws2812TimerConfig.Init.Period = period;
ws2812TimerConfig.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&ws2812TimerConfig); // <- linker can not find this function
__HAL_TIM_ENABLE(&ws2812TimerConfig);
}
This is my include structure:
main->
include"WS2812.h" ->
include stm32f1xx_hal_tim.h
The stm32f1xx_hal_tim.h is in the STM32F1xxHAL_DRIVER->inc, which is also put in the include path.
I also have added the include path in the project properties->C/C++ Build->Settings
for
GNU ARM Cross Assembler
GNU ARM Cross C compiler
GNU ARM Cross C++ Compiler
I searched in the internet found out this is a linker issue, that the linker can not find the proper source for linking.
What I have found in internet and tried:
added the folder which contents stm32f1xx_hal_tim.h and WS2812.h to project properties-> C/C++ Build -> GNU ARM Cross C++ Linker -> Libraries -> (-L)
added the folder which contents stm32f1xx_hal_tim.c and WS2812.c to project properties-> C/C++ Build -> GNU ARM Cross C++ Linker -> Libraries -> (-L)
Checked "stm32f1xx_hal_tim.h" -> property-> Exclude resource from build is unchecked (some people in the internet solved the problem by this)
Added "--specs=nano.specs" to the Linker options
All of above do not solve the problem.
Some people suggest to modify the makefile. But the project generate the makefile automatically, so I don't know where to start.
If anyone can provide a hint or solution, it will be very thanksful.
UPDATE 1:
Thanks Jacek Ślimok's input.
I didn't know that, I also need to doe the "exclude from build" for .c files. And I check in the file browser. The .c files are not check in this configuration. Do you mean like this?
excluded from Build
The stm32f1xx_hal_tim.c is under project->Driver->STM32F1xxHAL_Driver->Src
At this moment, the problem remains unsolved.
Another thing I noticed is that, the Eclipse read my stm32f1xx_hal_tim.c differently. When I open the stm32f1xx_hal_tim.c in Eclipse, it just give me a plane text like in normal notepad:
stm32f1xx_hal_tim.c
But other .c file like stm32f1xx_hal_gpio.c looks like normal.
stm32f1xx_hal_gpio.c
They are in the same folder. I don't know where and why this difference came from. Does this relative to my problem.
Update2
#Jacek Ślimok, I found out why the eclipse see the stm32f1xx_hal_tim.c as plane text. I accidentally turned on the Scalability setting in Preference-> Editor, stm32f1xx_hal_tim.c has relatively large file size, 161kB. After I change it back to default, Eclipse shows the file as normal. But the linker problem is still there...
In the main.c I also used HAL_GPIO_TogglePin() from stm32f1xx_hal_gpio.h/.c. The linker does not complain about that. Currently I can not tell the difference between these 2 files(stm32f1xx_hal_gpio and stm32f1xx_hal_tim) They are in the same folder, and included the same as well. But I can use the function for GPIO not for Timer.
But one thing can be sure:
I can use the macro in the stm32f1xx_hal_tim.h, so this is a linker problem.
I start this project base on another project, which was generated from STM32CubeMX. To practice the timer function I added the timer config to it, this is the point I got problem with the linker.
I hope these information can lead to more hints.
Update 3
I tried build the .c files separately
For stm32f1xx_hal.h.c:
00:09:16 **** Building Selected Files of configuration Release for project TimerTest ****
Info: Internal Builder is used for build
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -Wall -Wextra -g -DSTM32F103xB -DHSE_VALUE=8000000 "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Device\\ST\\STM32F1xx\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\STM32F1xx_HAL_Driver\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Class\\CDC\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Core\\Inc" -std=gnu11 -c -o "Drivers\\STM32F1xx_HAL_Driver\\Src\\stm32f1xx_hal_tim.o" "..\\Drivers\\STM32F1xx_HAL_Driver\\Src\\stm32f1xx_hal_tim.c"
00:09:17 Build Finished (took 285ms)
For WS2812.c:
00:11:23 **** Building Selected Files of configuration Release for project TimerTest ****
Info: Internal Builder is used for build
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -Wall -Wextra -g -DSTM32F103xB -DHSE_VALUE=8000000 "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Device\\ST\\STM32F1xx\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\STM32F1xx_HAL_Driver\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Class\\CDC\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Core\\Inc" -std=gnu11 -c -o "Src\\WS2812.o" "..\\Src\\WS2812.c"
00:11:23 Build Finished (took 275ms)
And for Main.c:
00:12:02 **** Building Selected Files of configuration Release for project TimerTest ****
Info: Internal Builder is used for build
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -Wall -Wextra -g -DSTM32F103xB -DHSE_VALUE=8000000 "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\CMSIS\\Device\\ST\\STM32F1xx\\Include" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Drivers\\STM32F1xx_HAL_Driver\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Class\\CDC\\Inc" "-IC:\\Users\\Gebruiker\\Dropbox\\CodeBase\\Eclipse\\TimerTest\\Middlewares\\ST\\STM32_USB_Device_Library\\Core\\Inc" -std=gnu11 -c -o "Src\\main.o" "..\\Src\\main.c"
..\Src\main.c: In function '_Error_Handler':
..\Src\main.c:268:27: warning: unused parameter 'file' [-Wunused-parameter]
void _Error_Handler(char *file, int line)
^~~~
..\Src\main.c:268:37: warning: unused parameter 'line' [-Wunused-parameter]
void _Error_Handler(char *file, int line)
^~~~
In file included from ..\Src\main.c:55:0:
At top level:
C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Inc/WS2812.h:36:26: warning: 'ws2812TimerConfig' defined but not used [-Wunused-variable]
static TIM_HandleTypeDef ws2812TimerConfig;
^~~~~~~~~~~~~~~~~
C:\Users\Gebruiker\Dropbox\CodeBase\Eclipse\TimerTest\Inc/WS2812.h:26:25: warning: 'SW2812Pin' defined but not used [-Wunused-variable]
static GPIO_InitTypeDef SW2812Pin = {
^~~~~~~~~
00:12:02 Build Finished (took 272ms)
There are few warning in the main.c, but they are not crucial.
Update4:
Thanks for Jacek Ślimok's input:
I found out that functions of stm32f1xx_hal_tim.c shows gray in file browser.
functions seems like not usable
But the functions in stm32f1xx_hal_gpio.c shows solid balck.
function in gpio.c are usable
Now the difference is there, just need to find out why.
Thanks in advance.
Best regards.
Doing #include stm32f1xx_hal_tim.h is not enough - it only causes your compiler not to complain, linker will still have a problem. Neither is adding a search path for the linker - this one you use mainly when you have static pre-compiled libraries that you explicitly link with the -l option. HAL is not a static library but rather a library you compile yourself.
To solve your problem, make sure you compile the corresponding source files - in this case stm32f1xx_hal_tim.c file and that it's later being linked. You mention that you use Eclipse and by default it generates a Makefile that causes all source files that you compiled in your project to also be linked. Therefore you mainly should check whether stm32f1xx_hal_tim.c is being compiled. One way to do that is to find the file in the Project Explorer, rightclick on it and select Resource Configurations -> Exclude from Build.... Make sure it's NOT checked. If it is, it is likely a whole directory is excluded from build which it should not be.
Another possibility is given function not being defined in any source file that is compiled or the function signature (name, return type and parameter types) don't match.
Yet another possibility (which in this case turned out to be the source of the issue) is that a portion of the file may not be compiled due to a #if/#ifdef preprocessor directive. In the OP's case this was caused by HAL_TIM_MODULE_ENABLED being undefined.
It is not relative to linker issue, but pre-processor.
As I mentioned, that I am building this code based on a project, which was generated from cubeMX. In the previous project, there is no timer used or configured. Than I started to write timer configuration. What I forgot is that to uncomment the #define HAL_TIM_MODULE_ENABLED in stm32f1xx_hal_conf.h. Which blocked all the implementation in stm32f1xx_hal_tim.c by pre-processor.
That is why eclipse shows all the function in stm32f1xx_hal_tim.c as gray color and not be able to be referenced.
And anyway, thanks Jacek Ślimok's effort!
Agree with Jacek Slimok, had this problem a while back, and for some reason I keep forgetting how to fix it. Googling the same solution every time if becoming annoying.
Just Skip to Solution
So you hit ctrl+space and autocomplete locates the function you want to call.
Yet in build, errors show up as "undefined reference to YOUR_FUNCTION_NAME".
So, you compile dependencies to become object files, but link object files to form an executable "firmware" generated by the compiler.
The "undefined reference" function called in main supposed to come from an object file which the linker can't locate.
Eclipse has a feature that allows you to exclude certain files from being "built" into object files. Thus the linker can't locate that dependency.
Solution:
This works for added folders or individual files in Eclipse.
So you have .c and .h files you created and you sometimes lump them in a folder you added to eclipse.
Right-click that added folder and hit properties.
In left menu select "Settings" under "C/C++ Build".
On the right, uncheck "Exclude resource from build".
Link to the picture below.
Folder Properties window in Eclipse:
Hope that helps everyone, and myself when I forget in a few days. Can you imagine the shock when I see my name on this post?
I am trying to compile a source file with icc compiler and MAGMAmic library. However I get the following error:
icc -c -o direct.o direct.c -O3 -openmp -DADD_ -Wall -DHAVE_MIC -I/opt/intel/mic/coi/include -I/usr/include/intel-coi -I/opt/intel/compilers_and_libraries_2017.2.174/linux/mkl/include:/opt/intel/compilers_and_libraries_2017.2.174/linux/ipp/include:/opt/intel/compilers_and_libraries_2017.2.174/linux/mkl/include:/opt/intel/compilers_and_libraries_2017.2.174/linux/tbb/include:/opt/intel/compilers_and_libraries_2017.2.174/linux/daal/include -I/home/dslavchev/install/magmamic-1.4.0/include -I/home/dslavchev/install/magmamic-1.4.0/contol
icc: command line remark #10411: option '-openmp' is deprecated and will be removed in a future release. Please use the replacement option '-qopenmp'
In file included from /home/dslavchev/install/magmamic-1.4.0/include/magma_types.h(134),
from /home/dslavchev/install/magmamic-1.4.0/include/magmablas_z.h(17),
from /home/dslavchev/install/magmamic-1.4.0/include/magmablas.h(12),
from /home/dslavchev/install/magmamic-1.4.0/include/magma.h(17),
from direct.c(21):
/opt/intel/compilers_and_libraries_2017.2.174/linux/compiler/include/complex(30): catastrophic error: cannot open source file "complex"
#include_next <complex>
^
The MAGMAmic library has compiled correctly and I can run it's test ok.
I have looked at the way testing_dgesv_mic.cpp example compiles and used the same includes and link, however in my case I get the above error.
I have added the following in my .bashrc file in order to get the Intel compilers' and libraries' enviromental variables:
#for MAGMA mic
export MAGMA_PATH=/home/dslavchev/install/magmamic-1.4.0
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/mkl/bin/mklvars.sh intel64
Any ideas what might cause icc to be unable to include the "complex" file?
The file complex really exists in "/opt/intel/compilers_and_libraries_2017.2.174/linux/compiler/include/complex"
icc vesrion is:
[dslavchev#sl051 results]$ icc -v
icc version 17.0.2 (gcc version 4.4.7 compatibility)
magmamic version is magmamic-1.4.0
EDIT: Removed unnecessary code comment
EDIT2: Added version info.
MAGMAmic is a C++ library and it cannot be used with C code directly.
When icc detects that you want to compile .c++ file it automatically switches to icpc (Intel C++ compiler) which in turn results in the above error.
Solution: Either switch to icpc or rename your files to .c++
This question was answered by mark on the MAGMA forums. Link:
http://icl.cs.utk.edu/magma/forum/viewtopic.php?f=2&t=1587&p=4442#p4442
I'm currently attempting to make an existing project to link statically to its main dependency in order to reduce size of the resulting output library. The project I'm trying to change is Tesseract OCR that depends on Leptonica image processing library.
At the time being, Leptonica counts 2481 functions but Tesseract uses only 163 of them. In other words, only 6,6% of Leptonica functionality is used in Tesseract but the whole bunch of code (3,5 MB + additional libraries) will be loaded and kept in memory. It's probably not an issue at all for desktop systems. But on mobile devices with limited memory, it's too costly to have several MBs occupied by unused code.
I hope to reduce the overall size of this Tesseract+Leptonica couple using static linking. Both projects utilize autoconfig/automake/libtool build system.
Leptonica's build produces both static and dynamic libraries. Tesseract uses the following line in its configure.ac in order to declare Leptonica dependency:
AC_CHECK_LIB(lept,pixCreate,[],AC_MSG_ERROR([Leptonica library missing]))
Because the above mentioned line does add Leptonica automatically to $LIBS, I've changed this as follows:
AC_CHECK_LIB(lept,pixCreate,[LIBS="-Bstatic -llept -Bdynamic $LIBS"],AC_MSG_ERROR([Leptonica library missing])))
When I run ./configure and make, everything goes right but Tesseract will still be dynamically linked to Leptonica.
While examining the corresponding make log, I noticed that the g++ linking invocation simply ignores my "-Bstatic" attribute and links to the shared library (liblept.so) instead:
libtool: link: g++ -m32 -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crti.o /usr/lib/gcc/i686-linux-gnu/4.8/crtbeginS.o -Wl,--whole-archive ./.libs/libtesseract_api.a ../ccmain/.libs/libtesseract_main.a ../cube/.libs/libtesseract_cube.a ../neural_networks/runtime/.libs/libtesseract_neural.a ../textord/.libs/libtesseract_textord.a ../wordrec/.libs/libtesseract_wordrec.a ../classify/.libs/libtesseract_classify.a ../dict/.libs/libtesseract_dict.a ../ccstruct/.libs/libtesseract_ccstruct.a ../cutil/.libs/libtesseract_cutil.a ../viewer/.libs/libtesseract_viewer.a ../ccutil/.libs/libtesseract_ccutil.a ../opencl/.libs/libtesseract_opencl.a -Wl,--no-whole-archive -Wl,-rpath -Wl,/home/maxpol/Dokumente/javacpp-presets-myfork/tesseract/cppbuild/linux-x86/lib -Wl,-rpath -Wl,/home/maxpol/Dokumente/javacpp-presets-myfork/tesseract/cppbuild/linux-x86/lib -L/home/maxpol/Dokumente/javacpp-presets-myfork/tesseract/cppbuild/linux-x86/lib/ -lz /home/maxpol/Dokumente/javacpp-presets-myfork/tesseract/cppbuild/linux-x86/lib/liblept.so -lpthread -L/usr/lib/gcc/i686-linux-gnu/4.8 -L/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu -L/usr/lib/gcc/i686-linux-gnu/4.8/../../../../lib -L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/i686-linux-gnu/4.8/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/i686-linux-gnu/4.8/crtendS.o /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crtn.o -m32 -pthread -Wl,-soname -Wl,libtesseract.so.3 -o .libs/libtesseract.so.3.0.4
I've already consulted the autotools docs and several other projects but couldn't find anything helpful. Therefore I decided myself to ask this question here.
Am I missing something important?
Thank you very much in advance for your help!
Best regards
Max
I use Eclipse + ARM plugin to build my projects. When I needed to use in my project the StemWin library, I configured my IDE to use external library.
I set
Preferences -> C/C++ General -> Paths and Symbols
I added in "Library Paths" the link to my folder includes library.
I also added the name of my library in tab "Library".
I checked the settings in the compiler tab and I ascertained all should be good.
When I tried to build my project I got an error from linker:
cannot find -lMyLib.a Hello C/C++ Problem
I double checked the name of my library and link, all are correct. This is the output of my linker:
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -L"C:\lib"
-T"C:\arm_toolchain\stm32_workspace\Hello\LinkerScript.ld" -Wl,
-Map=output.map -Wl,--gc-sections -o "Hello.elf" #"objects.list" -lMyLib.a
What should I do from here?
I faced the same problem before.
-l:STemWin526_CM4_GCC.a
-L"C:\Edu_Workspace\STM32F4\stm32f4_bsp_template\Drivers\Middlewares\ST\STemWin\Lib"
Above are my working settings.
With -l:<archive file name> the colon : is important for archive file linking.
And -L will contain library path.
Also for stemwin make sure to compile with hardware floating point
-mfloat-abi=hard -mfpu=fpv4-sp-d16
the convention for the -l option of the linker (say you give -lMyLib.a as a linker option) is to search for a library file with "lib" prepended to the given name and .a (or .so) appended, i.e. your command line searches for a file libMyLib.a.{a,so} which is probably not how it's named.
Either you rename your library according to this convention or give it to the linker command line omitting -l (provided your IDE allows you to do so).
Looks like the problem is in -lMyLib.a which means you're trying to link a static library as a dynamic one.
To link a static lib you have to use its path as with ordinary .o files: ... /path/to/MyLib.a
and the resulting command line should look something like
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -L"C:\lib" -T"C:\arm_toolchain\stm32_workspace\Hello\LinkerScript.ld" -Wl,-Map=output.map -Wl,--gc-sections -o "Hello.elf" #"objects.list" /path/to/MyLib.a
UPDATE:
Although it might fix the issue, turns out it's not true:
-llibrary
-l library
...
Normally the files found this way are library files—archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with ‘lib’ and ‘.a’ and searches several directories.
(https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html)
I have a set of iPhone static libraries (a *.a file) in which I only call a few of the classes from.
I have used AR in the past (with linux libraries) to extract the object files from the static library, remove the unwanted object files and rearchive.
However, when I try this with an iPhone compliled static library, I get the following error:
ar: CustomiPhoneLib.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: CustomiPhoneLib.a: Inappropriate file type or format
Does anyone know how to extract the object files from an iphone compiled static library? Doing thie could potentially reduce the final file size.
That’s because your CustomiPhoneLib.a is a fat library, i.e., a library that contains more than one target architecture, namely armv6 and armv7 on iOS. You can use lipo to extract a specific architecture into another .a file, use ar and ranlib to manipulate it at will, and then use lipo again to recombine the manipulated .a files into a single .a fat file. For instance,
lipo CustomiPhoneLib.a -thin armv6 -output CustomiPhoneLibarmv6.a
lipo CustomiPhoneLib.a -thin armv7 -output CustomiPhoneLibarmv7.a
### use ar and ranlib at will on both files
mv CustomiPhoneLib.a CustomiPhoneLib.a.original
lipo CustomiPhoneLibarmv6.a CustomiPhoneLibarmv7.a -create -output CustomiPhoneLib.a
However, you don’t have to do this for the reason you’ve mentioned. The linker will only pull object (.o) files from a library (.a) if it needs to resolve some symbol reference. Therefore, if a library contains an object file whose symbols are never referenced during the linking process (i.e., symbols that are not effectively used), that object file won’t make it into the executable.
Code:
ar -t mylib.a
This will list all of the files in the archive.
Code:
ar -xv mylib.a myobj.o
This will extract the object give myobj.o from the library mylib.a.