I am trying to build a shared object for Android using ndk-build command, the source compiles fine but then I get this error:
make (e=206): The filename or extension is too long.
If any body can tell me what causes this problem and how to fix it.
Thanks.
You hit the Windows command length limit. You should use some static libraries as a workaround. Typically, people compile branches of their source tree with separate Android.mk files that end with include $(BUILD_STATIC_LIBRARY), and then list these as $(LOCAL_STATIC_LIBRARIES) in the "main" jni/Android.mk that ends with include $(BUILD_SHARED_LIBRARY). Your ndk-build will load this "main" makefile, so it should include (explicitly or using some nesting approach) all the static library makefiles.
But this is only a convenience. You can achieve the same result if you use single jni/Android.mk file as you have now.
You may also find it easier to list the static libraries as $(LOCAL_WHOLE_STATIC_LIBRARIES) - this way you guarantee that the order of listing these libraries will not cause linking problems.
You can add this to Application.mk
APP_SHORT_COMMANDs :=true
This worked for me.
Maybe as a workaround, you can try to subst the directory "D:\MyFiles\Android\Datte\obj\local\armeabi\objs\ngspice\spicelib" for a drive letter, using:
subst X: "D:\MyFiles\Android\Datte\obj\local\armeabi\objs\ngspice\spicelib"
This could save some space and generate a smaller command line. However, it might not solve your problem, depending on the Windows command length limit, as Alex Cohn answered. Besides, you'll have to change your makefile and change, for example,
D:/MyFiles/Android/Datte//obj/local/armeabi/objs/ngspice/spicelib\parser\inp2y.o
for
X:\parser\inp2y.o
Related
I have an existing .so library (libgit2), and I would like to use this within a C program (the build system is Scons). I read through the entirety of the Scons documentation for "Chapter 4. Building and Linking with Libraries", but there is no mention of how to use an existing .so library. The only mention of .so in the entirety of chapter 4 is on the first page, and it is only about Scons using a .so file for output. How do I use an existing compiled .so library in Scons?
If you are using an sconscript then you should add a LIBS= arguments and a LIBS_PATH=.
if you want to directly add it to the build line, use -L for lib path and -l to link a lib.
You can find further information here: https://scons.org/doc/0.97/HTML/scons-user/x628.html
With help from the SCons Discord server and other places, I've gotten farther than when I first posted this question. I haven't solved my specific problem of using .so libraries with GDNative, but I think I've figured out the SCons side.
As of me posting this question, the SConstruct file was able to compile working code if I didn't use libgit2 and instead just printed out the text. With only the header included, my test call to git_libgit2_version compiled but didn't run, as Godot said undefined symbol: git_libgit2_version.
First of all, you need to add the named parameter for LIBS to your env.SharedLibrary or env.Program line. The lib prefix and .so suffix seem to be added automatically, I still haven't figured out how to make it point to libgit2.so.1.0.1 (so for now I have the library copied and named as libgit2.so, but I would like to have it point to libgit2.so.1.0.1 eventually instead). Also, the SCons team suggested adding LIBPATH, but this doesn't seem to actually do anything.
library = env.SharedLibrary(target=env["target_path"] + env["target_name"] , source=sources, LIBS=['git2'])
Then, the SConstruct file needs to have this magic line:
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
With the above code, ldd will report not found, and Godot will say Error: libgit2.so.1.0: cannot open shared object file: No such file or directory (I have no idea why it's asking for .so.1.0 instead of the .so or .so.1.0.1 file, and yes I tried copying and naming as libgit2.so.1.0 and that doesn't change anything either).
I also added this, which was suggested by another GDNative user.
env.Append(LINKFLAGS=[
'-Wl,-rpath,addons/git_for_godot/gdnative/linuxbsd'
])
With all of the above code, this seems to allow ldd and Godot to find the library just fine with a relative path (when running ldd you have to be cd'd into the project folder). I can run the project fine without any errors, but the project crashes immediately after opening, with no error messages printed. If I comment out the call to git_libgit2_version but keep the header included, the file does compile and run. Any time I try to call anything from libgit2 it causes Godot to crash without printing any errors. At this point I'm stuck and I don't know what I'm doing wrong.
I did try adding libgit2 to the Dependencies section of the .gdnlib file, but this doesn't seem to affect anything. Another thing I tried which didn't work is this line (+ variants on the extension) which append to the sources list passed as the named source parameter. I'll post it here for completeness, but for the moment I have this line commented out because it doesn't work:
sources.append(File("project/addons/git_for_godot/gdnative/linuxbsd/libgit2.so"))
I've got a tool that generates files that contain definitions and declarations. These files need to be included from other source files or headers - they aren't usable standalone.
The obvious thing to do is have a custom command to generate them. My CMakeLists.txt that does this is as follows. I'm currently using this with the GNU makefile generator.
project(test_didl)
cmake_minimum_required(VERSION 3.0)
add_custom_command(
OUTPUT test_didl_structs.h test_didl_structs.c
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/didl.py ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
add_executable(test_didl test_didl.c)
target_include_directories(test_didl PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(test_didl shared_lib)
test_didl.c is very simple:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "test_didl_structs.h"
#include "test_didl_structs.c"
int main(void) {
}
But on the first build, make tries to build test_didl.c, which of course fails, because test_didl_structs.* haven't been generated yet. Naturally, before the first successful build of test_didl.c, the dependency information isn't known, so make doesn't know to run the python command first.
I tried a custom target, but that's no good, because custom targets are assumed to be always dirty. This means the C file is recompiled on every build and the EXE is linked. This approach won't scale.
My eventual solution was to make the output .h file an input to the executable:
add_executable(test_didl test_didl.c test_didl_structs.h)
.h file inputs are treated as dependencies, but don't otherwise do anything interesting for makefile generators. (I am not currently interested in other generators.)
So that works, but it feels a bit ugly. It doesn't actually state explicitly that the custom commands need to be run first, though in practice this seems to happen. I'm not quite sure how, though (but I'm not up to speed on reading the CMake-generated Makefiles just yet).
Is this how it's supposed to work? Or is there something neater I'm supposed to be doing instead?
(What I'm imagining, I suppose, is something like a Visual Studio pre-build step, in that it's considered for running on every build, before the normal dependency checking. But I want this pre-build step to have dependency checking, so that it's skipped if its inputs are older than its outputs.)
My eventual solution was to make the output .h file an input to the executable.
This way is correct.
It actually states, that building executable depends on given file, and, if that file is OUTPUT for some add_custom_command(), this command will be executed before building executable.
Another way is to generate needed headers at configuration stage using execute_process(). In that case there is no need to add header files as sources for add_executable(): CMake has notion of autodetecting dependencies for compiling, so test_didl will be rebuilt after regeneration of test_didl_structs.h.
execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
# ...
add_executable(test_didl test_didl.c)
Drawback of this approach is that you need manually rerun configuration stage after changing your .py files. See also that question and answer to it.
Another problem is that header file will be updated every time configuration is run.
You can try tell cmake that you are using an external source, see docs about set_source_files_properties, see this past post
I would like to compile the following C file on an embedded platform:
https://github.com/openwsn-berkeley/openwsn-fw/blob/develop/firmware/openos/bsp/chips/at86rf231/radio.c
However, as you can see, on lines 20-26 of radio.c it references "radiotimer_capture_cbt":
typedef struct {
radiotimer_capture_cbt startFrame_cb;
radiotimer_capture_cbt endFrame_cb;
radio_state_t state;
} radio_vars_t;
radio_vars_t radio_vars;
So now I need to hunt down where it is defined and make sure I include the right header.
I have cloned the entire GIT repository here: https://github.com/openwsn-berkeley/openwsn-fw, and I'm looking for a way to compile this easily.
Is there a better way to get this compiled other than going through the brutal dependency nightmare?
My ultimate goal is only to get radio.c compiled and anything it needs. I do not see any makefiles in this project so I'm expecting they want us to use an IDE.
The project seems to use scons as a build system. So the simplest way is to dive into the scons files.
There's a small scons file in the directory containing the linked file and two main script in the top directory.
But if you want to play, first remove headers include, try to compile (using -c) to know which one are really needed. Once you get an object file (.o) you can use nm to identify missing symbols (marked with U.) Good luck …
I have a huge project, whole written in C language and I have a single make file that is used to compile it. The project C files contains lots of capitalize problems in it's header files, meaning there are tones of header files that were miss-spelled in lots of C files.
The problem is I need to migrate this project to compile on Linux machine and since Linux is case sensitive I got tones of errors.
Is there an elegant way which I can run make file in Linux and tell him to ignore case sensitive?
Any other solution will be welcome as well.
Thanks a lot.
Motti.
You'll have to fix everything by hand and rename every file or fix every place with #include. Even if you have a huge project (comparable with linux kernel), it should be possible to do this during a hour or two. Automation may be possible, but manual way should be better - because script won't be able to guess which name is right - filename, or the name used in #include.
Besides, this situation is a fault of original project developer. If he/she wasn't sloppy and named every header in every #include correctly, this wouldn't happen. Technically, this is a code problem similar to syntax error. The only right way to deal with it is to fix it.
I think it takes not too long to write a small script, which goes thru the directories first, then replaces C headers. Explained:
Scan the headers' folder and collect filenames.
Make a lowercase list of them. You have now original and locased pairs.
Scan the C source files and find each line contains "#include"
Lowercase it.
Find the lowercase filename in the list collected and lowercased from headers.
Replace the source line with the one collected from headers.
You should put the modified files into a separate folder structure, avoid overwriting the whole source with some buggy stuff. Don't forget to create target folders during the source tree scan.
I recommend a script language for that task, I prefer PHP, but just it's the only server-side script language which I know. Yep, it will run for a while, but only once.
(I bet that you will have other difficulties with that project, this problem is not a typical indicator of high quality work.)
Well I can only tell you that you need to change the case of those header files. I don't know that there is any way you can make it automatic but still you can use cscope to do it in a easier way.
http://www.linux-tutorial.info/modules.php?name=ManPage&sec=1&manpage=cscope
You can mount the files on a case-insensitive file system. FAT comes to mind. ntfs-3g does not appear to support this.
I use the find all and replace all functionality of Source Insight when i have to do complete replacement. But your problem seems quite big, but you can try the option to replace every header file name in all occurences of source files using the
"Find All" + "Replace" functionality. You can use notepad++ too for doing the same.
A long time ago there was a great tool under MPW (Macintosh Programmer's Workshop) called Canon. It was used to canonize text files, i.e. make all symbols found in a given refernce list have have the same usage of upper/lower case. This tool would be ideal for a task like this - I wonder if anything similar exists under Linux ?
When I work on someone else's code, I tipically need to abuse of grep in order to find data types declarations etc, and this usually makes me confused.
I'd like to have some tool which analyzes the source code and produces some graphviz-like drawing and allows me to follow dependencies.
Also I've found this on the internet, but I think is taylored for the linux kernel only.
Have you tried doxygen?
Doxygen can produce dot files, and you can build the documentation without changing the source code with the right options set in the Doxyfile.
Do you use an editor that can take advantage of tags ? In Emacs, I just type M-. to go to the definition of a symbol, and M-* to go back to where I was once I have read it. This also enables the command tags-search to grep among the files of the software project (very convenient if they are in multiple directories).