Xcode Library not found for -lavutil.57.28.100 - xcode

I try to make macOS GUI application with ffmpeg.
On project settings -> General -> Frameworks,Libraries..., I added the ffmpeg lib files
/opt/homebrew/Cellar/ffmpeg/5.1-with-options_2/lib/libavutil.57.28.100.dylib.
I also add lib search path of /opt/homebrew/Cellar/ffmpeg/5.1-with-options_2/lib
I still get error : Library not found for -lavutil.57.58.100.
I like to get more detail about error.
I think these possibility
not valid arm64 format.
linker expect x64 and arm64 binary. But the file has arm64 only.
Dependency of dylib is missing.
If someone knows solution or detail about this error, please let me know.
That file exist and valid arm64 Mach-O file.
file libavutil.57.28.100.dylib
libavutil.57.28.100.dylib: Mach-O 64-bit dynamically linked shared library arm64

Some tips that will help you to troubleshoot this issue.
Firstly, lldb expects an arm64 version of the lib if your main executable's architecture is arm64, a fat-universal version of the lib if your main executable's architecture is fat-universal.
So please check the main executable's architecture inside YOURAPP.app/Contents/MacOS. I'm taking IINA video player as an example:
lipo -i /Applications/IINA.app/Contents/MacOS/IINA
Secondly, it's not good to refer to a brew version of the binary. If the library's version on another machine mismatches with yours, your app will crash. It's ok that you copy the dylib file and copy it into your Xcode project. Then you can add the dylib file to the Frameworks, libraries, and Embedded Content section in Xcode. The below image shows an example of integrating ffmpeg libs into your project.
Alternatively, the ffmpeg-kit package is your friend. I have a simple showcase for you: Github
Finally, if you insist on using the brew version, please disable checking on code-signing for external libs: Project Settings > Signing & Capabilities > Hardened Runtime > Runtime Exceptions > Diable Library Validation

Xcode does not add library search path.
I add -L/opt/homebrew/Cellar/ffmpeg/5.1-with-options_2/lib on "Other Linker Flags"

Related

CMake + Xcode: how to select arm64 vs x86_64 libraries?

We have a CMake based project targeting Xcode, and must include a precompiled 3rd party library which supplies separate arm64 and x86_64 binaries.
What we have working now is to simply attach both binaries like
add_library( someLib INTERFACE )
add_library( someLib_x64 STATIC IMPORTED )
set_target_properties(
someLib_x64
PROPERTIES
IMPORTED_LOCATION_RELEASE "path/to/x64/libsomeLib.a"
)
add_library( someLib_arm STATIC IMPORTED )
set_target_properties(
someLib_arm
PROPERTIES
IMPORTED_LOCATION_RELEASE "path/to/arm/libsomeLib.a"
)
target_link_libraries(
someLib
INTERFACE
someLib_x64
someLib_arm
)
This seems to result in a valid compilation for both architectures (building for "Any Mac (Apple Silicon, Intel)"), however it causes a bunch of linker warnings as each architecture complains about the other one.
ld: warning: ignoring file /path/to/x64/libsomeLib.a, building for macOS-arm64 but attempting to link with file built for macOS-x86_64
and vice versa.
What is a more accurate way to do this that avoids linker warnings? I couldn't find an applicable generator expression to change the link path?
Edited, I misunderstood this previously. I think you have 3 options
suppress error, the error doesn't affect anything in fact, so the simplist way to
add_link_option("-w")
to ignore it, or just change link option for the target
try the latest cmake concept IMPORTED_TARGET, it looks like perfectly fit your demand, but require new cmake version
try to compile an universal library from source code, this is some example
change flag or cmake official example, but this looks like need another project for source code of the lib
UPDATE: ACCEPTED ANSWER:
Based on the documentation for IMPORTED_TARGET linked here, it revealed that you can use the symbol $(CURRENT_ARCH) in the library path, which is interpreted by Xcode at link time.
Works perfectly.
You can combine the two .a files into the fat binary and use the combined library for compilation. The linker will select the correct version based on the architecture.
To combine the .a library files, you can use the lipo command:
lipo -create 'path/to/x64/libsomeLib.a' 'path/to/arm/libsomeLib.a' \
-output 'path/to/combined/libsomeLib.a'
The combined library file can be reused until you need to install an update to the library. Alternatively, you can create a aggregate target to combine the library files every time you compile if you prefer not to manage the library manually.

Statically link OpenSSL in XCode

I am trying to link libssl.a and libcrypto.a static libraries in XCode command line project [under Link Binary With Libraries]. I have included Openssl header files in search path.
Compilation succeeds but execution fails with dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Any help would be appreciable.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Apple's linker uses the dylib or share object if its available, regardless of of your linker flags like -rpath and -Bstatic. They even do it on iOS, where dylib's are not allowed!
Its kind of a well known problem once you know about it :) See, for example, Installing Crypto++ 5.6.2 on Mac OS X. Crypto++ has the same problems with Apple's tools.
The fix is to stop using -L and -l options, and to link the object file or archive directly. An archive is just a collection of object files, so you can use them interchangeably.
To specify the object files or archives for the linker, see Linking to an object file. Under Xcode, you add the fully specified archive name (like /usr/local/openssl-ios/lib/libcrypto.a) to Other Linker Flags (the OTHER_LDFLAGS Xcode option).
When adding the full archive to OTHER_LDFLAGS, I believe you just add it verbatim without any switches, like -l or -L. You may need -Wl (-Wl,/usr/local/openssl-ios/lib/libcrypto.a), but you don't use -l (-l/usr/local/openssl-ios/lib/libcrypto.a).
You use -Wl when the option is passed through the compiler driver to the linker. If the linker is invoked directly, then you don't need -Wl and should not use it.
A second option is to set GCC_LINK_WITH_DYNAMIC_LIBRARIES to YES. Apple does not appear to document it in Xcode Build Setting Reference, but its clearly under my copy of Xcode. See How to link a static library for iOS on Stack Overflow.
I seem to recall having problems with this in the past. Its one of those things that should work in theory, but does not work in practice.
A third option is to remove the dylib or shared object from all paths used under Xcode so Xcode does not accidentally find it when using -lcrypto.
A fourth option is use allow dynamic linking, but execute the program with DYLD_LIBRARY_PATH. Its OS X's equivalent to LD_LIBRARY_PATH, and ensures your copy of OpenSSL is loaded (like 1.0.2), and not the system's version of OpenSSL (0.9.8).
But I don't like this option because it requires users of your software to do something.
Another possibility due to the message dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib is to code sign your copy of the library. Its a little odd its found but not loaded, so I'm going to toss this out there in case its OS X's Code Signing or Gatekeeper Service...
To code sign your copy of the library under the MAC Developer program, just:
codesign -fs "Johnny Developer" /usr/local/ssl/lib/libcrypto.so

