How to include parent directory include path in Android.mk? - c

I'm building using the NDK and am having trouble getting the parent directory in the include path. I tried this:
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
But that does not work, apparently the .. is not processed as I would expect. I ran make -n to see the generated command which includes what I want:
-I/Users/me/android/workspace/jni/module/popt/..
But it fails, although if I manually edit it to instead be:
-I/Users/me/android/workspace/jni/module
It works fine. What should I put in the Android.mk file to include the parent directory in the search path without using ..?
The issue is that popt is a symbolic link, so parent directory .. is not module.

Nothing will be expanding the .. and actually modifying the earlier parts of the path - this is pretty much the same in any build system if you specify a relative path with ...
Why doesn't -I/Users/me/android/workspace/jni/module/popt/.. give the same result as -I/Users/me/android/workspace/jni/module? Is popt a symlink to a different place? In that case, I think a solution would be to define a separate variable in jni/module/Android.mk like MODULE_PATH := $(LOCAL_PATH) and use $(MODULE_PATH) instead of $(LOCAL_PATH)/.. in the other Android.mk file.

you can use "wildcard", for example:
PARENT_DIR_PATH := $(wildcard ..)

Related

How to add subdir sources in target? [duplicate]

I have project which has not been divided into libraries, but the source is organized in a directory tree. I do not know how to tell cmake to go down a directory, then add the source in that directory to project defined in the parent directory. I have attempted the following:
in project/source/CMakelists.txt:
set(SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/unitTest/main.cpp
)
add_subdirectory("${PROJECT_SOURCE_DIR}/folder1")
add_executable(UnitTestRNG ${SOURCE} ${HEADERS})
then in project/source/folder1/CMakeLists.txt:
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/file1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp
)
set(HEADERS
${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/file1.hpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.hpp
)
using some message() statements, I have found that the the child folder will get the contents of the SOURCE variable, but it's new assignment to that variable will not persist on returning to the parent CMakeLists.txt
Looking for examples and at the cmake tutorial has led me to the conclusion that:
- Source file structures are usually flat within a project
- If code is divided into folders, it is usually is divided into corresponding libraries.
I wonder if there is some "best practice" from which I am deviating by attempting this structure.
Since CMake 3.1 there is a new way to add source from subdirectories: target_sources
Say you have root_dir and root_dir/sub_dir and source files in both. With target_sources you can do this:
In root_dir/CMakeLists.txt define the target
add_library(some_target main.cpp)
add_subdirectory(sub_dir)
In root_dir/sub_dir/CMakeLists.txt add sources:
target_sources(some_target PRIVATE more_cool_stuff.cpp)
some_target will now contain both source files.
It is also possible to use other commands in root_dir/sub_dir/CMakeLists.txt using some_target, for example target_compile_definitions which is quite convenient to add compilation definitions.
I learned about target_sources here, check it out if you want more explanation and examples
Like the second part of arrowdodger's answer says:
in project/source/folder1/CMakeLists.txt:
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/file1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.cpp
PARENT_SCOPE
)
set(HEADERS
${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/file1.hpp
${CMAKE_CURRENT_SOURCE_DIR}/file2.hpp
PARENT_SCOPE
)
Can't you just set all your sources in project/source/CMakelists.txt then?
Anyway, what you need is PARENT_SCOPE or CACHE option on set command.

Shake build capturing directories

I have recently converted my works make based build system to shake. I am now trying to make shake a little more robust to changes in the directory structure so that I do not have to regenerate the build system.
Each of my projects use are C based and have the following directory structure
src
source folder 1
source folder 2
inc
inc folder 1
inc folder 2
I am able to capture all the source files but what I cant get to work is capturing the include folders. The root inc folder and the sub folders I am trying to capture into a variable in the build system. I have been using the following setup
includes = getDirectoryDir "inc"
This will give me the included sub folders but not the root folder inc. Which I thought I could work around but inc will not be tracked.
What I would like is to have something like
includes = getDirectoryDirAndRoot "inc"
Which will capture each of the subdirectories and the root directory and have them tracked in the build system.
That aside what I have also tried to use
gcc -o out includes
But I would need to have every element in includes prepended with "-I" which I can't seem to figure out.
I guess how would one go abut doing this in shake, in make I can accomplish all of this by using makes shell function and a couple of string manipulation functions.
I think the question can be interpreted both ways, and both ways are useful (you may even want both), so I'll give two answers:
Answer 1: You want the C file to be recompiled if any file in the inc directory changes.
"*.c" *> \out -> do
headerFiles <- getDirectoryFiles "inc" "**/*.h"
need headerFiles
...
This snippet gets a list of all header files in the inc directory (or it's subdirectories) and introduces a dependency on them. If any header file changes, this rule will rerun.
Answer 2: You want to get the list of directories to pass to gcc.
"*.c" *> \out -> do
includeDirs <- getDirectoryDirs "inc"
cmd "gcc -c" [out] "-Iinc" (map ("-Iinc/" ++) includeDirs)
...
This snippet gets the directory names under inc and then uses map to prepend -Iinc/ over them. It also passes -Iinc directly. If the list of directories under inc changes this rule will rebuild. However, if the header files contained in those directories change nothing will rebuild. You can add dependencies on the used header files with the gcc -MD family of flags, as described in the Shake user manual, or using the technique from Answer 1.
Have a look at addOracle and its cousin addOracleCache. This should allow you to depend on information besides the files themselves, such as directories to be included.
But I would need to have every element in includes prepended with "-I" which I can't seem to figure out.
You can use Haskell here. If you have a list of directories directories :: [FilePath], you can turn those into compiler flags with
asIncludes :: [FilePath] -> [String]
asIncludes = fmap ("I" ++)

Is it possible to specify a #include file path relative to the user's current directory when compiling?

I know it is possible to specify #include filepaths either relative to the directory the file is located in, as an absolute file path, or relative to any of the directories in the $PATH system variable. Is there a way to instead specify it relative to the user's current directory when the program is compiled? Let's say I have the following file structure:
|--dir_a/
| |--a.c
| |--a.h
|--dir_b/
| |--b.c
| |--b.h
|--makefile
Now let's say I want to #include the file dir_a/a.h from dir_b/b.h. Using the location of dir_b/b.h, this can be written like this:
#include ../dir_a/a.h
However, this approach has a major flaw in my opinion since it hardcodes the locations of files relative to each other, meaning that relocating a file would require updating the file path everywhere that file was included from.
Using absolute file paths would avoid this problem, but would instead hardcode the location of the project within the filesystem, which seems like bad practice.
Finally, using the <> tags to specify the file path isn't feasible either since I can't assume the project will be listed in the $PATH variable.
So what I want to do is to be able to specify the paths relative to where the user compiles from (or even better, from the location of the makefile). In the above example, this would let me use the following statement to #include dir_a/a.h from dir_b/b.h:
#include dir_a/a.h
This I think would be the ideal solution. It would make the #include statements more consistent and easier to follow, as well as avoid the drawbacks I listed above. Is it possible to do this in any way, eg. with a compiler flag or something? I'm using gcc as my compiler.
If you consistently use <> includes, then the -I options in the makefile should be enough. The directory layout shows only one makefile, in the parent directory. That could use
-Idir_a -Idir_b
in the compiler options, and the .c files could just do
#include <a.h>
#include <b.h>
One of the problems with quoted includes is that their behavior with other compilers may differ, as noted in What is the difference between #include <filename> and #include “filename”? (the standard was not explicit enough). Using a gcc extension probably does not improve that situation.
I managed to solve my problem.
The first part of the solution involves specifying the -iquote flag in gcc when compiling. From man gcc:
-iquotedir
Add the directory dir to the head of the list of directories to be searched for header files only for the case of #include "file"; they are not searched for #include <file>, otherwise just like -I.
The second part of the puzzle was how to get the path to the makefile within the makefile itself. This answer worked for me. I'm pasting the solution here for convenience:
ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
edit: While this approach works, this answer is more cross-compiler friendly, so I'm personally going to use that.
Yes. Any include file, which is not directly in your include path specified in your project linker settings, should have all subfolders up to it specified, like:
#include "first/second/third/folder/library.h"

How to define relative paths in Visual Studio Project?

I have a library and a console application that uses a library. The library has a folder with source and header files.
My project is in a child/inner directory but that library directory that I want to include is in a parent/upper directory.
My project directory:
H:\Gmail_04\gsasl-1.0\lib\libgsaslMain
Includes files are here:
H:\Gmail_04\gsasl-1.0\src
How can I use paths relative to the project directory, to include folders that are in a parent/upper directory?
Instead of using relative paths, you could also use the predefined macros of VS to achieve this.
$(ProjectDir) points to the directory of your .vcproj file, $(SolutionDir) is the directory of the .sln file.
You get a list of available macros when opening a project, go to
Properties → Configuration Properties → C/C++ → General
and hit the three dots:
In the upcoming dialog, hit Macros to see the macros that are predefined by the Studio (consult MSDN for their meaning):
You can use the Macros by typing $(MACRO_NAME) (note the $ and the round brackets).
If I get you right, you need ..\..\src
I have used a syntax like this before:
$(ProjectDir)..\headers
or
..\headers
As other have pointed out, the starting directory is the one your project file is in(vcproj or vcxproj), not where your main code is located.
By default, all paths you define will be relative. The question is: relative to what? There are several options:
Specifying a file or a path with nothing before it. For example: "mylib.lib". In that case, the file will be searched at the Output Directory.
If you add "..\", the path will be calculated from the actual path where the .sln file resides.
Please note that following a macro such as $(SolutionDir) there is no need to add a backward slash "\". Just use $(SolutionDir)mylibdir\mylib.lib.
In case you just can't get it to work, open the project file externally from Notepad and check it.
There are a couple of hints you need to know.
consider your app is running under c:\MyRepository\MyApp
a single dot on your path means the folder where your app runs. So if you like to reach some folder or file under MyApp folder (imagine c:\MyRepository\MyApp\Resources\someText.txt) you can do it like var bla = File.Exists(./Resources/someText.txt)
and you can go one level up with double dots (..) think about a folder under c:\MyRepository\SomeFolder\sometext.txt
for MyApp, it will be like
var bla = File.Exists(../SomeFolder/someText.txt)
and it is possible to go 2,3,4.. levels up like
../../SomeFolder (2 levels up)
../../../SomeFolder (3 levels up)
and path starting with no dots means the drive root. var bla = File.Exists(/SomeFolder/someText.txt) will look for the c:\SomeFolder\someText.txt in our scenario.

Using files in Check test cases

I need to use a file for one of my tests written using Check. I initially hardcoded the path, which worked fine. However, this didn't work when the code is built outside of the source directory. I came up with the following solution which somewhat works. (I then prefix pathnames with TESTS_DIR)
# Set correct directory for test files
AS_IF([test "x$srcdir" = x.],
[TESTS_DIR=""],
[TESTS_DIR="$srcdir/tests/"])
AC_DEFINE_UNQUOTED([TESTS_DIR], ["$TESTS_DIR"], [directory for test files])
Unfortunately, this fails again for make distcheck. I could post specific path layouts and structures, but I'm wondering if there's an "easy" way to refer to files in the source directory in all these cases. Thanks!
UPDATE: I've tried to use absolute paths, but it seems $abs_top_srcdir isn't set when I tried to update the define in configure.ac. Any thoughts as to why that is would be appreciated.
I discovered that the problem was that $top_srcdir is not set at configure time. Instead, I added -DTESTS_DIR="\"$(top_srcdir)/tests/\"" to AM_CFLAGS in my tests Makefile.am and also added all directories containing test files to EXTRA_DIST.

Resources