I’m trying to add an a directory contain new header files to “CXXFLAGS” in makefile, e.g.:
prefs.devices.cpp_standalone.extra_make_args_unix += [‘CXXFLAGS += -I/new_dir’]
Somehow, this seems not the right way to use the command because the compilation command doesn’t show this new_dir is included in the CXXFLAGS. Any inputs would be appreciated.
Hi. To globally add compiler flags, you should add them to the list stored in the codegen.cpp.extra_compile_args_gcc
preference (see Preferences — Brian 2 2.5.1 documentation).
For include directories, there’s also a dedicated preference codegen.cpp.include_dirs
.
Finally, for specific user-defined functions you can add header files and include directories directly in the @implementation
decorator: Functions — Brian 2 2.5.1 documentation
After including the header file as instructed, the code works well in brian2.4.2 but still won’t compile brian2.5.1. In the brian2.5.1, the generated “code_objects” directory include two separate codes:
poissongroup_spike_thresholder_codeobject.cpp
after_run_poissongroup_spike_thresholder_codeobject.cpp # not exist in brian2.4.2
The “poissongroup_spike_thresholder_codeobject.cpp” contains all needed files and compiles successful, but the “after_run_poissongroup_spike_thresholder_codeobject.cpp” miss the “#include” and compilation complains the needed variables is not defined. I attached the test example to show the issue. More inputs are appreciated.
The “test.py” is:
import os
from brian2 import *
set_device('cpp_standalone', directory='standalone', debug=True)
current_dir = os.path.abspath(os.path.dirname(__file__))
@implementation('cpp', '''
using namespace aaa;
double test() {
return val;
}
''',
headers=['"oo.h"'],
include_dirs=[current_dir]
)
@check_units(result=Hz)
def test():
raise NotImplementedError('use standalone mode')
##
input = PoissonGroup(10, rates='test()')
run(1*second, report='text')
The “oo.h” containing the namespace aaa is:
using namespace std;
namespace aaa
{
int val = 10;
}
Thanks for the report and the example for easy replication! There was indeed a bug related to this in recent Brian versions, I fixed it with this PR: include user headers in before/after blocks by mstimberg · Pull Request #1436 · brian-team/brian2 · GitHub
After installing the latest development version as described here, it should work correctly. Note that your code needs a small addition/change, though: header files need to be able to be included in several places (here in the poissongroup_...
and the after_run_poissongroup_...
files) – this is not the case for your file. If you need to define external variables, you need to only include the declaration in the header file, and define the variable in a separate source file. I.e., your example should look like this:
import os
from brian2 import *
set_device('cpp_standalone', directory='standalone', debug=True)
current_dir = os.path.abspath(os.path.dirname(__file__))
@implementation('cpp', '''
using namespace aaa;
double test() {
return val;
}
''',
headers=['"oo.h"'],
sources=[os.path.join(current_dir, 'oo.cpp')], # ← NEW
include_dirs=[current_dir]
)
@check_units(result=Hz)
def test():
raise NotImplementedError('use standalone mode')
##
input = PoissonGroup(10, rates='test()')
run(1*second, report='text')
Together with oo.h
:
namespace aaa
{
extern int val;
}
and oo.cpp
:
namespace aaa {
int val = 10;
}
1 Like