CMake: Referencing a sibling native Android Library module from App code - cmake

I have an Android Studio project with a general layout as follows:
Project/
|
+-- app/
| |
| +-- src/main/cpp/
| | |
| | +-- native-lib.cpp
| | +-- CMakeLists.txt
| |
| +-- build.gradle
| +-- CMakeLists.txt
| |
+-- sibling-lib/
| |
| +-- src/main/cpp/
| | |
| | +-- partA/CMakeLists.txt
| | +-- partB/CMakeLists.txt
| | +-- partC/CMakeLists.txt
| |
| +-- build.gradle
| +-- CMakeLists.txt
|
+-- build.gradle
+-- settings.gradle
sibling-lib is a third-party library comprised of multiple parts, each with separate sources and common headers, each of which is compiled into either a static or shared library, using the associated CMake file, and included as a subdirectory by the top-level library CMake file. Most of those parts are dependent on other parts.
The goal is to compile and link the parts of sibling-lib into library files within an Android Library (.aar) and use those libraries from the native files within the main app (e.g. native-lib.cpp). I have been able to compile each of the parts as a static library, with the final part linked together as a shared library (using target_link_libraries() on that part), and then load the library from the app's Java code. However, when I try to call any of sibling-lib's functions, I receive reference errors when compiling.
How should I configure the CMake and gradle files (for both the app and library) to properly compile and set up my project? Is there, however, a better way to configure the project to obtain the desired result?

Related

Excluding a sub directory from executing CMakeLists.txt

I have the following project structure
MainProj
|-SubDir1
| |-Docs
| |-CMakeLists.txt
| |-Src
| |-CMakeLists.txt
|-SubDir2
| |-Src
| |-CMakeLists.txt
|-CMakeLists.txt
In my Mainproj cmakeList.txt I am using
Add_subdirectory(subDir1)
Add_subdirectory(subDir2)
So now I want to exclude the mainproj/subdir1/doc from the build process. But I couldn't find a direct way of doing the same in CMake scripts. Any help in this regard would be appreciated.

How to import libs module in different files

