Flutter windows: can I use relative path to bundle `.dll` library in CMakeLists.txt? - flutter

I am building a flutter plugin which calls native functions from lib.dll file and everything works as expected in my computer.
But I use relative path to link that lib such as
E:/_Projects/mahesabu/client/packages/server/windows/lib.dll
Now I want to move the build process in CI/CD which I believe using relative path such as
./lib.dll would be very easy.
Of cource I am new to cmake configuration. And in one comment it is written
List of absolute paths to libraries that should be bundled with the plugin
I wonder how can I use relative path there, because if I try build fails. The following is CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
set(PROJECT_NAME "server")
project(${PROJECT_NAME} LANGUAGES CXX)
# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "server_plugin")
add_library(${PLUGIN_NAME} SHARED
"server_plugin.cpp"
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
# List of absolute paths to libraries that should be bundled with the plugin
set(server_bundled_libraries
""
"E:/_Projects/mahesabu/client/packages/server/windows/lib.dll" #USE RELATIVE PATH HERE
PARENT_SCOPE
)
Any help will be appreciated.

Just use:
set(server_bundled_libraries "${CMAKE_CURRENT_SOURCE_DIR}/lib.dll" PARENT_SCOPE)
The CMAKE_CURRENT_SOURCE_DIR variable will expand to current source directory as tracked by add_subdirectory. This is usually, but not always, the directory in which the present CMakeLists.txt resides. Presumably, this is E:/_Projects/mahesabu/client/packages/server/windows on your computer (given your remark that you expect ./lib.dll to work), but will be somewhere else on CI or elsewhere.

Related

qbs - install to specific dir

I am trying to modify the install dir in qbs. I tried every possibility, which came in my mind.
I would like to install to the location of an env var...
but qbs always installs into a subdir in the dir where it was stated in (e.g. qtc_Desktop__0e446cd2-debug)
I tried combinations of:
qbs.install: true
qbs.installDir: project.defaultLibInstallDir
qbs.installPrefix: project.defaultLibInstallPrefix
qbs.installRoot: project.defaultInstallRoot
I really like qbs, but can't figure out how the install should be used correctly.
I would appreciate an example, how an install to different system paths work (e.g. /usr/local/bin and /usr/local/include)
Update:
DynamicLibrary {
name: "software"
files: ["src/*.cpp", "src/*.hpp"]
Depends { name: "cpp" }
Group {
fileTagsFilter: product.type
qbs.install: true
qbs.installDir: "lib"
qbs.installPrefix: "/home/userName/someDir"
}
}
The install properties in qbs are documented here:
I'll also give a few examples of each and how you might use it:
qbs.installDir: Relative to qbs.installPrefix. This might typically be something like "bin" or "lib" or "share" in your install Groups, depending on the content that Group is installing.
qbs.installPrefix: The prefix on the target system at which your tree is installed. This might be something like "/usr" or "/usr/local".
qbs.installRoot: This is an external property which is prepended to all installation paths in your project. You do not set it within your project, only on the qbs command line. It defaults to a temporary location within your build directory. For example, if you set qbs.installPrefix to "/usr" and actually want your file tree to get installed there, you'll set qbs.installRoot to "/". Otherwise, your entire installation tree gets rooted within the qbs.installRoot. For example, if you were using qbs to build a Debian or RPM package, you'd set qbs.installRoot to the location of the temporary root used by the build process.

Renaming sub package names in my Android project

I have an Android project called my.android.project, and in my src directory, I have a few sub-packages called my.android.projectGUI, my.android.projectClasses, my.android.projectOthers.
I wish to change my package name to com.android.project instead. I have successfully done this with Android Tools->Rename Application Package. However, this didn't take care of my sub packages in my src directory. I wish to rename them to com.android.project.gui, com.android.project.classes, and com.android.project.others
In my.android.projectOthers, I have a java file AccessJNI.java that loads a JNI library that is linked to jni/myjnifiles/myjni.c
When I try to change the sub-packages individually via Refactor->Rename, it works for the all except for my.android.projectOthers. Once I rename this sub-package, Eclipse throws me an error for several JNI symbols, saying they could not be resolved. This happens despite me changing all JNI function calls in myjni.c from Java_my_android_projectOthers_AccessJNI_functionName() to Java_com_android_project.others_AccessJNI_functionName()
The strange thing is, ndk-build still builds the library correctly, but Eclipse cannot seem to resolve the JNI symbols.
Am I missing anything while renaming my sub-packages?
Thanks!
This happens despite me changing all JNI function calls in myjni.c from Java_my_android_projectOthers_AccessJNI_functionName() to Java_com_android_project.others_AccessJNI_functionName()
You should replace all JNI prefixes by Java_com_android_project_others_ and not Java_com_android_project.others_

Using CMake to index source files of an external library with Eclipse

I am using CMake to build a project with external libraries by using "Eclipse CDT4 - Unix Makefiles".
Importing in Eclipse leads to a working project, but only all header files and my implemented source files are recognized correctly by the index of Eclipse.
I would also like to navigate through the source files for one external library by using "ctrl+click". I don't know how to add the *.cpp files of that external library in my CMakeList.txt to get them recognized by the indexer without building the library.
You can mark the .cpp files as "header file only" like this:
# find all filenames in the lib path and gather them in $YOUR_LIB
FILE(GLOB YOUR_LIB path_to_library/*.?pp)
# create a seperate sourcegroup so it doesn't clutter up the rest of your code
SOURCE_GROUP(\\lib FILES ${YOUR_LIB})
# mark them as header-file only
SET_SOURCE_FILES_PROPERTIES(${YOUR_LIB} PROPERTIES HEADER_FILE_ONLY TRUE)
# add both your code and the lib-code to the project
ADD_EXECUTABLE(program ${YOUR_CODE} ${YOUR_LIB})
I found a way to attach external library source files to the Eclipse project that is compatible with CMake project generator.
It turns out that to indexing and "ctrl+click" navigation works correctly only when external library sources are direct descendants of the project source folder. Therefore the solution is following:
Scan external library folder for source files.
Create a child folder under project's source folder.
Symlink discovered sources inside the created folder.
I created a CMake function attachExternalSources that performs above steps:
function(attachExternalSources librarySourceLocation folderName)
# Create folder for Geant4 sources
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/${folderName})
message(STATUS "Searching for C++ sources in \"${librarySourceLocation}\"...")
FILE(GLOB_RECURSE libSources
${librarySourceLocation}/*.c
${librarySourceLocation}/*.cpp
${librarySourceLocation}/*.cxx
${librarySourceLocation}/*.cc
)
message(STATUS "Symlinking sources into\n \"${CMAKE_SOURCE_DIR}/${folderName}\"\n Please wait...")
foreach(source ${libSources})
# Obtain source filename
get_filename_component(source_filename ${source} NAME)
# Create symlink unless it already exists
set(symlink "${CMAKE_SOURCE_DIR}/${folderName}/${source_filename}")
if(NOT EXISTS ${symlink})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${symlink})
endif()
endforeach()
# Scan all the symlinks created under the project folder and disable their compilation
FILE(GLOB sources_symlinks ${CMAKE_SOURCE_DIR}/${folderName}/*)
SET_SOURCE_FILES_PROPERTIES(${sources_symlinks} PROPERTIES HEADER_FILE_ONLY TRUE)
endfunction()
The use of the function is following. Paste above function code in your CMakeLists.txt. Next, use it as follows:
attachExternalSources("path/to/external/library/sources" "library-sources")
First parameter is location of the external library source code. Second argument is the name of a folder inside your project that that will contain source symlinks.
P.S. I tested function with Eclipse 4.19 and CMake 3.20.5.

Setting environment variables in Eclipse to use with Android NDK

I use Android NDK with cygwin with Eclipse on Windows.
In my makefile I want to set path of prebuild library using environment variable in eclipse.
So I do the following:
And in makefile:
LOCAL_SRC_FILES = $(QCAR_SDK_ROOT)build/lib/$(TARGET_ARCH_ABI)/libQCAR.so
LOCAL_EXPORT_C_INCLUDES := $(QCAR_SDK_ROOT)build/include
But I get error:
Android NDK: ERROR:jni/Android.mk:QCAR-prebuilt: LOCAL_SRC_FILES points to a missing file
/cygdrive/d/Development/Android/android-ndk-r7/build/core/prebuilt-library.mk:43: *** Android NDK: Aborting . Stop.
make: *** [all] Error 2
Android NDK: Check that jni//cygdrive/D/Development/Android/qcar-android-1-5-4-beta1/build/lib/armeabi/libQCAR.so exists or that its path is correct
Tried defining variable in makefile directly, got the same result.
So, obviously, that path is not what I wanted. How do I set the proper path?
Why not just specify the paths in the make file? (N.B Just noticed you tried that.)
Using Cygwin with Android NDK
This site seems to indicate that the make file won't run correctly within Eclipse and you should run in via Windows Explorer. Are you running this within Eclipse? Try this and see if you still get the issues.
That's a problem of the previous NDK builds that Google fixed with NDK-9. "Updated ndk-build to support absolute paths in LOCAL_SRC_FILES."
See the release notes here:http://developer.android.com/tools/sdk/ndk/index.html
Try to play with LOCAL_PATH variable. As documentation (docs/ANDROID-MK.html in Android NDK package, or here) states:
LOCAL_SRC_FILES
This is a list of source files that will be built for your module.
Only list the files that will be passed to a compiler, since the
build system automatically computes dependencies for you.
Note that source files names are all relative to LOCAL_PATH and
you can use path components
Also, NDK hints you to Check that jni//cygdrive/D/Development/Android/qcar-android-1-5-4-beta1/build/lib/armeabi/libQCAR.so exists or that its path is correct.
Thus, I would try the following:
LOCAL_PATH := /
...or to reset it at all:
LOCAL_PATH :=
You can edit eclipse.ini file and add it there.
e.g. -DLOCAL_SRC_FILES=/home/user/.../
Or declare a path variable. It is a convenient way of sharing a common location among multiple projects within a workspace.
Hope that help you!
Recent NDK releases on Windows do not need cygwin. Worse, they do not recognize the cygdrive notation. You can simply use
QCAR_SDK_ROOT = D:/Development/Android/qcar-android-1-5-4-beta1
correction absolute paths for LOCAL_SRC_FILES do not work for ndk.r7, and even for r9 the ANDROID-MK.doc does not encourage using absolute paths there.

What is the difference between building C++ Builder project from IDE and command line?

I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.