How do I link a third party dylib in a Mac OS X app using XCode 4.5? "Undefined symbols" error - xcode4

I'm trying to use functions defined in a third-party dynamic library (libmysql) in a desktop app for Mac OS X. I'm using XCode 4.5.1 on Mac OS X v. 10.8.2.
Here's what I've done so far:
1) I downloaded the Mac OS X 10.5 x86 64-bit C connector files from http://dev.mysql.com/downloads/connector/c/ (this is the most recent version available).
2) I copied the files from the disk image to a local directory.
3) I added the path to that local directory to my project's Build Settings->Search Paths->User Header Search Paths and set "Always Search User Paths" to "Yes"
4) I added libmysql.client to Build Phases->Copy Files
5) I added libmysql.client to Copy Bundle Resources
6) I wrote a test function in my code:
#import "mysql.h"
-(NSNumber*)testFunction {
mysql_library_init(0, NULL, NULL);
mysql_library_end();
return [NSNumber numberWithInt:8];
}
The project compiles (target:My Mac 64-bit), but I get "Undefined symbols for architecture x86_64" errors for the two mysql functions from the linker. Here is the full error message:
Ld "/Users/chapka/Library/Developer/Xcode/DerivedData/The_Single_Table_Admin_Tools-ctdgurwiktybjqcnlfuufetgimfy/Build/Products/Debug/The Single Table Admin Tools.app/Contents/MacOS/The Single Table Admin Tools" normal x86_64
cd "/Users/chapka/Documents/Developer/The Single Table/The Single Table Admin Tools"
setenv MACOSX_DEPLOYMENT_TARGET 10.8
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/chapka/Library/Developer/Xcode/DerivedData/The_Single_Table_Admin_Tools-ctdgurwiktybjqcnlfuufetgimfy/Build/Products/Debug "-L/Users/chapka/Documents/Developer/The Single Table/The Single Table Admin Tools" "-L/Users/chapka/Documents/Developer/The Single Table/The Single Table Admin Tools/The Single Table Admin Tools" "-L/Users/chapka/Documents/Developer/The Single Table/The Single Table Admin Tools/../../Libraries/mysql" -F/Users/chapka/Library/Developer/Xcode/DerivedData/The_Single_Table_Admin_Tools-ctdgurwiktybjqcnlfuufetgimfy/Build/Products/Debug -filelist "/Users/chapka/Library/Developer/Xcode/DerivedData/The_Single_Table_Admin_Tools-ctdgurwiktybjqcnlfuufetgimfy/Build/Intermediates/The Single Table Admin Tools.build/Debug/The Single Table Admin Tools.build/Objects-normal/x86_64/The Single Table Admin Tools.LinkFileList" -mmacosx-version-min=10.8 -fobjc-arc -fobjc-link-runtime -framework Cocoa -o "/Users/chapka/Library/Developer/Xcode/DerivedData/The_Single_Table_Admin_Tools-ctdgurwiktybjqcnlfuufetgimfy/Build/Products/Debug/The Single Table Admin Tools.app/Contents/MacOS/The Single Table Admin Tools"
Undefined symbols for architecture x86_64:
"_mysql_server_end", referenced from:
-[TSTDataSource gameCount] in TSTDataSource.o
"_mysql_server_init", referenced from:
-[TSTDataSource gameCount] in TSTDataSource.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've looked around for other questions like this, but they all seem to be solved by steps 4 and/or 5 above. The only other suggestion I found was to use install_name_tool, but I'm not sure what exactly I would need to change or what I would need to change it to. If this is the likely issue, any hints would be more than welcome.

Related

Intel oneAPI dpcpp compiler with google test

