Can nw addon be built with _HAS_ITERATOR_DEBUGGING=1 for debug mode? (Windows) - chromium

Original questin: Is there any way to get what macros nw-gyp add to the build project by default?
I'm developing a nw addon and I've tried to link a custom static lib to .node DLL. However I found nw-gyp will add _HAS_ITERATOR_DEBUGGING=0 by default (It always appends to the addon project to override custom defines), which will affect the actual structure size for STL types (e.g. std::string).
So is there a way to get such macros node gyp added by default, or is there an easy way to make compiler's (maybe the whole toolchain, link tool etc.) configuration for both static lib and nw build project the same?
Now I've add _HAS_ITERATOR_DEBUGGING=0 to my lib and make it MT(D), and It seems to work fine, but I'm not sure if this is the right way. (Some other compiler settings may not cause compilation error but can crash in runtime)
Edit: Share some analysis to make my origin question clearer.
All current question is on Windows platform.
The _HAS_ITERATOR_DEBUGGING=0 is added even when I build nw addon in debug mode (with --debug), and this may be affected by the nw headers downloaded by nw-gyp. For example, headers download from http://node-webkit.s3.amazonaws.com/v0.49.2/nw-headers-v0.49.2.tar.gz , you will find 'defines': [ 'DEBUG', '_DEBUG', 'V8_ENABLE_CHECKS', '_HAS_ITERATOR_DEBUGGING=0' ] in common.gypi at line 288 in Debug_Base config section, and this is most likely inherit from https://github.com/nwjs/chromium.src (I guess here https://github.com/nwjs/chromium.src/blob/nw60/build/config/BUILD.gn#L130). So can it be concluded that Chrome add these defines for debug mode on purpose?
What is the problem _HAS_ITERATOR_DEBUGGING=0 in debug for me? Well, it affects the size for many STL classes (std::string, std::vector and etc.). So all debug lib that need to be linked to nw addon should be compiled with '_HAS_ITERATOR_DEBUGGING=0', otherwise compilation error will occur for static libs and runtime pointer problem crash (struct offset mismatch) for dynamic libs (of course it is not a good practice to use STL in dynamic lib headers, but if you can assume the toolchain same it will still work fine). But this is really hard for me when it comes to third-party binaries, I've got no sources for most of them, so I can't give a debug static lib with _HAS_ITERATOR_DEBUGGING=0 on. This is really frustrating when I need to debug the addon with lldb or VS, since all variables are optimized and you cannot debug their values.
Can I force _HAS_ITERATOR_DEBUGGING=1 for debug mode? As mentioned in origin question, it cannot be done normally like answer from #mmomtchev. A hack way to do is to add "/D _HAS_ITERATOR_DEBUGGING=1" to configurations->Debug->msvs_settings->VCLinkerTool->AdditionalOptions in gyp file for addon, this will append /D _HAS_ITERATOR_DEBUGGING=1 to the end of the compile command which override the former defination. But I'm not sure if this is a good workaround! I've checked v8 header files and have found some classes with std::string and std::vector members. I think force _HAS_ITERATOR_DEBUGGING will cause some problem if you use these classes, but for other classes it is safe (I've tested many cases, normal classes like v8::value v8::function work well). And it is not safe when cooperating with other addons. Let's assume one debug addon A and another release addon B need to communicate with each other, they agree on one C++ struct for data exchange. A common way is to let A to wrap a C++ struct instance to a JS object for user. and let user pass the JS object to B by calling methods provided by B (the JS object is one of the arguments), and then B unwrap the JS object from arguments and get the pointer of the C++ struct instance. All looks fine, but what if the C++ struct has std::string member? The sizes of same C++ struct for A and B are not the same. so B will crash when trying to access the member with type of std::string or std::vector. This is not an issue if _HAS_ITERATOR_DEBUGGING=0 is set for debug mode since _HAS_ITERATOR_DEBUGGING is always disabled for release, and I guess that's why nw addon can work with mixed production mode(debug an release) addons in common cases.
So my final question is: If it is not a good way to force _HAS_ITERATOR_DEBUGGING=1 for debug and I don't have source code for many external compiled lib binaries, does it mean I've no way to build a nw addon in debug mode? Athother possible way is to wrapper those libs with C style API and compile them to dynamic libs, but this is really huge work for me and is unacceptable.

