I'm trying to use the ncurses library on AIX 7.1 to make use of panels which aren't included in the curses library that is standard on AIX. I have the ncurses library installed. The compile,link, and execute work fine with:
xlc ngoodbye.c -lncurses
The actual ncurses library is libncurses.a, which I understand is a static library. However, when I move the executable to another AIX host and execute I get:
Dependent module libncurses.a(libncurses.so.5) could not be loaded. Could not load module libncurses.a(libncurses.so.5). System error: No such file or directory.
How can I link the ncurses library so that the program will execute on other hosts where the ncurses library isn't installed? Note I'm using xlc on AIX, not gcc.
I've tried -bstatic but get link errors at compile time. Note that I'm not a developer so my experience in this area is limited. Thanks.
Both static and shared libraries in AIX are built as position independent (PIC). So even a "shared" library can be statically bound to an executable. You were on the right track with -bstatic, you just need to switch back to dynamic binding for the rest of the libraries you're linking to.
So try this for your final link:
xlc -o myexe myexe.o <other objects as needed> -bstatic -lncurses -bdynamic -lm <and other other libraries as needed>
I do this all the time to make sure that my production environment matches my development one.
Normally ".a" does mean a static library. However, in adapting the initial report (in 2008) describing the AIX 5 shared library configuration there was some miscommunication and ".a" was used for both static and shared libraries. That was finally corrected last year (see changelog).
AIX 4, by the way, used a much more complicated scheme, so shared libraries for ncurses were first implemented on AIX 5.
Packagers prefer shared libraries. So what you have is a shared library named libncurses.a (legal, but not conventional). This is not created with the archiver ar, but using the loader ld. To see that they are different, you can try
ar tv libncurses.a
(with the appropriate directory). Likely ar will say something like
ar: 0707-108 File libncurses.a is not an archive file.
while file may give a more informative message:
libncurses.a: executable (RISC System/6000) or object module not stripped
You can however build ncurses from source. In that case (no matter what version), the default builds static libraries. You need not install those into the system area, but can configure ncurses using the --prefix option to install into a different directory.
As suggested in another answer, there is a workaround using the -bdynamic and -bstatic options of AIX's ld (loader), e.g., changing
xlc -o foo foo.c -lncurses
to
xlc -o foo foo.c -bstatic -lncurses -ldynamic
However, this is partly dependent upon the loader's search path and the name of the archive. If the archive is named libncurses.a, the command works as given. If it is named libncurses.so (as in current sources), then this command is needed to link against the shared library:
xlc -o foo foo.c -brtl -lncurses
But this command (which one might suppose to provide the static linkage using the libncurses.so file) does not succeed:
xlc -o foo foo.c -brtl -bstatic -lncurses -bdynamic
Related
I'm trying to build a package from Fedora that can run on a RedHat 6 machine. So I need to build and static linking with some library that does not exist in RedHat machine.
I found that I can you -static-libgcc or -static-libstdc++ to link with static version of standard library but I don't know how to do with glibc.
How can I link to static library of glibc with CMake?
I know the question mentions glibc but for C++, since -static-libgcc and -static-libstdc++ are linker options, the correct way to set them in CMake is with target_link_libraries().
So you would set it like this, where MyLibrary is the name of your project:
target_link_libraries(MyLibrary -static-libgcc -static-libstdc++)
Given this, if you want complete static linking of glibc you would likewise pass the -static flag.
target_link_libraries(MyLibrary -static)
If you want more of a global setting:
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
However, bear in mind that glibc is not designed to be statically linked, and without a great amount of additional work, you won't wind up with a truly static package. Your use case of building "a package from Fedora that can run on a RedHat 6 machine" will not readily work by statically linking glibc.
I'd like to link libpng found by pkg-config statically.
pkg-config --libs --static libpng
outputs
-L/usr/local/Cellar/libpng/1.6.15/lib -lpng16 -lz
I have both libpng16.a libpng16.dylib in that directory, and if I use these flags the library gets linked dynamically.
How can I tell either pkg-config or the linker (preferably in some portable-ish way) that I really want it linked statically?
I've tried adding -static before pkg-config's flags, but that makes clang's ld try and fail to link "crt0.o".
The pkg-config --static option relies on proper tagging in the .pc files. If providing the --static option does not return correct information necessary to link against the libpng archive, then you cannot use pkg-config for that purpose.
I suspect libpng (along with a majority of other packages) dropped support for static linking some time after libpng 1.2. They may still provide a library archive, but the libpng pkg-config file is no longer properly tagged to support a static link. You will have to manually tell ld to use the static lib.
Try:
-L/usr/local/Cellar/libpng/1.6.15/lib -l:libpng16.a -lz
Using -l with a : character allows you to specify the filename extension.
The -l: option is documented in the GNU ld 2.24 manual:
-l namespec
--library=namespec
Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.
On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a .so extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename.
You could edit the .pc file to make it support static linking, especially if you are in a position to be compiling, patching, and installing software yourself instead of relying on some Linux distribution.
Here is an example of a .pc file that supports both dynamic and static linking. This is taken from /usr/lib/x86_64-linux-gnu/pkgconfig/xcb.pc on my Ubuntu system:
prefix=/usr
exec_prefix=${prefix}
libdir=${prefix}/lib/x86_64-linux-gnu
includedir=${prefix}/include
xcbproto_version=1.11
Name: XCB
Description: X-protocol C Binding
Version: 1.11.1
Requires.private: pthread-stubs xau >= 0.99.2 xdmcp
Libs: -L${libdir} -lxcb
Libs.private:
Cflags: -I${includedir}
If you run pkg-config --libs xcb, it assumes you want the dynamic version and it gives you just -lxcb. The xcb.so dynamically shared object will know how to load all of its own dependencies so you don't have to specify them when linking against it.
If you run pkg-config --libs xcb --static, then the .private fields come into play, and you get -lxcb -lXau -lXdmcp.
I have not encountered many build systems that know to pass the --static argument to pkg-config. So if your .pc file is only intended to support static linking, it's probably best to not use .private fields, and just provide all the dependencies people will need unconditionally. That way people can link against the library successfully even if they don't know it's static or don't know to pass --static to pkg-config.
Just adding to the post by #David Garyson above I would like to add . If a particular
*.pc file is unavailable with the command
pkg-config --libs
then you might need to add a variable to your PATH
Perhaps you should add the directory containing `nice.pc' to the PKG_CONFIG_PATH environment variable
I use this trick in my Makefile.
LIBRARIES := $(shell pkg-config --libs libpng | sed -E 's/-l([a-z0-9]*)/-l:lib\1.a/g')
It grabs output from pkg config and expands it by prefixing each item with : and the lib, and post-fixing it with an .a. The end result is just what you need
-l:libpng.a -l:libz.a
I've been trying to create a CMake-based build-system for a project that is supposed to use SDL2_image library. I do not want to force user to install any libraries to the system to be able to build the project, so I took advantage of the CMake's ability to download and build dependencies (freetype, SDL2 and SDL2_image) from source code as External Projects.
Everything is fine with freetype and SDL2 (which both include CMakeLists.txt files out of the box), but I've ran out of ideas how to make it work for SDL2_image. CMake's external projects support custom configuration and building settings which I used in different variants with no success.
The CMake file itself can be found here, but the problematic part is this:
# SDL_image library
ExternalProject_Add(sdl2_image_project
URL https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.0.tar.gz
DEPENDS sdl2_project
PREFIX ${LIBS_DIR}/SDL2_image
CONFIGURE_COMMAND LDFLAGS=-L${SDL2_BIN} CFLAGS=-I${SDL2_SRC}/include SDL2_CONFIG=${SDL2_BIN}/sdl2-config <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --enable-shared=no
BUILD_COMMAND make
INSTALL_COMMAND ""
)
An error occurs while building sdl2_image_project. Some trivial research discovered that the error is generated by the undefined references to parts of libdl. Here is a tiny part of the hole error:
libtool: link: gcc -I/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project/include -I/usr/local/include/SDL2 -D_REENTRANT -o showimage showimage.o -Wl,-rpath -Wl,/usr/local/lib -pthread -L/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project-build ./.libs/libSDL2_image.a -L/usr/local/lib -lSDL2 -pthread
/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project-build/libSDL2.a(SDL_dynapi.c.o): In function `get_sdlapi_entry':
/home/snikitin/_src/img_glypher/libs/SDL2/src/sdl2_project/src/dynapi/SDL_dynapi.c:227: undefined reference to `dlopen'
I think the problem takes place due to the fact that linker tries to create a shared version of SDL2_image library while linking it to a static libSDL2.a. The thing is - if this is right - SDL2 building step creates both static and shared versions of itself so one would assume that linker would use libSDL2-2.0.so instead (I do not actually need a shared library - just the static one, but I do not know how to prevent the build system from trying to create it apart from passing --enable-shared=no to SDL2_image configure script, which does not help in this case).
After a lot of googling I've discovered that the possible source of the problem is that sdl2-config (which is called to get some flags for compiler during SDL_image building) may be called with wrong arguments and produces wrong cflags which confuse everything else. But I'm not sure that is the case and also I do not know how to influence sdl2_config call from CMake (configure --help does not seem to unveil any useful options for this situation).
I am running Ubuntu 14.04 x64 if it matters in any way. Would appreciate any advice!
Looks like you need to link some libraries like m and dl. It can be fixed by providing
custom sdl2-config file. Copy sdl2-config from extracted archive and substitute --libs result:
--libs)
echo -L${exec_prefix}/lib -Wl,-rpath,${libdir} -pthread -lSDL2 -lm -ldl
;;
Note that order is important (that's why just modifying LIBS not works for me).
Now this file can be used in your ExternalProject_Add command instead of SDL2_CONFIG=${SDL2_BIN}/sdl2-config:
...
... CFLAGS=-I${SDL2_SRC}/include SDL2_CONFIG=${CMAKE_CURRENT_LIST_DIR}/sdl2-config <SOURCE_DIR>/configure
...
I was checking out the portability of Objective-C via gnustep and ran into some problems...
I mean everything works on my 2 machines but the major problem is if I run my application on a platform where gnustep is not pre-installed... So I want to build it with static libraries. But I ran into several problems:
1.) I cant find the static libaries under /usr/local/lib so the question came up do they even exist within gnustep?
2.) In case there are static libraries available how to integrate it correctly into my gcc command?
sudo gcc -o main main.m GameRef.m SDLApplication.m SDLEvent.m SDLImage.m SDLMap.m SDLSprite.m Settings.m Utility.m -I -static `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS` -L `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES` -lgnustep-base -lSDL -fconstant-string-class=NSConstantString -std=c99 2>logFile
I'm currently using Ubuntu 12.04LTS and installed the SDL and Gnustep on one machine so the application runs fine... But not on the second because the shared libraries are missing so I need to add them as static but how?
The libraries in /usr/local/lib and other system 'lib' directories will be dynamic. They can't be used as static (AFAIK), and finding them wouldn't really help.
I'm no expert with GNUstep, but it sounds like you are missing the Objective-C runtime. You will need to download the source code of the GNUstep libraries and frameworks, and then compile them into static libraries yourself.
Really, wrapping all of those frameworks into your application will just add unnecessary work for both you and your end users. Dynamic libraries exist for a purpose. There's no reason to have multiple copies of the same code on the filesystem. Just require GNUstep as a dependency. Although its a slight pain for the users, they only need to do it once, and with most distros, installation is only a command or two away.
After installing Mono, I need to setup environment variable as follows.
PKG_CONFIG_PATH="/Library/Frameworks/Mono.framework/Versions/2.8/
What's the purpose of pkgconfig files (or .pc files) that are installed in /Library/Frameworks/Mono.framework/Versions/2.8/lib/pkgconfig?
There are two main kind of uses:
providing compiler and linking flags for compiling the mono runtime inside your own application (embedding): mono-2.pc is an example. These are generally used as follows:
gcc myprogram.c `pkg-config --cflags --libs mono-2`
providing default lists of managed assemblies for particular subsystems: dotnet.pc provides the assemblies that are normally loaded by default by csc on Windows, gtk-sharp-2.0.pc lists the assemblies of the Gtk+ binding, etc. These are generally used as follows:
gmcs -pkg:gtk-sharp-2.0 myprogram.cs
If you look inside the files, they have a Description field that should explain what each file is used for.