I'm kinda new to the world of Intel's HPC toolchain and I'm facing some troubles making even simple DPC++ application to work when gtest is used as a testing framework
This is the CMakeLists "structure" I'm following
cmake_minimum_required(VERSION 3.14)
project(foo)
set(CMAKE_CXX_COMPILER "dpcpp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O3 -fsycl")
# add executables
# target linked libraries
# ...
option(ENABLE_TESTS ON)
if(ENABLE_TESTS)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_subdirectory(tests)
endif()
If I remove the last block, it compiles and runs as expected, otherwise I get the following error:
CMake Error at build/_deps/googletest-src/CMakeLists.txt:10 (project):
The CMAKE_CXX_COMPILER:
dpcpp
is not a full path and was not found in the PATH.
Tell CMake where to find the compiler by setting either the environment
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
to the compiler, or to the compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred!
See also "/home/u141905/foo/build/CMakeFiles/CMakeOutput.log".
See also "/home/u141905/foo/build/CMakeFiles/CMakeError.log".
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_CXX_COMPILER= /usr/bin/c++
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
make: *** [Makefile:2: all] Error 1
Please notice that dpcpp is correctly set, in fact I'm using Intel's devcloud platform.
Setting CXXto the output of whereis dpcpp produces the same error.
The only "workaround" (I doubt it is one though) I found is using clang++ instead (the version from Intel's llvm). Any help or suggestion is much appreciated, thanks in advance!
EDIT: after some more attempts, I noticed that if I set CMAKE_CXX_COMPILER just after fetching gtest, everything works fine. Anyway I don't understand why this happens and how can be properly fixed.
Use the path for dpcpp binary for setting the CMAKE_CXX_COMPILER instead of using"set(CMAKE_CXX_COMPILER "dpcpp")". After adding the path("/opt/intel/oneapi/compiler/2022.0.1/linux/bin/dpcpp") to the CMAKE_CXX_COMPILER, you can run the program successfully.
Please find the below CMakeLists.txt for setting the CMAKE_CXX_COMPILER:
project(foo)
set(CMAKE_CXX_COMPILER "/opt/intel/oneapi/compiler/2022.0.1/linux/bin/dpcpp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O3 -fsycl")
# add executables
# target linked libraries
# ...
set(ENABLE_TESTS ON)
include(FetchContent)
if(ENABLE_TESTS)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_subdirectory(tests)
endif()
Thanks & Regards,
Hemanth
Did you run the source /opt/intel/oneapi/setvars.sh intel64 script? I.e. is dpcpp on your path before running cmake?

Robotframework, AutoIt: Error message "No keyword with name 'Send' found"

I'm trying to get familiar with the robotframework using autoitlibrary to test Windows applications. I found some examples which use the Send command to type text into a notpad window.
That's what I've done so far:
*** Settings ***
Library AutoItLibrary
*** Variables ***
${app} C:/Program Files/Notepad++/notepad++.exe
*** Test Cases ***
Enter text
Run ${app}
Win Wait Active new 1 - Notepad++
Send This is just a test.
So, the Notepad++ window is opened, but then it failed with the No keyword with name 'Send' found. message. I suppose there is no Send command in the AutoItLibrary, but I also cannot find any other command which may do this job.
AutoIt is installed, and so is the wrapper by pip install robotframework-autoitlibrary.
There really exists a Send keyword in AutoIt, but supposedly not in the wrapper for robotframework.
And ideas to fix this?
UPDATE: Windows 10 (64bit in a VirtualBox), Python v3.7.6 (32bit), RF v3.1.2, RF-AutoItLibrary v1.2.4, AutoIt v3.3.14.5
The "Search Keywords" dialog in RIDE provides AutoItLibrary as a Source, but then list only a few commands. So I suppose the library is accessible, but incomplete.
import os, re, subprocess, sys
# Set path to Python directories.
programfiles = os.environ['programfiles']
if not programfiles:
exit('Failed to get programfiles')
python_dirs = [os.path.join(programfiles, 'Python35'),
os.path.join(programfiles, 'Python36'),
os.path.join(programfiles, 'Python37'),
os.path.join(programfiles, 'Python38')]
# Process each python directory.
for python_dir in python_dirs:
print('---')
# Set path to AutoItX3.dll.
autoitx_dll = os.path.join(python_dir, r'Lib\site-packages\AutoItLibrary\lib\AutoItX3.dll')
if not os.path.isfile(autoitx_dll):
print('File not found: "' + autoitx_dll + '"')
continue
# Set path to the makepy module.
makepy = os.path.join(python_dir, r'Lib\site-packages\win32com\client\makepy.py')
if not os.path.isfile(makepy):
print('File not found: "' + makepy + '"')
continue
# Generate cache using make.py.
command = [os.path.join(python_dir, 'python.exe'), makepy, autoitx_dll]
with subprocess.Popen(command, stderr=subprocess.PIPE, cwd=python_dir, universal_newlines=True) as p:
stderr = p.communicate()[1]
print(stderr.rstrip())
parameters = re.findall(r'^Generating to .+\\([A-F0-9\-]+)x(\d+)x(\d+)x(\d+)\.py$', stderr, re.M)
if len(parameters) == 1:
parameters = parameters[0]
print('Insert the next line into AutoItLibrary.__init__.py if not exist.\n'
' win32com.client.gencache.EnsureModule("{{{guid}}}", {major}, {minor}, {lcid})'
.format(guid=parameters[0],
major=parameters[1],
minor=parameters[2],
lcid=parameters[3]))
# Pause so the user can view the subprocess output.
input('Press the return key to continue...')
The generated cache done by win32com\client\makepy.py for AutoItLibrary from the setup.py is saved in the %temp%\gen_py folder. This is done only when setup.py is executed. If the %temp% directory is cleaned later, which removes the cache, then I notice keywords like Send may fail to be recognized by the robotframework.
One solution appears to be regenerating the cache. The code above will generate the cache by use of makepy.py. It may also print a message about inserting win32com.client.gencache.EnsureModule(...) into AutoItLibrary\__init__.py for any of the Python versions as needed. This will ensure the cache is available when AutoItLibrary
is imported.
Change paths in the code to suit your environment.
With further research:
AutoItLibrary currently has AutoItX 3.3.6.1 and latest AutoIt has AutoItX 3.3.14.5. Important to know as one version registered can overwrite the registration of the previous registration.
AutoItLibrary currently registers AutoIt3X.dll without the _x64 suffix on the name on x64 systems. I may reference AutoIt3_x64.dll to define difference between x86 and x64.
Any version of AutoIt3X.dll and AutoIt3_x64.dll uses the same ID codes and the last registered wins (based on bitness as both x86 and x64 registrations can co-exist).
The TypeLib class key registered ID is {F8937E53-D444-4E71-9275-35B64210CC3B} and is where win32com may search.
If AutoIt3X.dll and AutoIt3_x64.dll are registered, unregister any 1 of those 2 will remove the AutoItX3.Control class key. Without this key, AutoIt3X will fail as AutoItLibrary needs this key. To fix, register again e.g. regsvr32.exe AutoIt3X.dll as admin in the working directory of AutoIt3X.dll.
The methods of any same version of AutoItX will match i.e. AutoIt3X.dll and AutoIt3X_x64.dll only changes in bitness, not methods.
Inserting win32com.client.gencache.EnsureModule("{F8937E53-D444-4E71-9275-35B64210CC3B}", 0, 1, 0) into AutoItLibrary\__init__.py should ensure the cache is always available for any AutoItX version. The initial code can be used to generate the cache, though the suggested change in AutoItLibrary\__init__.py makes it obsolete as the cache is generated on import of AutoItLibrary. If the ID was not constant, then the initial code may inform you of the ID to use.
The cache is important as it has generated .py files with methods like e.g.:
def Send(self, strSendText=defaultNamedNotOptArg, nMode=0):
'method Send'
# etc...
which if missing, makes Send and many others, an invalid keyword in AutoItLibrary.
If AutoItX 3.3.14.5 is registered, the - leading methods are removed and the + leading methods are added as compared to AutoItX 3.3.6.1:
-BlockInput
-CDTray
-IniDelete
-IniRead
-IniWrite
-RegDeleteKey
-RegDeleteVal
-RegEnumKey
-RegEnumVal
-RegRead
-RegWrite
-RunAsSet
+RunAs
+RunAsWait
So if any of those methods causes error, then you may want AutoItX 3.3.6.1 registered instead. In the AutoItX history, 3.3.10.0 release is when those method changes happened.
Fix:
Check your python architecture ( is it 32 or 64 bit)
For 32:
Open cmd in "Run as administrator" mode
run the command pip install robotframework-autoitlibrary
Now clone the autoit library source code:
https://github.com/nokia/robotframework-autoitlibrary
in the root directory run the below command: python setup.py install using cmd in admin mode
to navigate to root directory use the command pushd <filepath>' instead ofcd ` if cd doesn't work in cmd opened in admin mode.
For 64:
Open cmd in "Run as administrator" mode
Now clone the autoit library source code:
https://github.com/nokia/robotframework-autoitlibrary
in the root directory run the below command: python setup.py install using cmd in admin mode
to navigate to root directory use the command pushd <filepath>' instead ofcd ` if cd doesn't work in cmd opened in admin mode.

Missing symbol on libQt5Dbus.so.5?

I have a python application that uses QT5.
I'm generating a binary for this app with pyinstaller (so that all the dependencies are bundled). This app is built from a Centos6.8 docker instance (for compatibility reasons) with a patched-in GLIBC that QT5 needs.
When I run the application it fails with the bundled libQt5Dbus.so.5 not having the symbol dbus_connection_can_send_type:
symbol lookup error: /tmp/_MEIyxSbsB/libQt5DBus.so.5: undefined symbol: dbus_connection_can_send_type
When I do nm -D /path/to/libQt5Dbus.so.5 on the Centos6.8 docker instance doesn't show the symbol I need (dbus_connection_can_send_type).
What can I do to get the symbol in a libQt5Dbus.so.5?
EDIT:
I have found that one of the libQt5Dbus.so.5 library in my system does actually have dbus_connection_can_send_type symbol. I've replaced all libQt5Dbus.so.5 libraries with the one that does have the symbol and I still get the error.
The problem I had was the minimum GLIBC required by QT5 (GLIBC 14) does not define the symbol dbus_connection_can_send_type (among others).
Upgrading it to GLIBC 17 makes it work again.

Use qjson in my Qt symbain app

I'm using Qt to develop a Symbian app.
I downloaded qjson from the link. I followed the instructions in that link and yes, I have the qjson.sis file. Now I need to use it in my app. When I tried, I got this error.
Launch failed: Command answer [command error], 1 values(s) to request: 'C|101|Processes|start|""|"MyProject.exe"|[""]|[]|true'
{"Code":-46,Format="Failed to create the process (verify that the executable and all required DLLs have been transferred) (permission denied)"}
Error: 'Failed to create the process (verify that the executable and all required DLLs have been transferred) (permission denied)' Code: -46
And when I press the launch icon, it shows, "Unable to execute file for security reasons".
Then I install the qjson.sis in my mobile and then tried to install my app, I got this error.
:-1: error: Installation failed: 'Failed to overwrite file owned by another package: c:\sys\bin\qjson.dll in ' Code: 131073; see http://wiki.forum.nokia.com/index.php/Symbian_OS_Error_Codes for descriptions of the error codes
In my .pro file I have this.
symbian: {
addFiles.sources = qjson.dll
addFiles.path = /sys/bin
DEPLOYMENT += addFiles
}
symbian: {
LIBS += -lqjson
}
Any ideas...?
Ok, I've just resolved a similar issue: it seems that your current build of QJson's library has different UID3 than the previous one that you installed on the phone.
Each .SIS file that is installed on the device has an identifier. The phone OS tracks which file was installed by which packacge, and if some new package wants to overwrite an existing file, the OS checks whether the new package has the same 'identity' than the previous owner of the file to be overwritten.
If the identity does not match, this error pops up.
There are number of reasons why this could have happened. For example, you could have simply changed the UID3 of the QJson before the build. Or, maybe you have forgot to set the library's UID3? Check the "src.pro' in the QJson project and go to the half of the file, you'd see lines:
#TARGET.UID3 =
TARGET.CAPABILITY = ReadDeviceData WriteDeviceData
If there's #, then you have forgot to set it and the build process assumed, well, letssay 'a random value'. So, now, set it to something, ie. TARGET.UID3 = 0xE0123456. Remember to correct that once you are ready to publish the application.
If a package with broken UID3 gets onto your phone and is blocking something - simply: uninstall it. Go to Settings/Installations/Installed, then find "qjson" and uninstall it. Afterwards, next installtion of qjson should succeed with no problems.

illegal text reloc to non_lazy_ptr error while building in xcode 4 with libav* libraries

I'm trying to build a simple application that uses ffmpeg's libav* libraries in xcode 4 and getting the following error:
ld: illegal text reloc to non_lazy_ptr from /ffmpeg/temp/ffmpeg-0.8/builduni/lib/libavcodec.a(ac3.o) in _ff_ac3_bit_alloc_calc_psd for architecture i386
I've already tried to run ranlib -c libavcodec.a to fix this problem, but nothing happend.
One more thing: my libav* libraries are fat binaries (i386 + x86_64).
Any ideas what can it be?
I have the same error. Finally, I got the solution at
http://lists.apple.com/archives/unix-porting/2008/Jan/msg00027.html
just add other link flag:
-read_only_relocs suppress
* EXPLANATION * The two assembly commands load the absolutes address of _trail into R15. Doing so is fine if _trail is ultimately
in the same linkage unit. _trail is in libmodule.dylib. For this to
work, at runtime the dynamic loader (dyld) would have to rewrite the
two instructions. Normally dyld only updates data pointers. One work
around is to make libdyalog an archive (e.g. libdyalog.a) and link
that with pere.s. Then all the code would be in the same linkage unit,
so there would be no need for runtime text relocs. The runtime (dyld)
does support text relocs (updating instructions) for i386, but you
need to link with -read_only_relocs suppress.

Resources