Normally, _HAS_ITERATOR_DEBUGGING=0 is defined by default on all Release builds.
If you need to add macros, you need to add this section to the root of your gyp:
'defines': [ '_HAS_ITERATOR_DEBUGGING=0' ]

Related

Find out why cmake adds specific link flags

I have big project with cmake. It mostly works.
But recently some combination of compilation server vs test server broke. Investigation found that final compile/link command calls gcc (...) -licudata -licui18n -licuuc (...), this introduces dependency on shared library which is not present on test server.
How do I find out what in my project (my library, imported library, found library, whatever) adds those 3 flags to compile command?
I don't add them explicitly, so something is done automagically and I want to find it. compile_commands.json doesn't have them because linking flags don't belong in it. CMakeCache.txt has those flags in some obscure variable PC_LIBXML_STATIC_LIBRARIES:INTERNAL but removing them there doesn't affect compile/link command.
Note that this question is not about dealing with libicu specifically but about a method for investigation in general (though comments about eventual known problems with libicu would be appreciated too).
I found out that dependency graphs created by cmake can have more details that was configured for our project. Here are all options: https://cmake.org/cmake/help/latest/module/CMakeGraphVizOptions.html I expect GRAPHVIZ_EXTERNAL_LIBS, GRAPHVIZ_SHARED_LIBS are most important to set to true.
We enabled everything that was possible to enable, filtered out nothing and resulting graph was massive (to big for xdot - luckily .dot files are human readable), but showed that Boost::regex uses those 3 libraries.

How to reuse Fortran modules without copying source or creating libraries

