Bundling dylibs, headerpad_max_install_names not working - macos

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++

Related

ld: too many sections (90295)

I am trying to build a haskell project from Ludum Dare, but whenever I attempt the build I get an error message saying the object file has too many sections. Here is the error:
C:\Users\REDACTED\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.2\lib\../mingw/bin\ld.exe: .stack-work\dist\a3a5fe88\build\HSsingletons-2.7-J1xRPYS9ah3kGEIOoeLuX.o: too many sections (90295)
singletons > C:\Users\REDACTED\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.2\lib\../mingw/bin\ld.exe: final link failed: file too big
-- While building package singletons-2.7 using:
C:\Users\REDACTED\AppData\Local\Temp\stack-5ba10ebdb151d9fa\singletons-2.7\.stack-work\dist\a3a5fe88\setup\setup --builddir=.stack-work\dist\a3a5fe88 build --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
I am using stack 2.3.3 and Windows 10. The project uses the vulkan library.
I tried adding -opta-mbig-obj, but gcc then failed with error: unrecognized command line option '-mbig-obj'
It looks like you may need to try explicitly using the “large object” file format, which I believe you can do by adding -opta-mbig-obj or -Wa,-mbig-obj to the GHC flags in the project’s build config (package.yaml or .cabal file) to add -mbig-obj to the assembler options. You may also need to add --oformat pe-bigobj-x86-64 to the linker flags, using (I think) -optl--oformat -optlpe-bigobj-x86-64 or -Wl,--oformat,pe-bigobj-x86-64. Are you using a 32-bit MinGW? I would expect MinGW64 to handle this by default. (And I’m not actually sure whether 32-bit supports these flags, so you may need to upgrade anyway.)
Since about a year ago (https://gitlab.haskell.org/ghc/ghc/-/commit/1ef90f990da90036d481c830d8832e21b8f1571b) GHC already uses the -mbig-obj and --oformat,pe-bigobj-x86-64 when assembling and linking on 64 bit MinGW. Adding these flags manually will not help on recent GHC versions.
I was able to replicate this problem for both the sdl2 and vulkan Haskell packages using Stack, however neither of them exhibit this issue when compiled with Cabal (and --enable-split-sections) on Windows; this looks to be a bug in stack.

GCC built from source in different location is incorrectly using same shared libs as native GCC

I'm a student doing research involving extending the TM capabilities of gcc. My goal is to make changes to gcc source, build gcc from the modified source, and, use the new executable the same way I'd use my distro's vanilla gcc.
I built and installed gcc in a different location (not /usr/bin/gcc), specifically because the modified gcc will be unstable, and because our project goal is to compare transactional programs compiled with the two different versions.
Our changes to gcc source impact both /gcc and /libitm. This means we are making a change to libitm.so, one of the shared libraries that get built.
My expectation:
when compiling myprogram.cpp with /usr/bin/g++, the version of libitm.so that will get linked should be the one that came with my distro;
when compiling it with ~/project/install-dir/bin/g++, the version of libitm.so that will get linked should be the one that just got built when I built my modified gcc.
But in reality it seems both native gcc and mine are using the same libitm, /usr/lib/x86_64-linux-gnu/libitm.so.1.
I only have a rough grasp of gcc internals as they apply to our project, but this is my understanding:
Our changes tell one compiler pass to conditionally insert our own "function builtin" instead of one it would normally use, and this is / becomes a "symbol" which needs to link to libitm.
When I use the new gcc to compile my program, that pass detects those conditions and successfully inserts the symbol, but then at runtime my program gives a "relocation error" indicating the symbol is not defined in the file it is searching in: ./test: relocation error: ./test: symbol _ITM_S1RU4, version LIBITM_1.0 not defined in file libitm.so.1 with link time reference
readelf shows me that /usr/lib/x86_64-linux-gnu/libitm.so.1 does not contain our new symbols while ~/project/install-dir/lib64/libitm.so.1 does; if I re-run my program after simply copying the latter libitm over the former (backing it up first, of course), it does not produce the relocation error anymore. But naturally this is not a permanent solution.
So I want the gcc I built to use the shared libs that were built along with it when linking. And I don't want to have to tell it where they are every time - my feeling is that it should know where to look for them since I deliberately built it somewhere else to behave differently.
This sounds like the kind of problem any amateur gcc developer would have when trying to make a dev environment and still be able to use both versions of gcc, but I had difficulty finding similar questions. I am thinking this is a matter of lacking certain config options when I configure gcc before building it. What is the right configuration to do this?
My small understanding of the instructions for building and installing gcc led me to do the following:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
I only have those config options because they seemed like the ones closest related to "only building the parts I need" and "not overwriting native gcc", but I could be wrong. After the initial config step I just re-run make -j2 and make install every time I change the code. All these steps do complete without errors, and they produce the ~/project/install-dir/bin/ folder, containing the gcc and g++ which behave as described.
I use ~/project/install-dir/bin/g++ -fgnu-tm -o myprogram myprogram.cpp to compile a transactional program, possibly with other options for programs with threads.
(I am using Xubuntu 16.04.3 (64 bit), within VirtualBox on Windows. The installed /usr/bin/gcc is version 5.4.0. Our source at ~/project/source-dir/ is a modified version of 5.3.0.)
You’re running into build- versus run-time linking differences. When you build with -fgnu-tm, the compiler knows where the library it needs is found, and it tells the linker where to find it; you can see this by adding -v to your g++ command. However when you run the resulting program, the dynamic linker doesn’t know it should look somewhere special for the ITM library, so it uses the default library in /usr/lib/x86_64-linux-gnu.
Things get even more confusing with ITM on Ubuntu because the library is installed system-wide, but the link script is installed in a GCC-private directory. This doesn’t happen with the default GCC build, so your own GCC build doesn’t do this, and you’ll see libitm.so in ~/project/install-dir/lib64.
To fix this at run-time, you need to tell the dynamic linker where to find the right library. You can do this either by setting LD_LIBRARY_PATH (to /home/.../project/install-dir/lib64), or by storing the path in the binary using -Wl,-rpath=/home/.../project/install-dir/lib64 when you build it.

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

Xcode Linker Issue - Other LD Flags won't clear

I am a noob and am having an issue with linker flags.
I tried building my own ssh2 libraries, and then afterwards I cloned a git repository with a project in the libraries already built.
Before I downloaded the compiled binaries, I was building with gcrypt and added the -lgrcrypt library to the other linker flags.
With this new library set that I am using, I no longer require gycrpt and so I removed the linker flags. However that did not clear the linker options. I am still getting all of the old linker flags in spite of clearing them in the project properties.
The error shows that the -lgrypt is still being processed as a linker flag:
-no_implicit_dylibs -mios-simulator-version-min=6.0 -lgcrypt
How can I reset the linker flags to what they were?
Thanks in advance
well i presume you have checked the flags and removed the path for that lib in your target level of the project, and also have clean the build and removed the previouse builds from organizer and inside xcode, and also have reset your simulator, and also have checked the project folder on your computer and removed that lib from the library folder of the project. these are the necessary steps and if you have done all of these then i cant think of anything else other than port your code to a new project and try to compile again. good luck my friend.

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