I have troubles resolving my module imports. Here is my file structure:
.
|-- scenes
| |-- libs
| | |-- mod.rs
| | `-- components.rs
| |-- mod.rs
| `-- scene.rs
`-- main.rs
I can't import the module libs in scene.rs. I think I don't get it the module logical. Any help would be very appreciable.
if I try to do mod libs; in scene.rs
error[E0583]: file not found for module `libs`
--> src/scenes/scene.rs:2:5
|
2 | mod libs;
| ^^^^
|
= help: name the file either scene/libs.rs or scene/libs/mod.rs inside the directory "src/scenes"
Contents files:
main.rs
mod scenes;
let sc = scenes::scene::Scene{};
scenes/scene.rs
mod libs; // errors
pub struct Sphere {
pub center: libs::components::Point
}
pub struct Scene {}
scenes/mod.rs
pub mod scene;
pub mod libs;
scenes/libs/components.rs
pub struct Point {}
scenes/libs/mod.rs
pub mod components;
Instead of mod libs, write use crate::scenes::libs.
The Rust 2018 Edition has changed the module system slightly to help clarify situations such as this.
Your directory should be restructured like so:
main.rs
scenes.rs
scenes
| libs.rs
| libs
| | components.rs
| scene.rs
The main difference here is that mod.rs files are now extracted from their folder and named appropriately.
PRE-RUST-2018 - NOV 2018
Instead of mod libs, write use scenes::libs.
The error message is telling you is you're trying to declare the existence of a submodule of scene that does not exist. Instead, you want to import (with use) the libs module which is accessed by scenes::libs from the crate root.

CMake configuration to build a project from root or from subdirectories

I've started using CMake (2.8.12.2, the one included in CentOS 6.8) recently, and I think it's powerful enough to help acomplish what I want, but I haven't been able to figure out how :-), so I call for your wisdom to help me find the missing point.
I have a project layout like this:
BaseDir
|
+-->bin (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->lib (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->CMakeLists.txt
|
+-->Library_A
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Library_B (depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Application_1 (depends on Library_B, hence transitivitely depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| |
| +-->CMakeLists.txt
|
+-->Application_2 (depends on Library_A)
|
+-->CMakeLists.txt
+-->include
+-->src
|
+-->CMakeLists.txt
It works like a charm when I place myself under BaseDir and run "cmake .". Application_1, Application_2, Library_A and Libray_B are all built in the proper order, linked, etc.
However, my idea is to be also able to build while standing under any of the subdirectories (Application_, Library_), and in that case, build only the code relevant to it (meaning itself, its tests and its dependencies). For example, while standing inside Library_A, only that folder is build, while from Library_B, Library_A is also built, and the equivalent that happens when standing under Application_1 or Application_2. Plus, indepedently on where I'm standing to trigger the cmake process, the build results (libs or bins) must always placed under BaseDir/{lib|bin}/{Debug/Release/etc}, never under the libraries or applications subdirectories. It implies, for example, that the linking of Library_B (which depends on Library_A) or Application_1 (which depends on Library_A and B) must look into BaseDir/lib/{Debug/Release}.
My goal is to have many App's under BaseDir, so I want to avoid having to build them all every time if that's not really necessary, just the single App I want.
I've looked into CMakeLists.txt files for multiple libraries and executables and also CMake and finding other projects and their dependencies, but that's not really the same situation than what I'm trying to achieve here.
I've tried something like the following:
BaseDir/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (BASE_DIR)
|
| add_subdirectory (Library_A) # No local dependencies
| add_subdirectory (Library_B) # Depends on A
| add_subdirectory (Application_1) # Depends on A and B
| add_subdirectory (Application_2) # Depends on A
|
| # I want all binary outputs (executables and libraries) placed under BaseDir/{lib|bin}/{Debug|Release}
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}") # For the executables
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
|
+-->BaseDir/Library_A/CMakeLists.txt (again, no dependencies)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_A)
| |
| | # In case CMake is run from within BaseDir/Library_A and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_A/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_A_SRCS "*.h" "*.cpp")
| |
| | # Create a library called libA.a
| | add_library(A ${LIB_A_SRCS})
| |
| +-->BaseDir/Library_A/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_A_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources
| add_executable(TEST_A ${TEST_A_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_A A)
|
+-->BaseDir/Library_B/CMakeLists.txt (dependency on A)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_B)
| |
| | # In case CMake is run from within BaseDir/Library_B and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_B/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_B_SRCS "*.h" "*.c")
| |
| | # Create a library called libB.a
| | add_library(B ${LIB_B_SRCS})
| |
| | # Add a dependency to Library_A
| | find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_A)
| | include_directories("$LIB_A_INCLUDE_DIRECTORIES")
| | target_link_libraries(B ${LIBRARY_A})
| |
| +-->BaseDir/Library_B/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_B_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources, for both versions of the library
| add_executable(TEST_B ${TEST_B_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_B B)
|
+-->BaseDir/Application_1/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (APP_1)
| |
| | # In case CMake is run from within BaseDir/Application_1 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | # In this case, only executables are generated.
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
| |
| | include_directories(include)
| | add_subdirectory (src)
| |
| +-->BaseDir/Application_1/src/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB APP_1_SRCS "*.cpp")
|
| # Create an executable file from sources
| add_executable(EXE_1 ${APP_1_SRCS})
|
| # This should automatically bring Library_A
| find_library(LIBRARY_B B PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_B)
| include_directories(${LIB_B_INCLUDE_DIRECTORIES})
| target_link_libraries(EXE_1 ${LIBRARY_B})
|
+-->BaseDir/Application_2/CMakeLists/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (APP_2)
|
| # In case CMake is run from within BaseDir/Application_2 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| # In this case, only executables are generated.
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
|
| include_directories(include)
| add_subdirectory (src)
|
+-->BaseDir/Application_2/src/CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
# add all files in the current directory
file(GLOB APP_2_SRCS "*.cpp")
# Create an executable file from sources
add_executable(EXE_2 ${APP_2_SRCS})
# Link this executable to the library it needs
find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}../../Library_A)
include_directories(${LIB_A_INCLUDE_DIRECTORIES})
target_link_libraries(EXE_2 ${LIBRARY_A})
But with no luck, because when I run from the subdirectories (for example, BaseDir/Application_1), I just get:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
LIBRARY_B
I guess the "find_library()" call is not enough for what I want, which is basically to load all the settings contained in the libraries project, including not only the library itself, but also the include's directories added by that library. What is exactly the way of usage for find_library(), to point it to the location of the project creating the library, or the actual resulting library (".a" or ".so")?
So, my main doubt is: Is this layout doable? If so, what am I missing? Should I use something like find_package() or find_path()? How do I trigger the parsing of a CMakeLists.txt config file from another "same level" CMakeLists.txt?
PS: Do I really need to consider using "add_dependencies()" at any point? What's the point of that command if not?
First a general piece of advice: In CMake you will always want try to strictly separate your build directories from your source directories. In particular, you should never write files back to the source directory as part of the build process. Write your scripts so that they will also work with the source directory being mounted on a read-only file system. While this might seem like an arbitrary restriction at first, it actually will help you avoid many headaches in the long run.
As for your actual problem: find_library is a very low-level tool for solving the dependency problem. The idea here is basically that you have binaries for a third-party library (which itself knows nothing about CMake) installed somewhere on the system and you know need to find them simply by inspecting the contents of the filesystem. This is not the case here, as you build the dependencies as part of the same CMake configure run.
What you want to do instead is directly depend on the targets for the dependency. So instead of doing this:
find_library(LIBRARY_A A)
target_link_libraries(B ${LIBRARY_A})
you would directly write
target_link_libraries(B A)
This of course only works if A is a known target at that point, and this is the problem that you should focus on.
As long as you keep building the libraries together as part of the same CMake run, this is pretty straightforward: If a target is added by a parent or sibling directory, you should be able to use it right away. What complicates things in your situation is that you also want to be able to build the different libraries in isolation. That means you need a mechanism that imports a target into your build so that it looks as if that target was again produced as part of the same CMake run.
You can either do this manually by adding an imported target and setting its interface properties, or you can use CMake's packaging mechanism to have this done in an automated way. Note that neither of these is trivial to pull off, so you might want to start with the simple case where everything happens in one CMake run and then add support for the separated build later once you are more comfortable with using CMake.

Standards for infrastructure in cgi-bin directory

I'm maintaining some CGI web applications, which I'm migrating to a new Linux web server, on which I have a non-admin account, say www_maintainer. So I am installing the CGI applications inside /home/www_maintainer/, and I'd like to take the opportunity to clean things up, in particular the cgi-bin/ directory could be better organized; I'd like to learn about a best-practice standard for that.
For instance, is it normal to have subdirs called bin/ and lib/ inside cgi-bin/, with the binaries and libraries of auxiliary things?
I will describe a specific example, namely with the math- and data plot application gnuplot and its dependencies (libfontconfig, libpng , libgd, libjpeg, libreadline.so, ...).
Python could be another example (the distro provides 2.4 but I need >2.6), however I hope the admin can install 2.6 from a package so I don't have to worry about it.
The new web server has Scientific Linux (SL), which is based on Redhat RHEL. Unfortunately the distro repository for our current SL version does not provide gnuplot version 4.4 which I need, so it cannot be installed in the normal place like /usr/bin/, so I could build and install it and its dependencies in a non-system location, for example cgi-bin/tools/. The actual CGI web applications are binary executables launched by the scripts launch1.sh or launch2.sh.
Here is a illustration of the directory tree and some of the files in there (many dirs and files omitted of course).
cd /home/www_maintainer/www_root/
|-- html/
| |-- index.html
| `-- info.html
|-- cgi-bin/
| |-- gen/
| | |-- status.sh*
| | `-- sybase/
| | `-- DataAccess64/
| | `-- ODBC/
| | |-- lib/
| | |-- samples/
| | `-- spl/
| |-- exe1/
| | `-- launch1.sh*
| |-- exe2/
| | `-- launch2.sh*
| |-- javascript/
| | `-- check-input.js
| |-- scripts/
| | |-- decode.pl*
| | |-- generate-random-string.bash*
| | |-- gnuplot -> ../tools
| | `-- upload.php*
| |-- tools
| | |-- bin/
| | | |-- gnuplot*
| | | |-- python -> python2.6
| | | |-- python-config -> python2.6-config
| | | |-- python2.6*
| | | |-- python2.6-config*
| | | `-- xmlwf*
| | |-- etc
| | | `-- fonts/
| | |-- include/
| | |-- info/
| | |-- lib/
| | | |-- libfontconfig.so
| | | |-- libpdf.so
| | | |-- libreadline.so
| | | |-- libpng15.so
| | | |-- libpng15.so
| | | |-- pkgconfig/
| | | |-- libpng.so
| | | |-- libjpeg.so
| | | |-- libreadline.so
| | |-- libexec/
| | |-- man/
| | `-- share/
|-- tests/
| `-- results/
| `-- info/
| |-- readme.pdf
| `-- readme.html
|-- fonts/
|-- index.html -> html/index.html
|-- log/
| `-- log.txt
`-- tmp -> /tmp/
Would it be better to install outside the www_root, e.g.in the directory /home/www_maintainer/bin/ and /home/www_maintainer/lib/ and configure the web server to allow that?
EDIT: 05/23/2012 3pm PT US
If you're restricted to the user's directory, you can do pretty much whatever you want.
What used to be the common case was that you put all of the CGI-using files (Perl, etc) into the cgi-bin directory and you can (and probably should) put those in subdirectories based on the purpose or application.
Then you put the non-CGI files outside of the cgi-bin directory, which includes any bare HTML files, graphics files, CSS files, JS files, etc.
For any programs that are used by the CGI files but not directly by the web user, do not put them in the webroot at all as that is not necessary and could be a security hole if the web user can submit values into those programs in some fashion.
Directory tree example:
/home/www_maintainer/public_html/index.html
/home/www_maintainer/public_html/images/logo.png
/home/www_maintainer/public_html/scripts/something.js
/home/www_maintainer/public_html/cgi-bin/application1/app1.cgi
/home/www_maintainer/public_html/cgi-bin/application2/app2.cgi
/home/www_maintainer/public_html/cgi-bin/application2/app2helper.cgi
/home/www_maintainer/tools/gnuplot/gnuplot
/home/www_maintainer/tools/python/python -> python2.6
/home/www_maintainer/tools/python/python2.6
/home/www_maintainer/tools/python/python2.6-config
Then in your CGI files, make sure that the paths to the tools are set correctly as needed. It is not necessary for web users to access those tools directly, so keep those out of access. If you're doing python via CGI (which I assume, in this case), make sure your shebang line shows the correct path; #!/home/www_maintainer/tools/python/python, for example.
Original answer:
What a lot of applications do, such as the ones distributed with Debian, is put their applications in the /usr/share/lib/programname directory and then use an Apache Alias and ScriptAlias to map them to a base URL. This is how I used to run our own internally-developed applications as well and that worked very well.
For your situation, I'd recommend changing as little as possible unless you plan to enhance the code or the system more and more over time. Making changes could bring headache if paths change, especially if any are bookmarked, unless you want to get cozy with some mod_rewrite in your config.
Do you have any specific examples that I could use to demonstrate what I've described?
Also, with regard to ancient /usr/bin/python, is your system completely up-to-date? Or is the problem that your Linux distribution just doesn't push a newer version? I'd avoid installing a version of Python that isn't managed by your distro's package management system.

Copy artifacts of each module in multi-module project to specific folder [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Maven multi-module project - copying all “package” JARS from submodules into parent/target/
I have an pom structure:
project1
|
|______ pom.xml
|______ module 1
| |_____ pom.xml
| |_____ dist
| |_____ bin
| |_____ lib
|______ module 2
| |_____ pom.xml
| |_____ dist
| |_____ bin
| |_____ lib
|______ dist
| |____ bin
| |____ lib
Requirements:
+ When build each module, bundle file will be copied to its' dist/bin and dependencies copied to its' dist/lib
+ When build project1, bundle file of each module will be copied to project1/dist/bin and dependencies of all modules copied to project/dist/lib
Can we achieve this??? If it can, how we do it???
Just take a look here: https://github.com/khmarbaise/maven-copy-example . The only thing i changed is not to use a a folder like dist i use target/dist in the maven style.