I'm having trouble understanding if/how to share code among several Fortran projects without building libraries or duplicating source code.
I am using Eclipse/Photran with the Intel compiler (ifort) on a linux system, but I believe I'm having a bigger conceptual problem with modules than with the specific tools.
Here's a simple example: In ~/workspace/cow I have a source directory (src) containing cow.f90 (the PROGRAM) and two modules m_graze and m_moo in m_graze.f90 and m_moo.f90, respectively. This project builds and links properly to create the executable 'cow'. The executable and modules (m_graze.mod and m_moo.mod) are stored in ~/workspace/cow/Debug and object files are stored under ~/workspace/cow/Debug/src
Later, I create ~/workplace/sheep and have src/sheep.f90 as the program and src/m_baa.f90 as the module m_baa. I want to 'use m_graze, only: ruminate' in sheep.f90 to get access to the ruminate() subroutine. I could just copy m_graze.f90 but that could lead to code getting out of sync and doesn't take into account any dependencies m_graze might have. For these reasons, I'd rather leave m_graze in the cow project and compile and link sheep.f90 against it.
If I try to compile the sheep project, I'll get an error like:
error #7002: Error in opening the compiled module file. Check INCLUDE paths. [M_GRAZE]
Under Properties:Project References for sheep, I can select the cow project. Under Properties:Fortran Build:Settings:Intel Compiler:Preprocessor I can add ~/workspace/cow/Debug (location of the module files) to the list of include directories so the compiler now finds the cow modules and compiles sheep.f90. However the linker dies with something like:
Building target: sheep
Invoking: Intel(R) Fortran Linker
ifort -L/home/me/workspace/cow/Debug -o "sheep" ./src/sheep.o
./src/sheep.o: In function `sheep':
/home/me/workspace/sheep/src/sheep.f90:11: undefined reference to `m_graze_mp_ruminate_'
This would normally be solved by adding libraries and library paths to the linker settings except there are no appropriate libraries to link to (this is Fortran, not C.)
The cow project was perfectly capable of compiling and linking together cow.f90, m_graze.f90 and m_moo.f90 into an executable. Yet while the sheep project can compile sheep.f90 and m_baa.f90 and can find the module m_graze.mod, it can't seem to find the symbols for m_graze even though all the requisite information is present on the system for it to do so.
It would seem to be an easy matter of configuration to get the linker portion of ifort to find the missing pieces and put them together but I have no idea what magic words need to be entered where in the Photran UI to make this happen.
I confess an utter lack of interest and competence in C and the C build process and I'd rather avoid the diversion of creating libraries (.a or .so) unless that's the only way to make this work.
Ultimately, I'm looking for a pure Fortran solution to this problem so I can keep a single copy of the source code and don't have to manually maintain a pile of custom Makefiles.
So can this be done?
Apologies if this has already been documented somewhere; Google is only showing me simple build examples, how to create modules, and how to link with existing libraries. There don't seem to be (m)any examples of code reuse with modules that don't involve duplicating source code.
Edit
As respondents have pointed out, the .mod files are necessary but not sufficient; either object code (in the form of m_graze.o) or static or shared libraries must be specified during the linking phase. The .mod files describe the interface to the object code/library but both are necessary to build the final executable.
For an oversimplified toy problem such as this, that's sufficient to answer the question as posed.
In a larger project with more complex dependencies (in my case, 80+KLOC of F90 linking to the MKL version of LAPACK95), the IDE or toolchain may lack sufficient automatic or user-interface facilities to make sharing a single canonical set of source files a viable strategy. The choice seems to be between risking duplicate source files getting out of sync, giving up many of the benefits of an IDE (i.e. avoiding manual creation of make/CMake/SCons files), or, in all likelihood, both. While a revision control system and good code organization can help, it's clear that sharing a single canonical set of source files among projects is far from easy given the current state of Eclipse.
Some background which I suspect you already know: Typically (including ifort) compiling the source code for a Fortran module results in two outputs - a "mod" file that contains a description of the Fortran entities that the module defines that the compiler needs to find whenever it sees a USE statement for the module, and object code for the linker that implements the procedures and variable storage, etc., that the module defines.
Your first error (the one you solved) is because the compiler couldn't find the mod file.
The second error is because the linker hasn't been told about the object code that implements the stuff that was in the source file with the module. I'm not an Eclipse user by any means, but a brute force way of specifying that is just to add the object file (xxxxx/Debug/m_graze.o) as an additional linker option (Fortran Build > Settings, under Intel Fortran Linker > Command Line). (Other tool chains have explicit "additional object file" properties for their link stage - there may well be a better way of doing this for the Intel chain.)
For more involved examples you would typically create a library out of the shared code. That's not really C specific, the only Fortran aspect is that the libraries archive of object code needs to be provided alongside the mod files that the Fortran compiler generates.
Yes the object code must be provided. E.g., when you install libnetcdf-dev in Debian (apt-get install libnetcdf-dev), there is a /usr/include/netcdf.mod file that is included.
You can now use all netcdf routines in your Fortran code. E.g.,
program main
use netcdf
...
end
but you'll have link to the netcdf shared (or static) library, i.e.,
gfortran -I/usr/include/ main.f90 -lnetcdff
However, as user MSB mentioned the mod file can only be used by gfortran that comes with the distribution (apt-get install gfortran). If you want to use any other compiler (even a different version that you may have installed yourself) then you'll have to build netcdf yourself using that particular compiler.
So creating a library is not a bad solution.

How do I link multiple libraries in a Firebreath plugin?

Does anyone know where I can find a Firebreath sample (either Mac OS X or Windows) that illustrates how to create a plugin that includes 1 or more other libraries (.DLLs or .SOs) that each rely on other sub-projects built as static libraries (LIBs)?
For example, let's say that the Firebreath plugin is called PluginA, and that PluginA calls methods from DLL_B and DLL_C. DLL_B and DLL_C are C++ projects. DLL_B calls methods from another project called LIB_D, and DLL_C calls methods from a project called DLL_E.
Therefore, the final package should contain the following files:
PluginA.dll
DLL_B.dll (which also incorporates LIB_D)
DLL_C.dll
DLL_E.dll
I am currently forced to dump all source files in the pluginA solution, but this is just a bottleneck (for example I cannot call libraries written in other languages, such as Objective-C on Mac OS X).
I tried following the samples on Firebreath, but couldn't get them to work, and I found no samples from other users that claimed they were able to get it to work. I tried using CMAKE, and also running the solutions directly from X-Code, but the end result was the same (received linking errors, after deployment DLL_C couldn't find DLL_E etc.)
Any help would be appreciated - thank you,
Mihnea
You're way overthinking this.
On windows:
DLLs don't depend on a static library because if they did it would have been compiled in when they were built.
DLLs that depend on another DLL generally just need that other DLL to be present in the same location or otherwise in the DLL search path.
Those two things taken into consideration, all you need to do is locate the .lib file that either is the static library or goes with the .dll and add a target_link_library call for each one. There is a page on firebreath.org that explains how to do this.
On linux it's about the same but using the normal rules for finding .so files.

