-isysroot or SDKROOT problem - c

I am a newbie to libhistory, so I was looking at the sample found with readline library. Compiled it on command prompt using: gcc -o ./a.out /usr/local/share/readline/histexamp.c -lreadline -L/usr/local/lib/It compiles and maintains history.
Then crated a xcode project with the same file and linked against readline library it compiles fine. But when I run , it won't maintain history and crashing while enumeration of history entries. After some trials i found that -isysroot argument is the cause for this problem:-isysroot /Developer/SDKs/MacOSX10.6.sdk The gcc man page says isysroot is like the --sysroot option, but applies only to header files.
Why the same program behaves differently with this option?

-isysroot is used to define the SDK that you build with. If you build with the 10.6 SDK and then try and run on OS X 10.5 then you will probably fail. You should build with whichever SDK corresponds to the minimum required OS for your program (for maximum backward-compatibility).

-isysroot /Developer/SDKs/MacOSX10.6.sdk
the sysroot will overwrite the system path /usr/local etc.
In my opinion, it is a problematic way to use the SDK path by XCode.
It will result in a non-existent path like
/Developer/SDKs/MacOSX10.6.sdk/usr/local/lib/
if you want to search in the user link -L/usr/local/lib/
I don't think it is a good idea at all to change sysroot just in order to use SDK

Related

Makefile for C code

