/lib/libc.so.0 error with buildroot - linux

It is seen that sometimes if we select a package we get this strange error from buildroot saying cannot find /lib/libc.so.0 . Further probing it is defined in libc.so found in $(STAGING_DIR)/usr/lib ; if we change the absolute path
GROUP (/lib/libc.so.0 /usr/lib/uclibc_nonshared.a AS_NEEDED (/lib/ld-uClibc.so.0 ) )
to relative path meaning something like below :
GROUP ( ../../lib/libc.so.0 ../usr/lib/uclibc_nonshared.a AS_NEEDED (../../lib/ld-uClibc.so.0 ) )
compilation goes thro' fine. Q? is whether this is the right way to get around this problem ? or we need to do some change so that this file gets generated properly ?; Thanks for any solutions.

Are you using an External Toolchain? Does it happen with packages that don't use the autotools Makefile?
I think you may need to pass the TARGET_(CFLAGS|LDFLAGS) in the packages .mk files.
something like:
CFLAGS="$(TARGET_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(PACKAGE_SRCDIR)

Related

Shared Libraries not linking together after installation with CMake

I have run into a rather strange problem with Google Tests.
In my project, I am using externalProject_add in order to download google tests and add them into my project. In my function, I believe I am asking for the project to be built, and then installed into a specific directory:
ExternalProject_Add(gTest_download
URL ${GTEST_url}
URL_HASH ${GTEST_hash}
UPDATE_COMMAND ""
BUILD_COMMAND cmake --build . --target install
CMAKE_CACHE_ARGS
-DCMAKE_C_COMPILER:PATH=${Compiler_C}
-DCMAKE_CXX_COMPILER:PATH=${Compiler_CXX}
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_INSTALL_PREFIX:PATH=<BINARY_DIR>/installation
)
I can then tell the program where all the source files are living with this:
ExternalProject_Get_Property(gTest_download BINARY_DIR)
set(gTest_LIBRARY_DIR ${BINARY_DIR}/installation/lib CACHE INTERNAL "Google Test Binary Dir")
set(gTest_INCLUDE_DIR ${BINARY_DIR}/installation/include CACHE INTERNAL "Google Test Include Dir")
However, when I try to run a cmake test with protobufs I get the run time error:
./Protobuf_test: error while loading shared libraries: libgmock.so.1.11.0: cannot open shared object file: No such file or directory
Which is super odd, because I know I specifically told the program where to find the libraries in the same externalProject_add file:
set(gTest_LIBRARIES
${gTest_LIBRARY_DIR}/${prefix}gmock${suffix}
${gTest_LIBRARY_DIR}/${prefix}gmock_main${suffix}
${gTest_LIBRARY_DIR}/${prefix}gtest${suffix}
${gTest_LIBRARY_DIR}/${prefix}gtest_main${suffix}
CACHE INTERNAL "Google Test Libraries"
)
Where ${prefix} is "lib" and ${suffix} is ".lib". And I make sure to link them in my CMakeLists.txt file properly by doing target_link_libraries(Protobuf_test ${gTest_LIBRARIES} ${protobuf_LIBRARIES}) ex:
CUSTOM_PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDS ${CMAKE_CURRENT_LIST_DIR} hello.proto)
include_directories(
${protoBuf_INCLUDE_DIR}
${gTest_INCLUDE_DIR}
${CMAKE_CURRENT_LIST_DIR}
)
add_executable(Protobuf_test protobuf_test.cc ${PROTO_SRCS} ${PROTO_HDS})
add_dependencies(Protobuf_test
gTest_download
protoBuf_download
)
target_link_libraries(Protobuf_test
${gTest_LIBRARIES}
${protoBuf_LIBRARIES}
)
add_test(NAME testing_protobuf COMMAND Protobuf_test)
So I went into the installation folder which is located in d/linuxBuild/lib/src/gTest_download-build/installation/lib and confirmed it exists there. I then ran ldd libgmock.so and got the following output:
libgtest.so.1.11.0 => not found
Which I thought was odd as well. gtest is in the same directory! How is that possible? So I ran ldd on gmock_main:
libgmock.so.1.11.0 => not found
libgtest.so.1.11.0 => not found
So now I have two libraries that are in the same directory however they cannot be found. Confused, I decide to go to where the libraries should have originally installed to and copied over from. So two folders up: d/linuxBuild/lib/src/gTest_download-build. I then go into that folders lib folder and verify the libraries are there. I then run the same ldd command on gmock:
libgtest.so.1.11.0 => /mnt/d/linuxBuild/lib/src/gTest_download-build/lib/libgtest.so.1.11.0 (0x00007fb651729000)
I'm confused by this and again, run it on gmock_main:
libgmock.so.1.11.0 => /mnt/d/linuxBuild/lib/src/gTest_download-build/lib/libgmock.so.1.11.0 (0x00007f58b0db3000)
libgtest.so.1.11.0 => /mnt/d/linuxBuild/lib/src/gTest_download-build/lib/libgtest.so.1.11.0 (0x00007f58b0c9c000)
I am sorry for the lengthy question, but I need to know what happened here? Why is it when I install the libraries the links break from each other and they don't know their locations compared to the ones in the original installation path? Did their symbolic links break? Did I do something incorrectly in the CMake build? I'm scratching my head on this problem since I have never encountered this before. Any advice would be greatly appreciated.
Forget about externalProject_add and use FetchContent / FetchContent_MakeAvailable, especially when dealing with CMake-ready projects:
See https://cmake.org/cmake/help/latest/module/FetchContent.html for details
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
FetchContent_MakeAvailable(googletest)
# ...
target_link_libraries(Protobuf_test
PRIVATE
gmock_main
${protoBuf_LIBRARIES}
)
This way, you are linking against the gmock_main target, which will set up your libraries, includes, and any indirect dependencies correctly like any cmake project added via add_subdirectory() or find_package().