Having to Link Binary With Libraries twice when using a static library in XCode

I am trying to use a static library in a project. The static library depends on several frameworks... CoreData, CFNetwork, AddressBook, etc.
The static library also uses categories, so I am forced to use the -all_load linker option in the main project's "Other Linker Settings". When I enable this, I get 120 errors all relating to my main project not being linked with the same frameworks as my static library (CoreData, CFNetwork, AddressBook, etc).
It is very inconvenient for a developer to want to use a static library, link to it, but then still be required to link to all of the frameworks that the library links to. Is there any way to automate this process, so that the main project automatically links to all of the frameworks linked to by the static library?
I am using XCode 4.4.
edit: to be more clear, I have the following:
StaticLibrary.xcodeproj
- AFNetworking
- files...
- CoreData
- categories for NSManagedObjectContext, for convenience
- AddressBook
- convenience methods for working with contacts
This project's target is linked to the necessary frameworks under Build Phases > Link Binary With Libraries. This includes CoreData.framework, AddressBook.framework, etc.
Now what I would like to do is add this library to another project of mine. In fact, I would like to add this library to every new project I make from here on out, so I always have easy access to the convenience functions/categories that I've written. So: I add the library to my project, and then add the .a file to Build Phases > Link Binary With Libraries (of my main project). I also do everything else necessary that I know of (see comments).
What I would like to happen: the main project is now linked to the library, so it inherits all of the library's links so that the main project is now also linked to CoreData.framework, AddressBook.framework, etc.
What does happen: the main project gives me errors because it is not linked to anything that the library requires.
Is there a way to automatically add the linked frameworks from the static library to the main project, or should I split the library up into CoreDataStaticLibrary, etc, and then require the developer to add CoreData.framework as well as the static library to the project target everytime?
As I understand, you should only need -all_load if your library contains only categories. Otherwise, you can use -ObjC. That's what I use, at any rate.
Also, when you build a static library, you are just creating an archive of compiled object modules. No external dependencies are resolved in the library. Really, you should just think of it as a single collection of a bunch of object code files.
So, when you finally link your executable, it will link all your compiled code, along with the archive of pre-compiled code in your static libraries. The linker will expect to resolve all symbols, so you must tell it where to find all the libraries (frameworks) that are needed to completely resolve all the symbols.
Should XCode be able to look inside a static-library subproject and pull out the framework dependencies from that project and add them to the linker invocation for the final project? Sure. But, I'm not aware of a way to make that happen automatically.
If you want, you can create a podfile for your library, and use CocoaPods to manage your project dependencies.
The problem is you're including the same symbols several times. I've run into the same issue several times and the solution is basically to understand what the "-all_load" flag does, which is pretty well explained in this SO question: What does the all load linked flag do
Said that, you never reference frameworks from your library in that way. Since these frameworks are dynamically linked they don't really belong to your static library, there are just references pointing to them on it.
The user of such library should be responsible of adding the necessary frameworks to make it work properly. This means, you don't have to link your library to such frameworks (as such thing just doesn't make sense), just add them to project that's gonna use it. (Have a look on Restkit to see how it's done).
Also, I think you could get rid of the "all_load" flag and try to replace it with "force_load /path/to/the/library" all_load is only necessary in case your library only contains categories (no classes at all).
Let us know how it goes and happy coding!

Static Library using frameworks in specific projects

