So I am working on building a NDK sample in Android Studio 2.2.2. The project use clapack (a math library) and it also has a testclapack.cpp at the same level as clapack folder. An Android.mk file is also at the same directory.
The content of the Android.mk file is:
LOCAL_PATH:= $(call my-dir)
export MAINDIR:= $(LOCAL_PATH)
include $(CLEAR_VARS)
include $(MAINDIR)/clapack/Android.mk
LOCAL_PATH := $(MAINDIR)
include $(CLEAR_VARS)
LOCAL_MODULE:= lapack
LOCAL_SHORT_COMMANDS := true
LOCAL_STATIC_LIBRARIES := tmglib clapack blas f2c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_EXPORT_LDLIBS := $(LOCAL_LDLIBS)
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= testlapack
LOCAL_SRC_FILES:= testclapack.cpp
LOCAL_STATIC_LIBRARIES := lapack
include $(BUILD_SHARED_LIBRARY)
However, Sync Gradle leads to the error:
Gradle sync failed: GNUMAKE: Expected exactly one source file in compile step: com.android.build.gradle.external.gnumake.CommandClassifier$NativeCompilerBuildTool#6fd7d241
but received:
D:/SDK/android/ndk-bundle/build//../platforms/android-19/arch-arm/usr/include
E:/test/lapack/app/src/main/jni/testclapack.cpp
I think it is related to the Android.mk since if I remove the section for testlapack then the gradle sync is fine.
I need some help on how to make them can be compiled together since I need to call functions in testclapack.cpp.
Related
On esp32, using esp-idf, I built a module called webSocket.c/.h .
it includes
#include "esp32/sha.h"
As this module is generic, I want to put it in a component. I moved it to
"components/webSocket" directory and added a CMakeLists.txt file like this:
FILE(GLOB cFiles *.c)
set(
COMPONENT_SRCS
${cFiles}
)
set(COMPONENT_ADD_INCLUDEDIRS
"."
)
register_component()
From this point, the module does not compile anymore because the above included file is unreachable.
This module is part of esp-idf framework, or more accurately, part of mbedtls lib which is embedded in esp-idf framework.
I tried all these path without success:
mbedtls/port/include/esp32/sha.h
port/include/esp32/sha.h
include/esp32/sha.h
esp32/sha.h
sha.h
None is successfull, how should I do?
Added
set(COMPONENT_REQUIRES mbedtls)
to CMakeLists did the trick.
This is my CMakeLists.txt:
ADD_SUBDIRECTORY(third)
ADD_SUBDIRECTORY(utils)
ADD_SUBDIRECTORY(rpc)
But the directory 'rpc' will be compiled before directory 'utils', actually the 'rpc' is depends on 'utils', so I will get a link error.
How can I make the 'rpc' compiling after 'utils'?
Thanks.
When you use target_link_libraries() function and pass it other target name, CMake automatically sets this target as a dependency. You can also use add_dependencies() to specify dependencies manually.
Also note that order of sources compilation have nothing to do with your problem. Link errors (i guess, you are seeing "undefined reference" ones) are because you aren't linking your targets properly.
if the 'rpc' is depends on 'utils':
utils CMAKELISTS.txt
project(utils)
add_library (utils SHARED ${PROJECT_SOURCE_LIST})
rpc CMAKELISTS.txt
project(rpc)
add_library (rpc SHARED ${PROJECT_SOURCE_LIST})
# must add this command to scan dependencies of target rpc
add_dependencies (rpc utils)
target_link_libraries (${TEST_SOURCE_FILE_NAME} libutils.so)
I have the same question with you.
I have open source libs —— jthread and jrtplib. I want to build them by a main CmakeList.text so I make a folder like:
cpp
├─jrtplib
│ ├─src
│ └─CMakeFiles.txt
├─jthread
│ ├─src
│ └─CMakeFiles.txt
└─CMakeFiles.txt
and cpp/CMakeFiles.txt like:
cmake_minimum_required (VERSION 3.8)
set(JTHREAD_ENABLED 1)
# 包含子项目。
add_subdirectory ("jthread")
add_subdirectory ("jrtplib")
but build error, it build jrtplib first, I think "jr" > "jt", so build jrtplib first, and it can't find libjthread.so , so target_link_libraries error
I find a solution :
cmake_minimum_required (VERSION 3.8)
# ↓↓↓↓↓↓↓↓ attention ↓↓↓↓↓↓↓↓
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
# ↑↑↑↑↑↑↑↑ attention ↑↑↑↑↑↑↑↑
set(JTHREAD_ENABLED 1)
# copy jthread/src/*.h to C:/thirdParty/include/jthread
set(JTHREAD_INCLUDE_DIRS "C:/thirdParty/include")
set(JTHREAD_LIBRARIES "libjthread.so")
# 包含子项目。
add_subdirectory (jthread)
add_subdirectory (jrtplib)
set xx_OUTPUT_DIRECTORY can set library build in main cmake_build folder, so jrtplib can find libjthread.so .
build success ...
I am assuming that the project named "third" is independent however "utils" depends upon "rpc". Try the following code for a sequential build
ADD_SUBDIRECTORY(third)
ADD_SUBDIRECTORY(utils "${CMAKE_CURRENT_BINARY_DIR}/utils_build")
ADD_SUBDIRECTORY(rpc "${CMAKE_CURRENT_BINARY_DIR}/rpc_build")
this will make a "_build" directory in your given build directory. and will copy the binaries there. For more information try
cmake --help-command ADD_SUBDIRECTORY
I am trying to add a package for directfb tutorials. I followed the instructions in http://wiki.openwrt.org/doc/devel/packages.
Currently the package is downloaded successfully to the dl folder and even compiled in the build directory, but when I add the install section to the makefile I get dependency error:
Package directfb_tutorials is missing dependencies for the following libraries:
libdirect-1.4.so.0
libdirectfb-1.4.so.0
libfusion-1.4.so.0
libpthread.so.0
The package Makefile (I put it under package/utils/directfb_tutorials/):
include $(TOPDIR)/rules.mk
PKG_NAME:=DFBTutorials
PKG_VERSION:=0.5.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.directfb.org/downloads/Extras/
PKG_MD5SUM:=13e443a64bddd68835b574045d9025e9
PKG_LICENSE:=LGPLv2.1
PKG_LICENSE_FILES:=COPYING
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/directfb_tutorials
TITLE:=directfb_tutorials
SECTION:=utils
CATEGORY:=Utilities
URL:=http://directfb.org
DEPENDS:=+libdirectfb
endef
define Package/directfb_tutorials/description
DirectFB Tutorials
endef
define Build/Configure
$(call Build/Configure/Default,)
endef
define Package/directfb_tutorials/Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)
endef
define Package/directfb_tutorials/install
$(INSTALL_DIR) $(1)/bin/dfb_tutorials
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/image/image $(1)/bin/dfb_tutorials/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/simple/simple $(1)/bin/dfb_tutorials/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/keybuffer/keybuffer $(1)/bin/dfb_tutorials/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/text/text $(1)/bin/dfb_tutorials/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/sprite/sprite $(1)/bin/dfb_tutorials/
endef
$(eval $(call BuildPackage,directfb_tutorials))
When adding +libpthread to the DEPENDS section, libpthread.so.0 does not appear in the missing dependencies error message above:
Package directfb_tutorials is missing dependencies for the following libraries:
libdirect-1.4.so.0
libdirectfb-1.4.so.0
libfusion-1.4.so.0
is because I must have used DEPENDS in a wrong manner (DEPENDS= +libdirectfb). How can I tell the correct name of the library for the DEPENDS flag? Is the fact that the library is installed to /usr/lib instead of just /lib (like libpthread) makes a difference?
Thanks in advance,
Tomer
The message about missing libraries comes from check fired from include/package-ipkg.mk. It is the latest stage of package creation. This check is verifying all executable files have all needed libraries available in the system. To enforce that, system requires you to add some entries in "DEPENDS" section. But before - you need of course to know, which one(s) to add.
To find missing library provider, if the case is not obvious (usually it is just a library name), you may search in $STAGING_DIR/pkginfo folder. In my case it is staging_dir/target-mips_mips32_uClibc-0.9.33.2/pkginfo.
Just cd to that folder and run something like:
grep libdirect-1.4.so.0 "*.provides"
You should see one or more results. Use common sense to pick the best one, usually it is a package named similar to the library, but not always. This is a generic way, should be helpful in case you miss the package in DEPENDS and cannot easily guess the correct one(s).
My guess is, that you should modify DEPENDS in your Makefile to contain
this:
DEPENDS:=+libdirect +libdirectfb +libfusion +libpthread
Look at the iftop core package for a syntax example:
https://github.com/openwrt/openwrt/blob/master/package/network/utils/iftop/Makefile#L28
It is the perfect example. The right syntax should be:
DEPENDS:=+libdirectfb +libpthread
I'm trying to link my kernel module with an external static lib, like this:
obj-m += my_prog.o
my_prog-objs := some/path/lib.a
# all the standard targets...
For some reasone, the above Makefile doesn't compile my_prog.c at all, and the resulting module doesn't contain its code. Certainly, if I remove my_prog-objs line, my_prog.c gets compiled.
What's wrong with such an approach in a Makefile?
You must create a synthetic name as well as the source file and it's object name. You can not use my_prog.o directly as there are rules to make it from source. Here is an sample,
obj-m += full.o
full-src := my_prog.c
full-objs := $(full-src:.c=.o) lib.o # yes, make it an object.
Libraries are only supported from some special directories. Your object should be named lib.o_shipped and placed in the same directory. So, you need to take the external library and provide it locally as a shipped version. You need two object files; one is your compiled 'C' code/driver and the other is it linked together with the library.
The above is relevant to 2.6.36 kbuild infra-structure. The current documentation is in modules.rst section 3.3 Binary Blobs. I think the technique above will still work for libraries as opposed to just objects.
When you create the my_prog-objs list, you tell kbuild to use only the object files in that list. kbuild will no longer compile my_prog.c, and including my_prog.o in my_prog-objs results in a circular dependency. Instead, you need to create a unique obj-m and include both my_prog.o and /path/lib.a in its objs list. For example:
obj-m += foo.o
foo-objs += my_prog.o /path/lib.a
Took me about 2 hours to figure out why my module was doing nothing!
You're overriding the default my_prog-objs, which is just my_prog.o. Instead of replacing the contents with the library, add the library to the default:
my_prog-objs := my_prog.o some/path/lib.a
Hopefully you're not trying to link against a general userspace library... that won't work at all in kernelspace.
I started with the following directory structure:
project
exec
executable.exe
lib
src
include
config
<cmake-generated config file>
I created the library in the lib/src folder by using a CMakefile in the lib/src folder. The exe would compile.
Then, I moved my CMakeFile up to /lib, making sure to change the source file paths to /src/*
Now, when I try to compile, all my libraries compile and link fine, but when I try to link the executable, I get /usr/bin/ld: cannot find -lconfig.
Does anyone have any idea why this happens or how to fix it?
Here is some of my code:
./CMakeLists.txt:
include_directories(config)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
ADD_SUBDIRECTORY(libs) #library sources
ADD_SUBDIRECTORY(exec) #executable sources
CONFIGURE_FILE(${core_SOURCE_DIR}/config/config.h.in
${core_SOURCE_DIR}/config/config.h)
./libs/CMakeLists.txt:
file(GLOB src ...)
file(GLOB header ...)
add_library(lib ${src} ${header})
./exec/CMakeLists:
add_executable(executable executable.cpp)
link_directories(${core_SOURCE_DIR}/lib) #not sure if this is required
target_link_libraries(executable ${lots_of_libs})
Every library in lots_of_libs can be found as a .a file in the lib directory
One problem, probably not risolutive, is this:
link_directories(${core_SOURCE_DIR}/lib) #not sure if this is required
should be:
link_directories(${PROJECT_BINARY_DIR}/lib)
or:
link_directories(${LIBRARY_OUTPUT_PATH})
Anyway, normally you wouldn't need to add to your link_directories the path to a library that is built within the project, even if you have specified a different LIBRARY_OUTPUT_PATH