Mac OS X 10.6 : OpenSSL library

I have received an old code on the Mac and trying to compile it on OS X 10.6, in the code there are few calls to OpenSSL library (such as SSL_write()) I added the headers (#include ) in those files and check my version of OpenSSL shows me "0.9.8r" (I know Apple has it's own framework for this library crypto' ) but why I get the Link error as this:
sockets::TcpSocket::TryWrite(char const*, unsigned long) in TcpSocket.o
I know the code should compile against this library in /usr/lib but it doesn't, do I missing path or other setting in Xcode?
There are no libraries in /usr/bin. I assume you mean /usr/lib. You generally do not compile against /usr/lib, however. You usually compile against a specific SDK, which has its own copy of /usr/lib and /usr/include. The SDK header files you use is generally passed in the -isysroot parameter. If you're building in Xcode, these settings are set primarily via the "Base SDK" and "OS X Deployment Target." Without more specifics of how you're building, I'm not certain where else to point you, though. In particular, what does the compile and link lines look like for the relevant file?
In Xcode, don't try to link against specific system libraries by path. You should always link against system libraries using the Link Phase panel of the build settings, and selecting from the SDK list of libraries. Selecting specific paths in the Link Phase panel almost always leads to problems.

Bundling dylibs, headerpad_max_install_names not working

I have another OSX application problem. I want to bundle in my final application several dylibs, all of them needed by the application and by other dylibs.
I change its references using the install_name_tool, but some of the libraries couldn't be changed properly, having this error:
install_name_tool: changing install names or rpaths can't be redone for: aLibrary.dylib (for architecture x86_64) because larger updated load commands do not fit (the program must be relinked, and you may need to use -headerpad or -headerpad_max_install_names)
So I added the headerpad_max_install_names option flag on the linker flags of the xcode project (Project Properties-Build Settings-Linking-Other Linker Flags). Also I verified in the build log, if the option flag was included, and the option flag was included properly.
But still having the same error in the last dylibs.
Is there any way to bundle all the libraries needed in a unique Framework? Or am I doing something wrong in the building process?
Hope I'm clear with the main problem.
Thanks!
I had this same problem, using C++ and Code::Blocks, and I fixed it by switching from g++ to clang++

Why doesn't Xcode recognize my LIBRARY_SEARCH_PATHS?

I've set LIBRARY_SEARCH_PATHS to /opt/local/lib, and verified that the library in question is there (I'm linking to GLEW):
$ls /opt/local/lib
libGLEW.1.5.1.dylib libfreetype.a libz.a
libGLEW.1.5.dylib libfreetype.dylib libz.dylib
libGLEW.a libfreetype.la pkgconfig
libGLEW.dylib libz.1.2.3.dylib
libfreetype.6.dylib libz.1.dylib
but Xcode gives me the linker error
library not found for -lGLEW
I'm generating the Xcode project with CMake, so I don't want to explicitly modify the Xcode project (if someone suggests adding it as a framework, or something like that). Xcode recognizes USER_HEADER_SEARCH_PATHS fine (as in this question); why doesn't it work here?
Perhaps adding something like this to your CMakeLists.txt?
find_library(GLEW_LIB GLEW /opt/local/lib)
if(NOT ${GLEW_LIB})
message(FATAL_ERROR "Could not find GLEW")
endif()
target_link_libraries(myprogram ${GLEW_LIB} ...)
Where myprogram is the name of the target executable that needs to link with the library. You would replace the ... with the other libraries you are using on that executable.
This way CMake would handle the library path details for you.
Xcode works on potentially multiple SDK's, so whenever your define these kinds of things (like HEADER_SEARCH_PATHS or LIBRARY_SEARCH_PATHS) the current SDK root is prepended to the actual path that's getting passed to the linker.
So, one way to make this work would be to add your directory to the SDK. For example, assuming you're building with the Mac OS X 10.5 sdk, you could add your opt dir:
ln -s /opt /Developer/SDKs/MacOSX10.5.sdk/opt
Your library would now be found on your system.
If you don't want to do this, then you will have to look at CMake and find out how to get it to generate a library requirement for your actual library (I don't know anything about CMake, so I can't help you there). This is also why you see a difference between USER_HEADER_SEARCH_PATHS and HEADER_SEARCH_PATHS re your other question.
As another option, you could also specify this path with the OTHER_LDFLAGS build variable:
OTHER_LDFLAGS=-L/opt/local/lib
This would cause the linker to search /opt/local/lib as well as its standard paths and wouldn't require you to generate a different project file.

Resources