I had set sysroot in CXXFLAGS
and when compile object file I can see sysroot in cmd line
but when build elf I cann't find the sysroot in cmd line, so build failed
so how can I pass sysroot in scons rightly?
SCons has a variety of flags that can be set for the different tasks, and you can always add your own if you need. As you correctly figured out, CXXFLAGS is used when compiling files...but not for linking. You'll have to add your flag to LINKFLAGS...a rather complete list of all available variables and their meaning can be found in the UserGuide ( http://www.scons.org/doc/production/HTML/scons-user.html ). Also note that there is a second set of flags/variables for shared objects (SHCXXFLAGS/SHLINKFLAGS).
Related
I have several object files coming from different directories (they are stored near the corresponding source that generated them). Is there a way that given this directory structure
Root
main.o
Root/Some_long_path
object_1.o
object_2.o
I could run a command like this
g++ -Wall main.o -ISome_long_path object_1.o object_2.o -o app
So that I don't have to put the full path in front of every object file. What would go instead of the -I command?
I am using gcc version 4.8.3 (from Cygwin installation).
So that I don't have to put the full path in front of every object file. What would go instead of the -I command?
There is no gcc option like -I to add some directory to the object "search path", and there is no search path for objects. But there is search path for libraries (usually named lib*.a for static libraries and lib*.so for shared libraries in Unix world).
Directory-Options manual of gcc lists only -I option for include paths and -L option for library paths. There is no object path:
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options
And Link-Options manual of gcc mention only -L option (near -l description):
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
What can you use:
shell variables or environment variables (in bash: OBJ_DIR=./path/to/dir then g++ ... $OBJ_DIR/obj1.o $OBJ_DIR/obj2.o)
Packing several objects from single directory to single static library libSome_Long_Component_Name.a (this type of library is just like the archive of several *.o object files and some extra info made with ar rcs); then you can use g++ ... -Ldir/ -lSome_Long_Component_Name
Makefiles and some variant of make utility (gnu make for linux and cygwin, nmake for windows's MSVC; you can start from gnu make manual: http://www.gnu.org/software/make/manual/make.html#Simple-Makefile then "2.4 Variables Make Makefiles Simpler" then "4.3 Types of Prerequisites" - with example of addprefix command to ask make find objects in some objdir. There is also VPATH special variable which instructs make to search sources and objects in several directories; but all objects in project should have different names).
Some IDE with support of Unix projects (Code::Blocks, list1, list2, wikilist of C/C++ IDE?); they usually manage all sources of you project and are able to generate Makefiles for project.
Some more modern build system, not the make: like CMake, SCons (or qmake if you use Qt).
I'm in a situation where I should not disturb the existing CMakeLists.txt files, but I still should add some g++ system include directory to my build.
In other words, I need -isystem /path/to/my/include added to my compiler flags, but when calling something like cmake ...
Maybe something like cmake .. -DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS -isystem /path/to/my/include"? Is there a way to do this?
I have the same problem. I found two solutions:
The one proposed by sakra in a previous answer, i.e. setting an environment variable with C++ flags:
export CXXFLAGS=-isystem\ /path/to/my/include
cmake <path to my sources>
OR the same thing, but environment variable are set only for this CMake call:
CXXFLAGS=-isystem\ /path/to/my/include cmake <path to my sources>
IMPORTANT: you must clean your build directory (i.e. clean the CMake cache) before launching any of this form. Without cleaning the cache, CMake will continue using your cached CMAKE_CXX_FLAGS from the previous run.
Directly setting CMAKE_CXX_FLAGS in cmake string:
cmake -DCMAKE_CXX_FLAGS=-isystem\ /path/to/my/include <path to my sources>
I believe that it can be done by a more 'native' way, but I didn't find a variable responsible for paths to headers in CMake.
You can set the environment variable CXXFLAGS before invoking CMake.
$ export CXXFLAGS=-isystem\ /path/to/my/include
$ cmake ..
CMake will the initialize the cache variable CMAKE_CXX_FLAGS with the flags from the environment variable. The variable affects all build types.
Using -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=<something> worked for me even without toolchain file. This avoids cluttering compiler flags.
Just an additional note to the other answers: with CMake 3.15.3 on macOS 10.14.5, only the solution using the CMake flag seems to work properly.
So, in my case, only this solution worked fine:
cmake -DCMAKE_CXX_FLAGS=-I\ /path/to/include <path/to/source>
With Mac OS X 10.6 Apple changed the default target of g++ so it produces 64-bit rather than 32-bit code. I know I can specify "-arch i386" on the command line but is there any way to globally change the default architecture by means of an environment variable or similar? (I keep getting linking errors because I'm having real problems finding all the places I need to specify the architecture on the project I'm porting.)
Not that I know of. Depending on the configuration & build system you’re using, setting the CXXFLAGS, CFLAGS, and LDFLAGS environmental variables to include -arch i386 can help. However, some configuration & build system are tricky and it might not be sufficient to set those variables.
Another option is to provide a g++ (and friends as needed) bash script in a PATH location that precedes /usr/bin and invokes the actual command with -arch i386 along with the command-line arguments passed to the script.
An alternative to the solution described in the previous paragraph is to use arch(1) in one of its various forms. For instance, the shell script described above could invoke arch -i386 /usr/bin/g++. You can also set the ARCHPREFERENCE environmental variable to something like g++:/usr/bin/g++:i386,x86_64 and invoke arch /usr/bin/g++. However, note that you must use arch to invoke /usr/bin/g++.
Option 1
You could set your path so that it searches your private bin directory first.
In this bin directory place a g++ script that explicitly invokes the correct g++ compiler will the appropriate flags.
Option 2
Set a g++ alias. This will then be used in preference to a command. Set the alias to run the command with the appropriate flags.
Note: Both of these assume you are building from the command line as XCode probably explicitly executes the g++ binary.
I am trying to compile omniORB on AIX 6.1 with gcc 4.2.0.
The initialization does not work as it is picking up the non pthreaded library.
If I set LIBPATH to /opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/ omniNames will not work, as the streams interface gives an exception.
Setting the LIBPATH to /opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/pthread seems to work, but other non pthreaded programs will pick up the pthreaded lib which may cause problems...
The link looks like this:
g++ -o omniNames -O2 -Wall -Wno-unused -fexceptions -Wl,-brtl -Wl,-blibpath:/lib:/usr/lib:/opt/dbx/omniORB-4/lib -L../../../lib -L../../../../lib omniNames.o NamingContext_i.o log.o omniNamesWin.o -lomniORB4-ar -lomnithread34 -lpthreads
How do I resolve this ??
Note that I have tried to change libpath using configure arguments but without success.
Launching via a wrapper script which set LIBPATH correctly is probably the easiest.
Then there is the RUNPATH/RPATH feature of ELF which allows to embded a search path for dynamic libraries in the executable; but I don't know if AIX implement it. It it does and is set with the same argument as for Linux and Solaris, -Wl,--enable-new-dtags -Wl,-R$(RUNPATH) for DT_RUNPATH, -Wl,--disable-new-dtags -Wl,-R$(RPATH) for DT_RPATH; you may want to test also simply -Wl,-R$(RPATH) (which will probably set the DT_RPATH).
Each OS uses its own unique set of environment variables to decide where to search for shared libraries.
Most UNIX like systems use LD_LIBRARY_PATH (but it varies).
I found that the most effective way to find which environment variable to use is to look at the man page for dlopen() on the platform you are building for.
Edited: also note that these variables act like the PATH environment variables, in that they are a list of paths that are ':' separated. So could you not set the environment like this:
# Using tcsh syntax for setting environment. Your shell may very.
setenv LIBPATH "/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/pthread"
The AIX ld man page states:
Note: If you specify a shared object, or an archive file containing a
shared object, with an absolute or relative path name, instead of with
the -lName flag, the path name is included in the import file ID string
in the loader section of the output file. You can override this
behavior with the -bnoipath option.
So, just specifying /my/path/to/libfoo.so instead of -lfoo should give you the behaviour you want.
I am building a C++ application that uses Intel's IPP library. This library is installed by default in /opt and requires you to set LD_LIBRARY_PATH both for compiling and for running your software (if you choose the shared library linking, which I did). I already modified my configure.ac/Makefile.am so that I do not need to set that variable when compiling, but I still can't find the shared library at run-time; how do I do that?
I'm compiling with the -Wl, -R/path/to/libdir flag using g++
Update 1:
Actually my binary program has some IPP libraries correctly linked, but just one is not:
$ ldd myprogram
linux-vdso.so.1 => (0x00007fffa93ff000)
libippacem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippacem64t.so.6.0 (0x00007f22c2fa3000)
libippsem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippsem64t.so.6.0 (0x00007f22c2d20000)
libippcoreem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippcoreem64t.so.6.0 (0x00007f22c2c14000)
[...]
libiomp5.so => not found
libiomp5.so => not found
libiomp5.so => not found
Of course the library is there:
$ locate libiomp5.so
/opt/intel/ipp/6.0.2.076/em64t/sharedlib/libiomp5.so
By /path/to/lib do you mean path to the directory containing the library, or the path to the actual file?
The -R option given a directory argument is treated like -rpath by ld, which is the option you're actually wanting here. It adds the given directory to the runtime library search path. That should work, as long as you give it the directory and not filename. I'm fairly confident about that, having done it myself, and because it's one of the hints given by libtool:
Libraries have been installed in:
/path/to/library-directory
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
use the `-Wl,-rpath -Wl,LIBDIR' linker flag
have your system administrator add LIBDIR to `/etc/ld.so.conf'
(I paste this here since conceivably one of the other options could be more desirable - for example LD_RUN_PATH can save you makefile modification)
As suggested by Richard Pennington, the missing library is not used directly by my application, but it is used by the shared libraries I use. Since I cannot recompile IPP, the solution to my problem is to add -liomp5 when compiling, using the -R option for the linker. This actually adds the rpath for libiomp5.so fixing the problem!
You can check if the path to the library is being picked up from your -R flag by running the ldd command or the readelf command on your binary. The LD_LIBRARY_PATH environment variable is an override, so shouldn't be necessary normally.
You should use the -R option if possible.
If not, rename your executable and create a launch script that runs your executable, and in there set LD_LIBRARY_PATH just for that scope.
Depending on platform, you can modify ld.so.conf via /etc/ld.so.conf.d (Redhat/Fedora come to mind) which makes deploying changes to ld.so "easier" from a deployment scenario.
Besides all the useful hints posted here.. you're not trying to use a 64-bit specific library on a 32-bit system (or viceversa, depending on other conditions), are you?
bash:
export LD_LIBRARY_PATH=/path/to/lib
tcsh:
setenv LD_LIBRARY_PATH /path/to/lib
Try configuring your ldconfig through ld.so.conf so it searches your /opt/... directory by default.