NDK APP_CFLAGS can't handle <> characters?

I am including a procedurally generated file into code used by several libraries, using something like
#include MY_CONFIG_FILE_H
Then I am attempting to set this value in my Application.mk using the following directive
APP_CFLAGS += -DMY_CONFIG_FILE_H=<Config/MyFile.h>
however, this results in ndk-build not finding the path. It fails right away on the first file it tries to compile
"Compile++ thumb : MyLibraryName <= MyFirstFile.cpp
The system cannot find the path specified.
make: *** [obj/local/armeabi-v7a/objs/MyLibraryName/MyFirstFile.o] Error 1
Indeed, the file is not there, but it did manage to create the file path. There must be some strange/inconsistent string manipulation going on.
Any ideas? Work arounds? Is this a known issue in ndk-build.cmd? For the record I'm on Windows x64 and NDK R9.
Also notice that if I only include > and no <, I get a different error
The filename, directory name, or volume label syntax is incorrect.
Changing the line to
APP_CFLAGS += -DMY_CONFIG_FILE_H="<Config/MyFile.h>"
worked. Hope this helps anyone else!

cmake ignoring include directory when cross compiling

I am perplexed and would like your help.
I am cross compiling a project that requires ifaddrs.h, but no matter how I try to specify the location of the file, it never finds it. It is located at /usr/include/ifaddrs.h and I have used the code below to try to point to it. (Granted this is the host system's file, but that should not matter in this context. I have also put the file in the target systems include directory: /tmp/toolchain/include with no different results). And the message call does print /usr/include
If, however, I put the file in ${CMAKE_CURRENT_SOURCE_DIR}/../include
it is found. It is there, I can see it -- why not cmake?
FIND_FILE( IFADDRS ifaddrs.h PATH /usr/include )
get_filename_component(if_path ${IFADDRS} PATH)
message( "IFADDRS = " ${if_path} )
include_directories( ${if_path} )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../include )
Changing the code above to this:
include_directories( BEFORE SYSTEM /usr/include )
and running make VERBOSE=1 gives this:
[ 18%] Building C object CMakeFiles/cpcommon_lib.dir/eui48.c.o
/tmp/toolchain/arm-linux-uclibc/bin/gcc -DPJ_AUTOCONF=1 -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1 -I/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/../include -I/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/../../pjproject/pjlib-util/include -I/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/../../pjproject/pjlib/include -I/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/../../pjproject/pjnath/include -I/usr/include/w32api -I/usr/X11R6/include -I/usr/include/X11 -I/usr/pkg/include -I/opt/csw/include -I/opt/include -I/usr/openwin/include -I/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/../../cjson -o CMakeFiles/cpcommon_lib.dir/eui48.c.o -c /home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/eui48.c
In file included from /home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/eui48.c:26:
/home/bp/MySnapCam/projects/Communication/trunk/cpcommon/src/impl/eui48_unix.c:14:21: ifaddrs.h: No such file or directory
There is no /usr/include/ in the include paths. It is also not in the flags.make files either.

Reusing custom makefile for static library with cmake