I inherited a code which has a makefile, but so far I was unable to run it on a linux server. The main complain of the compiler is that it is unable to load libgmp.so.3 : error while loading shared libraries: libgmp.so.3. I know that libgmp.so.10 exists on this server, but I was wondering which part of the makefile needs to be changed so the compiler looks for libgmp.so.10 rather than libgmp.so.3.
OPTFLAG = -O2 -Wall -fPIC -fexceptions -DNDEBUG
LDFLAGS = -O2 -Wl,-no_compact_unwind -DNDEBUG -lm -pthread
COMPILER = gcc ${OPTFLAG}
LINKER = gcc ${LDFLAGS}
# CPLEX directory
CPLEX_HOME = /opt/ibm/ILOG/CPLEX_Studio1263/cplex
CPLEX_INC = ${CPLEX_HOME}/include/
CPLEX_LIB = ${CPLEX_HOME}/lib/x86-64_linux/static_pic/ -lcplex
# Compile the main file
code: code.c
${COMPILER} -c code.c -o code.o -I${CPLEX_INC}
${LINKER} -o code code.o -L${CPLEX_LIB}
clean::
rm -f *.o
rm -f ${LIB}/*.o
rm -f *~
rm -f ${SRC}/*~ ${INCLUDE}/*~
You need to rebuild whatever program or library uses libgmp.so.3 from source code. Could you provide the exact command run by make and the error message it produces?
EDIT The problem here is that the system has installed a version of the IBM CPLEX software which comes with its own GCC binary, and that GCC binary uses libgmp.so.3. The easiest way to fix this would be to upgrade the CPLEX software to a version which supports the operating system being used, or use the software on the operating system for which it was written (i.e., something really old that actually ships libgmp.so.3).
The most easy way it to install libgmp-dev package, from your linux distribution. GMP is a package library to do multiple precision calculations on large integers, which is probably needed by your program. As you put in some comments, adding -L/usr/lib64/libgmp.so.10 is an error, as -L option allows to add a directory to search for libraries, and not a specific library.
If only the library is needed and no header file is missing in your compilation (this is something strange, but sometimes happen) then you can still link with only the libgmp.so.10 object, but you have to do in a something nasty way. Just add /usr/lib64/libgmp.so.10 as an object file (not a library, with -l option) to your link command.
EDIT
From looking more closely your Makefile I see no reference to the libgmp.so.3 library, so I only can assume this is a indirect reference from some other already compiled library that comes from outside with your package. Just use
ldd lib<nameOfLibrary>.so.x.x
with all the libraries needed by your final executable, so see which shared objetc is the one that requests libgmp.so.3 soname, and then recompile it, reinstall it, or use your system's libraries ONLY, and not mesh anymore with libraries coming from another system. For example you can try (this is an expensive command, but it will get the answer)
find / -name "lib*.so.*" -print | xargs ldd > all_libs.lddout
and then find all_libs.lddout to see which library uses libgmp.so.3 (this will be the outdated library) You'll need to deinstall it or upgrade it, to be able to continue.
Linux systems have a library version system that allows an executable to be able to load different versions of the same library and allow them to live together in the same system. One of two: or you are able to locate the sources of version 3 of the shared libgmp.so.3 library and install it on your system, or you'll need to update the libraries your program uses to be able to link with the libgmp.so.10 already installed on your system.
2ND EDIT
As I see in the comments, you have changed the default compiler on your system by another coming possibly from other linux distribution (as your installed library is libgmp.so.10 while the one cc1 requests is libgmp.so.3, which is not installed on your system.
Installing a different compiler from the one you have installed, and doing that without previously deinstalling the other compiler, can lead you to this kind of problems.
The most reliable thing you can do is to reinstall the compiler from your distribution, or better, reinstall the whole linux system, as you have probably broken many things that will be emerging as you use your system. There's very poor info on what you have done to go further in your problem. Anyway, my recommendation is to not use the comment parts to add new information about your problem, just edit your question and add all those new information to it.

Compiling openmp on mac using gcc and Matlab

I am trying to compile a Matlab mex program that uses openmp on a mac. I would like to distribute this to other Matlab users so that they can use it, without them needing to install other software.
From what I can tell, xcode doesn't allow this, so I've installed gcc. I am able to compile the program fine, and run it locally, but it links to dependencies that are not available by default on a mac (I think). In particular, otool points to libgomp.1.dylib and libgcc_s.1.dylib, which from what I can tell, are not a part of the standard os installation.
I am able to link against libgomp.a statically, which from some testing (renaming the .dylib file) seems to have properly removed that dependency (i.e. the code still works when I rename the dylib file, and otool does not list it as well). However, I am unsure how to remove the libgcc_s.1.dylib dependency. In windows, copying the dll locally would fix the issue, but this doesn't work on a mac. I could not find a static library for that dependency. Instead, I am trying to get some version of rpath working (with a locally copied file), but otool consistently points to /usr/local/opt/gcc/lib/gcc/6/libgcc_s.1.dylib
The relevant parts of the Matlab command were:
'LDFLAGS="$LDFLAGS -fopenmp -Wl,-rpath,$ORIGIN/"' and
'-lgcc_s.1'
I found one solution here: Openmp with mex in Matlab on mac
However, for another project, I am using gcc specific commands so I'd really like to get this working with gcc.
So, I had some luck bypassing the mex compiling infrastructure and just passing the commands directly to gcc. To start, I ran what I currently had using the '-v' option to see the commands that Matlab was sending to the compiler. The 4 edits I then made were, 1) removed the crazy object output paths that Matlab creates (uses some temporary folder) 2) removed the reference to xcode 3) added a -L directive to the mex folder (although I will probably change this to the proper gcc directory - I'm just used to copying files locally to compile due to Matlab problems) and 4) added '-static-libgcc' (which I swear I had tried before ...) oh, and 5) I also updated the min osx version
This is the final line, the first two just had the -o options removed
/usr/local/Cellar/gcc/6.3.0_1/bin/gcc-6 -Wl,-twolevel_namespace -static-libgcc -L"/Users/jim/Documents/repos/matlab_git/matlab_sl_modules/plotBig_Matlab/+big_plot/private" -undefined error -arch x86_64 -mmacosx-version-min=10.12 -bundle -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/mexFunction.map" -fopenmp reduce_to_width_mex.o c_mexapi_version.o -O -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/c_exportsmexfileversion.map" libgomp.a -L"/Applications/MATLAB_R2017a.app/bin/maci64" -lmx -lmex -lmat -lc++ -o reduce_to_width_mex.mexmaci64
Oh and finally I should mention I just ran these commands in the terminal, rather than in the Matlab command window ...

How to configure a non-standard linker for an autotooled build?

I wanted to configure an autotooled project to invoke a non-standard
linker (the gold linker),
using the stock autotools of Linux Mint 16/Ubuntu 13.10
I believed I would achieve this by:
libtoolize-ing the project
Running ./configure LD=/path/to/my/linker ... etc.
However this has been ineffective. libtoolize has been successful. After
a standard ./configure; make I now see that libtool is doing the
linking:
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -o helloworld helloworld.o
But passing LD=/path/to/my/linker to configure makes no difference. Experimentally,
I even ran:
./configure LD=/does/not/exist
expecting to provoke an error, but I didn't. The output contains:
checking if the linker (/does/not/exist -m elf_x86_64) is GNU ld... no
checking whether the g++ linker (/does/not/exist -m elf_x86_64) supports shared libraries... yes
And thereafter a make continues to link, successfully, invoking g++ exactly as before.
What is the right way to configure a non-standard linker?
But passing LD=/path/to/my/linker to configure makes no difference
This is because LD is almost never and should almost never be used to link any user-space program. Correct links are performed by using the appropriate compiler driver (gcc, g++, etc) instead.
What is the right way to configure a non-standard linker?
If you have /some/path/ld and you want gcc to use that ld, pass -B/some/path flag to gcc.
It then follows that you likely want:
./configure CC='gcc -B/some/path' CXX='g++ -B/some/path' ...
I landed on this via a Google search, though my scenario is a bit different from yours; there was no libtool involved. An old open source program's Makefile was hard-coding ld to create an object file with a symbol from binary data.
This is what I ended up doing to work around the lack of $(LD) being recognized when passed to configure:
https://github.com/turboencabulator/tuxnes/commit/bab2747b175ee7f2fc3d9afb28d69d82db054b5e
Basically I added to configure.ac:
AC_CHECK_TOOL([LD], [ld])
Leaving this answer here for if someone else lands via a google search.

Adding a header file to Xcode

I'm trying to add a C library to Xcode. I downloaded the library from an online C class, and the zipped file contains two files: cs50.c and cs50.h.
I installed these files using the following commands:
gcc -c -ggdb -std=c99 cs50.c -o cs50.o
ar rcs libcs50.a cs50.o
rm -f cs50.o
chmod 0644 cs50.h libcs50.a
sudo mv cs50.h /usr/include
sudo cp libcs50.a /usr/lib
When building the project, I get the following error message:
Undefined symbols for architecture x86_64:
"_GetString", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is how I'm referencing the header file in my program:
#include </usr/include/cs50.h>
If I don't include the path, I get a can't find file message.
My version of Xcode is: Version 4.5.2 (4G2008a) and I'm running OS X 10.7.5.
Thanks for any suggestions.
Update:
As a general rule, you should never install or modify anything in /usr unless you have a very good reason to do so. This directory is reserved for the operating system, and you can quickly run into a lot of problems - for instance if you accidentally overwrite a system library or header file and even installing new things in there may cause problems when updating your operating system.
If you really need to install this system-wide, then put it into /usr/local.
However, since you compiled the library with debugging information, I assume that you also want to test and play around with it in your project.
To do that, it's much easier to add the sources as a new "C/C++ Library" target to your project. Then Xcode will take care of all the ugly details such as compiling, choosing the right processor architecture (32 or 64 bit), you'll get source-level debugging support in Xcode and if you ever want to install your app or create a package for it, then Xcode will also automatically bundle the dependencies for you.
If you trying to use gcc to compile the cs50.h library, I have found that to be unsuccessful on most modern 64 bit macs. Xcode 4.x generally wants a 64 bit compatible library format. GCC has not been updated to include 64 bit object files. Clang/LLVM is a rising alternative to gcc, and is used by Apple for Xcode as their preferred compiler engine. I have not personally tried it yet, but will be exploring Xcode to produce a compatible library for Xcode. I am taking the Harvardx cs50x course at edX, and it is great course, even for experienced programmers. The cs50.h library is interesting, because it provides relatively robust I/O routines for various variable types, e.g. String, Integer. float for the c programming language, including good protection for buffer overflow attacks.
You are actually building a custom dynamic library to be added to Xcode, which is also known as a framework. If you have apple developer account, check out the framework programming guide, it should prove useful.

Compile shared library with link to other .so

I want to link an existing shared library (FlashRuntimeExtensions.so) to my C-code while compiling my own shared library. But whatever I try I always get the same error; that the file is in a wrong format. Does anybody have an idea on how to solve this?
Here is my compile command:
$ g++ -Wall ane.c FlashRuntimeExtensions.so -o aneObject
FlashRuntimeExtensions.so: could not read symbols: File in wrong format
collect2: ld gaf exit-status 1 terug
Your command line tries to generate x86 code and link it to ARM code using the native g++ available in your distribution.
This will not work. Use the Android NDK available here: http://developer.android.com/tools/sdk/ndk/index.html
The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms.
In general .so will be linked using -l.
for example, pthread -lpthread we use.
gcc sample.c -o myoutput -lpthread
But as per #chill's statement, what you are doing in command is correct only.
I suggest you to refer the following link.
C++ Linker Error SDL Image - could not read symbols
It should be an architecture mismatch. I faced this problem once, I have solved it by building the libs in same target platform and it is obvious. If you are using linux or Unix like OS you can see that by file command and if you are using windows you can see that using Dependency Walker. You need to make sure that all the libs matches architecture.

Resources