I am having the following while making from source that also uses some static library during compilation. Here is the error:
/usr/bin/x86_64-linux-gnu-ld:/home/sajjad/Documents/Course/graphics/cmu/assignments/asst1_drawsvg/lib/libCMU462.a(base64.cpp.o): relocation R_X86_64_32S against symbol`_ZNSs4_Rep20_S_empty_rep_storageE##GLIBCXX_3.4' can not be used when making a PIE object; recompile with -fPIC
It has already been discussed here before, it says that I am trying to - "Linking dynamically against static archives". And it asking to compile with -fPIC while creating the archives. But I got the source with already generated .a (archive) file.
What flag do I have to pass inside cmake to build against a static library.
Related
I want to create a shared library with 'sqlite3(SHARED)' and 'glog(STATIC)' installed.
add_library(sqlite3 SHARED IMPORTED)
add_library(glog STATIC IMPORTED)
set_target_properties(sqlite3 PROPERTIES IMPORTED_LOCATION /usr/local/lib/libsqlite3.so)
set_target_properties(glog PROPERTIES IMPORTED_LOCATION /usr/local/lib/libglog.a)
add_library(${MY_LIBRARY} SHARED ${MY_SOURCE})
target_link_libraries(${MY_LIBRARY} sqlite3 glog)
This causes following error
/usr/local/lib/libglog.a: can not be used when making a shared object; recompile with -fPIC
What is wrong in CMakeLists.txt?
Your problem isn't with CMake (though you should never have hardcoded paths... use find_package or find_library), it's that you're trying to do something impossible. As your compiler tells you,
/usr/local/lib/libglog.a: can not be used when making a shared object; recompile with -fPIC
libglog.a was not compiled with position-independent code, so it cannot be used in a shared library, period. There's more information here on SO: How to recompile with -fPIC
You'll need to recompile libglog.a with -fPIC.
Cross compiling an executable for an embedded system with CMake requires me to manually add link options to link libc, libgcc and whatnot. However using target_link_options for that results in a linker call where all those additional link options are added in front of all the object files generated from my actual code. I believe that this is the wrong linking order and it causes "duplicate symbol errors" whenever I try to overwrite weak symbols from the standard library (e.g. __cxa_pure_virtual).
Here is an exemplar of the output I get from the linking stage
"/usr/bin/ld.lld"
--gc-sections
/usr/arm-none-eabi/lib/crt0.o
/usr/lib/gcc/arm-none-eabi/10.1.0/thumb/v7e-m+fp/hard/crti.o
/usr/lib/gcc/arm-none-eabi/10.1.0/thumb/v7e-m+fp/hard/crtbegin.o
/usr/lib/gcc/arm-none-eabi/10.1.0/thumb/v7e-m+fp/hard/crtn.o
/usr/lib/gcc/arm-none-eabi/10.1.0/thumb/v7e-m+fp/hard/crtend.o
--start-group -lstdc++_nano -lm -lgcc -lc_nano --end-group
my.obj ///< Shoudln't object files and application libs be linked first?
libmylib.a
-Bstatic
-L/usr/lib/clang/10.0.0/lib/baremetal
-L/usr/arm-none-eabi/lib/thumb/v7e-m+fp/hard/
-L/usr/lib/gcc/arm-none-eabi/10.1.0/thumb/v7e-m+fp/hard/
-T ldscript.ld
-o myelf
Is there any way to solve this in CMake?
target_link_options specifies options to the linker - and typically options are specified before anything else. Use target_link_libraries to link with libraries.
I'm currently struggling with cmake.
I'm using Cmake for an embedded platform with GCC.
My project is separate into several modules. Each module is build into a static library. At link time, all of these libraries are collected and linked into one binary.
The problem: I created a new folder for some unit tests. All sources are build into a library libunit_tests.a.(I checked the library actually gets created).
However in my linker call other libraries are passed to the linker, mine however gets omitted resulting in an undefined reference error.
My folder structure looks like this
*
unit_tests/
*
unit_tests/inc
*unit_tests/src
There is one Cmake file located at
- /unit_tests/CMakeLists.txt
My actual CMakeLists.txt file is pretty basic
include_directories("./inc")
set(module_name "unit_tests")
set(MODULE_SOURCES
./inc/active_tests.h
./inc/Run_All_Tests.h ./src/Run_All_Tests.c
)
###########################
# add library
###########################
if(MODULE_SOURCES)
# add files to library
add_library("${module_name}"
${MODULE_SOURCES})
target_link_libraries("${module_name}"
-Wl,--start-group
-Wl,--end-group)
endif()
How do i pass this library to the linker to resolve the undefined reference error?
I thought this is done via add_libary and target_link_libraries?
I am trying to generate a shared library (libgenerated.so) using g++ . The shared library uses some functionality that comes from a third party static library (libmystatic.a). For which I am linking the static library with the shared library as :
g++ -shared -o libgenerated.so $(OBJ_FILES) -lmystatic
The above command returns the following relocation error for the static library:
relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
Which points out that the object files in the static library needs to be compiled with -fpic flag. I am unable to understand why creating a Windows dll using the same static library (compiled for windows without -fpic) works ? I am using x86_64-w64-mingw32-g++ for the Windows DLL.
Thoughts from experts....
Which points out that the object files in the static library needs to be compiled with -fpic flag.
Exactly: on x86_64 you must compile code that is linked into a shared library with -fPIC of -fPIC.
I am unable to understand why creating a Windows dll using the same static library (compiled for windows without -fpic) works ?
There are two reasons:
On Windows, position-independent code is the default. So you get code compiled as if -fPIC was on command line regardless of whether that flag was on compile line or not.
The requirement to have position-independent code is architecture-specific. You can build a 32-bit i*86 shared library without -fPIC (this is ill-advised, but it works). On x86_64 (64-bit) Linux, you can't -- it simply can't work on that architecture.
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
...