I guess this would be a generic question on including libraries with existing makefiles within cmake; but here's my context -
I'm trying to include scintilla in another CMake project, and I have the following problem:
On Linux, scintilla has a makefile in (say) the ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk directory; if you run make in that directory (as usual), you get a ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/bin/scintilla.a file - which (I guess) is the static library.
Now, if I'd try to use cmake's ADD_LIBRARY, I'd have to manually specify the sources of scintilla within cmake - and I'd rather not mess with that, given I already have a makefile. So, I'd rather call the usual scintilla make - and then instruct CMAKE to somehow refer to the resulting scintilla.a. (I guess that this then would not ensure cross-platform compatibility - but note that currently cross-platform is not an issue for me; I'd just like to build scintilla as part of this project that already uses cmake, only within Linux)
So, I've tried a bit with this:
ADD_CUSTOM_COMMAND(
OUTPUT scintilla.a
COMMAND ${CMAKE_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
COMMENT "Original scintilla makefile target" )
... but then, add_custom_command adds a "target with no output"; so I'm trying several approach to build upon that, all of which fail (errors given as comment):
ADD_CUSTOM_TARGET(scintilla STATIC DEPENDS scintilla.a) # Target "scintilla" of type UTILITY may not be linked into another target.
ADD_LIBRARY(scintilla STATIC DEPENDS scintilla.a) # Cannot find source file "DEPENDS".
ADD_LIBRARY(scintilla STATIC) # You have called ADD_LIBRARY for library scintilla without any source files.
ADD_DEPENDENCIES(scintilla scintilla.a)
I'm obviously quote a noob with cmake - so, is it possible at all to have cmake run a pre-existing makefile, and "capture" its output library file, such that other components of the cmake project can link against it?
Many thanks for any answers,
Cheers!
EDIT: possible duplicate: CMake: how do i depend on output from a custom target? - Stack Overflow - however, here the breakage seems to be due to the need to specifically have a library that the rest of the cmake project would recognize...
Another related: cmake - adding a custom command with the file name as a target - Stack Overflow; however, it specifically builds an executable from source files (which I wanted to avoid)..
You could also use imported targets and a custom target like this:
# set the output destination
set(SCINTILLA_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk/scintilla.a)
# create a custom target called build_scintilla that is part of ALL
# and will run each time you type make
add_custom_target(build_scintilla ALL
COMMAND ${CMAKE_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
COMMENT "Original scintilla makefile target")
# now create an imported static target
add_library(scintilla STATIC IMPORTED)
# Import target "scintilla" for configuration ""
set_property(TARGET scintilla APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(scintilla PROPERTIES
IMPORTED_LOCATION_NOCONFIG "${SCINTILLA_LIBRARY}")
# now you can use scintilla as if it were a regular cmake built target in your project
add_dependencies(scintilla build_scintilla)
add_executable(foo foo.c)
target_link_libraries(foo scintilla)
# note, this will only work on linux/unix platforms, also it does building
# in the source tree which is also sort of bad style and keeps out of source
# builds from working.
OK, I think I have it somewhat; basically, in the CMakeLists.txt that build scintilla, I used this only:
ADD_CUSTOM_TARGET(
scintilla.a ALL
COMMAND ${CMAKE_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
COMMENT "Original scintilla makefile target" )
... and then, the slightly more complicated part, was to find the correct cmake file elsewhere in the project, where the ${PROJECT_NAME} was defined - so as to add a dependency:
ADD_DEPENDENCIES(${PROJECT_NAME} scintilla.a)
... and finally, the library needs to be linked.
Note that in the commands heretofore, the scintilla.a is merely a name/label/identifier/string (so it could be anything else, like scintilla--a or something); but for linking - the full path to the actual `scintilla.a file is needed (which in this project ends up in a variable ${SCINTILLA_LIBRARY}). In this project, the linking basically occurs through a form of a
list(APPEND PROJ_LIBRARIES ${SCINTILLA_LIBRARY} )
... and I don't really know how cmake handles the actual linking afterwards (but it seems to work)
For consistency, I tried to use ${SCINTILLA_LIBRARY} instead of scintilla.a as identifier in the ADD_CUSTOM_TARGET, but got error: "Target names may not contain a slash. Use ADD_CUSTOM_COMMAND to generate files". So probably this could be solved smarter/more correct with ADD_CUSTOM_COMMAND - however, I read that it "defines a new command that can be executed during the build process. The outputs named should be listed as source files in the target for which they are to be generated."... And by now I'm totally confused so as to what is a file, what is a label, and what is a target - so I think I'll leave at this (and not fix it if it ain't broken :) )
Well, it'd still be nice to know a more correct way to do this eventually,
Cheers!

Problems with CMAKE vars

I'm using CMAKE to generate VS2008 SLN/VCPROJ files but a few simple things don't appear to work:
1)This works: INCLUDE_DIRECTORIES ($ENV{MCS_OGRE_HOME}/OgreMain/include)
But this doesn't, my VC++ additional include dirs gets totally screwed up when I do this, brackets and all kinds floating around:
SET (OGRE_PATH $ENV{OGRE_HOME}/OgreMain)
INCLUDE_DIRECTORIES (${OGRE_PATH}/include)
2)This works: target_link_libraries( debug $ENV{OGRE_HOME}/lib/OgreMainStatic_d.lib )
But this doesn't, the library path isn't shown under the library paths in VC++:
LINK_DIRECTORIES($ENV{OGRE_HOME}/lib/)
target_link_libraries( debug OgreMainStatic_d.lib )
I figure it must be something simple?
Rather than:
set(OGRE_PATH $ENV{OGRE_HOME}/OgreMain)
Use:
string(REPLACE "\\" "/" OGRE_PATH "$ENV{OGRE_HOME}/OgreMain")
CMake uses all "/" for path separators on all platforms.
Also, it's recommended to use full path names (with "/" separators) as library arguments to target_link_libraries rather than specifying link_directories. CMake then takes the whole set of libraries linked to and figures out the right order to pass linker flags on all platforms.
One more comment: looks like you have a library or an executable named "debug" from your call to target_link_libraries. Is that true? Or are you missing the first argument in the question posted here?
Should be something like:
target_link_libraries(mylib
debug /path/to/DebugLib.lib
optimized /path/to/ReleaseLib.lib)

Resources