I have created a static library containing all my generic classes. Some of these classes use frameworks.
Now I have two projects, one that uses some classes that use frameworks, and one that doesn't use any of the classes that use frameworks.
Because Static Libraries don't support including frameworks (if I am correct). I have to include the frameworks in the project that uses them. But when I compile the project that doesn't use any of the framework-classes the compiler breaks because it still requires the frameworks. Now I know it tries to compile all the (unused) classes from the library because I use the Linker Flag '-ObjC' to prevent 'unrecognized selector' errors.
Does anyone know how to compile only the required source files per project? And prevent from all frameworks having to be included in all projects that use my static library?
First of all, you are right in that a static library cannot include any framework nor other static libraries, it is just the collection of all object files (*.obj) that make up that specific static library.
Does anyone know how to compile only the required source files per project?
The linker will by default only link in object files from the static library that contain symbols referenced by the application. So, if you have two files a.m and b.m in your static library and you only use symbols from a.m in your main program, then b.o (the object file generated from b.c) will not appear in your final executable. As a sub-case, if b.m uses a function/class c which is only declared (not implemented), then you will not get any linker errors. As soon as you include some symbols from b.m in your program, b.o will also be linked and you will get linker errors due to the missing implementation of c.
If you want this kind of selection to happen at symbol rather than at object level granularity, enable dead code stripping in Xcode. This corresponds to the gcc option -Wl,-dead_strip (= linker option -dead_strip in the Build settings Info pane for your project). This would ensure further optimization.
In your case, though, as you correctly say, it is the use of the "-ObjC" linker flag that defeats this mechanism. So this actually depends on you. If you remove the -Objc flag, you get the behavior you like for free, while losing the stricter check on selectors.
And prevent from all frameworks having to be included in all projects that use my static library?
Xcode/GCC support an linking option which is called "weak linking", which allows to lazily load a framework or static library, i.e., only when one of its symbols is actually used.
"weak linking" can be enabled either through a linker flag (see Apple doc above), or through Xcode UI (Target -> Info -> General -> Linked Libraries).
Anyhow, the framework or library must be available in all cases at compile/link time: the "weak" option only affects the moment when the framework is first loaded at runtime. Thus, I don't think this is useful for you, since you would need anyway to include the framework in all of your projects, which is what you do not want.
As a side note, weak_linking is an option that mostly make sense when using features only available on newer SDK version (say, 4.3.2) while also supporting deployment on older SDK versions (say, 3.1.3). In this case, you rely on the fact that the newer SDK frameworks will be actually available on the newer deployment devices, and you conditionally compile in the features requiring it, so that on older devices they will not be required (and will not produce thus the attempt at loading the newer version of the framework and the crash).
To make things worse, GCC does not support a feature known as "auto-linking" with Microsoft compilers, which allow to specify which library to link by means of a #pragma comment in your source file. This could offer a workaround, but is not there.
So, I am really sorry to have to say that you should use a different approach that could equally satisfy your needs:
remove the -ObjC flag;
split your static library in two or more parts according to their dependencies from external frameworks;
resort to including the source files directly.
Abour second part of your question, you can mark a linked framework as Optional :
About first part, it is not clear to me what you intend to do:
A library being declared in a project
A project declaring which files are compiled (via Target > Build phases > Compile sources)
Unless setting complex build rules to include or not files, which if I remember well can be done using .xcconfig files, I don't see any other solutions than splitting your Library. Which I would recommend, for its ease. You should even do several targets in the same project... You could also just use precompiler MACROS (#ifdef...) but that depends on what you want to do.
It sounds like you have library bloat. To keep things small I think you need to refactor your library into separate libraries with minimal dependencies. You could try turning on "Dead Code Stripping" in the "Linker Flags" section of the build target info (Xcode 3.x) to see if that does what you want (doesn't require frameworks used by classes that are dead-stripped.)
When you link against a framework on iOS I don't think that really adds any bloat since the framework is on the device and not in your application. But your library is still a bit bloated by having entire classes that never get used but are not stripped out of the library.
A static library is built before your app is compiled, and then the whole thing is linked into your app. There's no way to include some parts of the library but not others -- you get the whole enchilada.
Since you have the source code for the library, why not just add the code directly to each application? That way you can control exactly what goes into each app. You can still keep your generic classes together in the same location, and use the same code in both apps, but you avoid the hassle of using a library.