I am having a project where suppose:
Project structure is root/p1/mod1/include/test.hrl and root/p2/mod2/foo.erl
I have a erlang hrl file in root/p1/mod1/include and i have included it in erlang file (.erl) in root/p2/mod2
When I am compiling file foo.erl it gives following error:
foo.erl:16: can't find include file "test.hrl"
I tried including it in -I flag of erlc such as below:
user[root/p2/mod2]$ erlc foo.erl -I "/local/user/root/p1/mod1/include"
foo.erl:16: can't find include file "test.hrl"
But it does not seem to solve it.
Can anyone help on how to resolve it?
In Erlang, the command should be below:
erlc flags file1.ext file2.ext...
Compiles one or more files. The files must include the extension, for example, .erl for Erlang source code, or .yrl for Yecc source code. Erlc uses the extension to invoke the correct compiler
The following flags are supported:
-I 'Directory'
So just move your -I before erl file:
erlc -I "/local/user/root/p1/mod1/include" foo.erl
Related
i'm working on a project requiring cmake. i'd like to add some custom rules to my makefile, but can't quite get my head around how to do it.
both c source files and header files are in the same directory. also in this same directory are a number of .def files, which are the sources for some of the header files #included in the source during compilation.
if i were to do this in a makefile, i'd use a simple rule like
.SUFFIXES: .def
.def.h:
$(PREPROC) $< > $#
how can i do this with cmake ??
i've tried various permutations of the following, both with and without cmake working directory specifications :
add_custom_command(
OUTPUT vvr_const.h
PRE_BUILD
COMMAND preproc vvr_const.def > vvr_const.h
DEPENDS vvr_const.def
)
add_custom_target(vvr_const.h DEPENDS vvr_const.def)
but the header file isn't generated by the time the c source file is compiled, so the compile fails. i've also tried a variation where i replace the last line above with
set_property(SOURCE main.c APPEND PROPERTY OBJECT_DEPENDS vvr_const.h)
in this case, the header file is correctly generated in advance, but make can't find it, and complains that there's no rule to make the target .h.
ideally this would be a general rule, like the make rule above, but i'm not opposed to making a separate rule for each of the .def files if that's what it takes.
cheers.
There are 2 problems with the add_custom_command approach you present:
You did not specify a working directory; by default the command is run in the build directory, not in the source directory.
You rely on shell functionality here (the redirect to a file). Even though this probably still works. You should go with an approach that does not rely on the shell.
To solve issues 1 and 2 I recommend creating a seperate cmake script file receiving the absolute paths to input and output files and using those in the custom command. This allows you to use execute_process to specify the file to write without relying on the platform.
preprocess_def.cmake
# preprocess def file
# parameters INPUT_FILE and OUTPUT_FILE denote the file to use as source
# and the file to write the results to respectively
# use preproc tool to get data to write to the output file
execute_process(COMMAND preproc "${INPUT_FILE}"
RESULT_VARIABLE _EXIT_CODE
OUTPUT_FILE "${OUTPUT_FILE}")
if (_EXIT_CODE)
message(FATAL_ERROR "An error occured when preprocessing the file ${INPUT_FILE}")
endif()
CMakeLists.txt
set(_INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.def")
set(_OUTPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.h")
# not necessary to use build event here, if we mark the output file as generated
add_custom_command(OUTPUT "${_OUTPUT_FILE}"
COMMAND "${CMAKE_BUILD_TOOL}" -D "OUPUT_FILE=${_OUTPUT_FILE}" -D "INPUT_FILE=${_INPUT_FILE}" -P "${CMAKE_CURRENT_SOURCE_DIR}/preprocess_def.cmake"
DEPENDS "${_INPUT_FILE}")
add_executable(my_target vvr_const.h ...)
set_source_files_properties(vvr_const.h PROPERTIES GENERATED 1)
Documentation from cmake:
PRE_BUILD
On Visual Studio Generators, run before any other rules are executed within the target. On other generators, run just before PRE_LINK commands.
So possibly your command is just running too late.
I am trying to include MPI compiler to my makefile. The makefile is already prepared such that I only need to include the address of the MPI compiler in a a separate env file. However doing so does not work. I can get the cpp file to run manually by typing:
mpicxx Demo_00.cpp -o aprogram
./aprogram
I test where the mpi compiler is located using:
which mpicxx
/usr/bin/mpicxx
In the env file the corresponding line is:
MPICXX=/usr/bin/mpicxx
However, when I try to 'make' he cpp file I get the following error:
make Demo_00
g++ Demo_00.cpp -o Demo_00
Demo_00.cpp:2:17: fatal error: mpi.h: No such file or directory
compilation terminated.
make: *** [Demo_00] Error 1
The cpp file is in the same folder as the env file and the makefile.
I am not quite sure how to identify the error.
Thank you for your help,
Tartaglia
If you want to change the name of the C++ compiler, you have to change the variable CXX. That's the default variable make uses when it wants to compile C++ code.
This line in your log file:
g++ Demo_00.cpp -o Demo_00
says that you are using g++ compiler instead of mpixx.
Usually in makefiles compiler definition is at the beginnig of the file and looks like this:
CC=g++
just change it to mpixx
CC=mpixx
Thank you all for your responses, I took a closer look into the makefile I thought I was using and it turns out, as you have already suggested, I was not using it at all. The makefile was only able to execute one specific cpp file with one specific name. So whenever I typed in make *.cpp I was using the standard make as you already pointed out.
Thanks again for your help.
Like others I have a link line that exceeds the Windows cmd line limit. For most cases we have solved the problem by building intermediate archives (aka static libraries) with subsets of the object files and performed the final link with those archives. However using this strategy with Google Test this causes the tests not to be found, specifically the tests defined in the object files that were archived.
Update: This is why. I will probably use this workaround, but I would still like to understand how to make response files work under scons.
The LongCmdLinesOnWin32 fix is problematic. We have a cygwin environment and pathnames that include spaces, so some compiler absolute paths involve quotes. The script in LongCmdLinesOnWin32 first needs to be extended to handle both the embedded quotes and the spaces (otherwise it creates separate tokens of a single path name). More seriously, when using MS Visual Studio, the compiler command is just 'cl' i.e doesn't include the pathname. This is not available in the PATH environment--it appears to be dynamically set (somehow) and not visible when constructing the cmdline argument to the LongCmdLinesOnWin32 script. But I digress....
There seems to be a much simpler (and to my eyes suitable) solution: response files, which are also supported by gcc.
I wrote a little function to take the list of object names and print them to a text file, one to a line, something like:
"""
In place for generating response files
"""
def gen_response_file(filename,file_list):
with open(filename,"w") as f:
for obj_name in file_list:
f.write ('%s\n' %os.path.abspath(str(obj_name)).replace('\\','/'))
return filename
I then tried prepending the '#' character to the file name and added it to the list of options.
The command line echoed was:
link /nologo /MACHINE:x86 /DEBUG #E:\dev\pcoip_view_client\soft_test.rsp /OUT:blah_client\blah_client_tests.exe /LIBPATH:\\sterbkp03\qt\4.8.2\lib ....
If I simply named the file "soft_test" then scons would add the suffix ".obj" and the linker could not find it, so I tried adding the suffix '.rsp'. Now, the linker complains it cannot find the file, but it is present. I captured the output from scons and pasted it to a bat file. When I ran the bat file (from the VS 2008 command line env.) the link worked like a charm, so it seems like scons is somehow causing the problem with finding the file
I tried changing the path, using absolute (#C:\blah\soft_test.rsp), relative (#.\soft_test.rsp) and just #soft_test.rsp, none of them worked.
LINK : fatal error LNK1104: cannot open file '#E:\dev\swift.dev\blah_client\soft_test.rsp'
scons: *** [blah_client\blah_client_tests.exe] Error 1104
I'm using scons v2.1.0.r5357, VS 2008 and python 2.7 under Windows 7-64
My scons file looks like:
test_objects = tenv.Object(test_sources)
xx = gen_response_file('soft_test.rsp',test_objects)
tenv.Append( LINKFLAGS = [ '#%s' % os.path.abspath(xx)]) #
test_exe = tenv.Program(target = 'blah_client_tests', source = objects + moc_objects + qrc_objects )
Any suggestions greatly appreciated.
Update: I tried with gcc and there was no problem. My guess is that somehow the scons rules associated with Visual Studio tools is different enough to cause grief.
I tried to reproduce this in Linux using gcc, and came across a different problem, whose solution may help.
Originally, I used this SConscript:
import os
"""
In place for generating response files
"""
def gen_response_file(filename,file_list):
with open(filename,"w") as f:
for obj_name in file_list:
f.write ('%s\n' %os.path.abspath(str(obj_name)).replace('\\','/'))
return filename
env = Environment()
test_objects = env.Object(target = 'testClass', source = 'testClass.cc')
resp_file = gen_response_file('response_file.rsp', test_objects)
env.Append(LINKFLAGS = [ '#%s' % os.path.abspath(resp_file)])
env.Program(target = 'helloWorld', source = 'helloWorld.cc')
Here are the related source files I used:
# tree .
.
|-- SConstruct
|-- helloWorld.cc
|-- testClass.cc
`-- testClass.h
Where helloWorld.cc is the main program. helloWorld.cc includes testClass.h and links in testClass.o When I tried to compile this, the response file was correctly generated (only contains /some/path/testClass.o) and read by the compiler. The problem that I came across was that testClass.o was not compiled, since SCons doesnt appear to recognize the dependency with the objects listed in the response file. Here is the result:
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o helloWorld.o -c helloWorld.cc
g++ -o helloWorld #/some/path/response_file.rsp helloWorld.o
g++: /some/path/testClass.o: No such file or directory
scons: *** [helloWorld] Error 1
scons: building terminated because of errors.
This seems like a failure in SCons because it doesnt analyze the response file. To solve this problem, I had to use the Depends() function as in the following excerpt:
...
bin = env.Program(target = 'helloWorld', source = 'helloWorld.cc')
env.Depends(bin, test_objects)
This worked and gave me the following:
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o helloWorld.o -c helloWorld.cc
g++ -o testClass.o -c testClass.cc
g++ -o helloWorld #/some/path/response_file.rsp helloWorld.o
scons: done building targets.
I know this doesnt answer the original question about why the response files cant be found, but once you solve that, you will most likely run into the problem mentioned above, and have to use the Depends() function.
I am very new to using the a command line to compile code so I was wondering how to make the D compiler compile all its code to a certain location instead of where the source is. As in I want the final .exe and the obj code all in a particular directory. I know you can use the -of command but I currently don't know the format for using it.
Currently I have:
C:\D\dmd2\windows\bin\dmd.exe -w C:\Users\Kyle\Desktop\D\Test.d C:\Users\Kyle\Desktop\D\src\MyMod.d
What do I need to add?
Use -offilename switch. Example:
dmd factorial.d -offilename "d:\test_name.exe"
or short version:
dmd factorial.d "-ofd:\test_name.exe"
Note: The double quotes are necessary if your path contains spaces.
Note2: In short version you can skip .exe, but don't do it in full version, because compiler would search for source file with that name.
I know people do not like RTFM answers, but the following is kind of RTFM answer that answers your question:
Execute dmd --help and you will get the following:
DMD32 D Compiler v2.061
Copyright (c) 1999-2012 by Digital Mars written by Walter Bright
Documentation: http://www.dlang.org/index.html
Usage:
dmd files.d ... { -switch }
files.d D source files
#cmdfile read arguments from cmdfile
-c do not link
-cov do code coverage analysis
-D generate documentation
-Dddocdir write documentation file to docdir directory
-Dffilename write documentation file to filename
-d silently allow deprecated features
-dw show use of deprecated features as warnings (default)
-de show use of deprecated features as errors (halt compilation)
-debug compile in debug code
-debug=level compile in debug code <= level
-debug=ident compile in debug code identified by ident
-debuglib=name set symbolic debug library to name
-defaultlib=name set default library to name
-deps=filename write module dependencies to filename
-g add symbolic debug info
-gc add symbolic debug info, pretend to be C
-gs always emit stack frame
-H generate 'header' file
-Hddirectory write 'header' file to directory
-Hffilename write 'header' file to filename
--help print help
-Ipath where to look for imports
-ignore ignore unsupported pragmas
-inline do function inlining
-Jpath where to look for string imports
-Llinkerflag pass linkerflag to link
-lib generate library rather than object files
-man open web browser on manual page
-map generate linker .map file
-noboundscheck turns off array bounds checking for all functions
-O optimize
-o- do not write object file
-odobjdir write object & library files to directory objdir
-offilename name output file to filename <---- [1]
-op do not strip paths from source file
-profile profile runtime performance of generated code
-property enforce property syntax
-quiet suppress unnecessary messages
-release compile release version
-run srcfile args... run resulting program, passing args
-unittest compile in unit tests
-v verbose
-version=level compile in version code >= level
-version=ident compile in version code identified by ident
-vtls list all variables going into thread local storage
-w warnings as errors (compilation will halt)
-wi warnings as messages (compilation will continue)
-X generate JSON file
-Xffilename write JSON file to filename
I marked the line that answers your question with [1] and an arrow.
Have a look at the -of, -od and -op switches. It's hard to be more specific without knowing what exactly you mean by "compile all its code to a certain location".
I am very new to Cmake and need to generate some files at compile time. once generated i need to compile and link the files. I ve created the cmake makefile to compile the already generated files like
cmake_minimum_required(VERSION 2.6)
project(demo)
set(CMAKE_CXX_FLAGS "-DWITH_COOKIES")
add_library(soapC soapC.cpp soapVimBindingProxy.cpp)
add_library(stdsoap2 /home/abdullah/installs/gsoap-shah_edits/gsoap/stdsoap2.cpp)
add_executable(demo test_file.cc test_app.cc)
target_link_libraries(demo soapC stdsoap2 gsoap++)
This successfully compiles the project. However the files soapC.cpp soapVimBindingProxy.cpp needs to be generated first. And I want to generate these files at runtime using the gsoap tool.
following is the command that needs to be run to generate the header file
wsdl2h -o outfile.h infile.wsdl
This takes an input wsdl file and creates a corresponding outfile.h.
Now I tried doing this in cmake like this
cmake_minimum_required(VERSION 2.6)
add_custom_command(
OUTPUT vsphere.h
COMMAND wsdl2h -o vsphere.h vim25/vim.wsdl
)
But something goes wrong here. No error pops up but no file is created either. Am I missing something ? All help much appreciated.
Thanks.
You've just created a command for producing your header file, so CMake knows just where to get vsphere.h from. I'd recommend using OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vsphere.h in the add_custom_command() call.
Now you need to create a target:
add_custom_target(vsphere_header ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/vsphere.h)
Finally, make your soapC target depend on it:
add_dependencies(soapC vsphere_header)
Be sure to place add_dependencies() call after soapC target definition.
Thanks arrododger and TobyHijzen for your lighting on this issue.
I use add_custom_command with main_dependency feature for solution for this issue. Following is my CMakeLists.txt for famous calc example of gsoap tutorial.
cmake_minimum_required(VERSION 2.8)
# Proejct name
PROJECT(Calculator)
# Make verbose level on/off
SET(CMAKE_VERBOSE_MAKEFILE ON)
# Varialbes used in cmake
SET(TARGET calc_client)
SET(GSOAP_STATIC_LIB gsoap)
SET(CLIENT_SRC calc_client.c)
SET(WSDL2H_EXEC wsdl2h)
SET(WSDL2H_IN http://www.genivia.com/calc.wsdl)
#SET(WSDL2H_IN calc.wsdl)
SET(WSDL2H_OUT calc.h)
SET(WSDL2H_OPT -c -o)
# command for generating stub and xml serializer code
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${WSDL2H_OUT}
COMMAND ${WSDL2H_EXEC} -c -ttypemap.dat -o ${WSDL2H_OUT} ${WSDL2H_IN}
COMMENT "=================== Generating ${WSDL2H_OUT} gSOAP Header file ..."
)
SET(SOAPCPP2_EXEC soapcpp2)
SET(STUB soapClient.c soapC.c)
SET(SOAPCPP2_OUT
${STUB}
calc.add.req.xml
calc.add.res.xml
calc.sub.req.xml
calc.sub.res.xml
calc.mul.req.xml
calc.mul.res.xml
calc.div.res.xml
calc.div.req.xml
calc.pow.res.xml
calc.pow.req.xml
calc.nsmap
soapH.c
soapH.h
soapStub.h
soapClientLib.c
)
# command for generating stub and xml serializer code
ADD_CUSTOM_COMMAND(
OUTPUT ${STUB}
COMMAND ${SOAPCPP2_EXEC} -c -C ${WSDL2H_OUT}
MAIN_DEPENDENCY ${WSDL2H_OUT}
COMMENT "=================== Generating ${STUB} outputs ..."
)
# Exutable files and dependents
ADD_EXECUTABLE(${TARGET} ${CLIENT_SRC} ${STUB})
# libraries for taget : for gcc -l option
TARGET_LINK_LIBRARIES(${TARGET} ${GSOAP_STATIC_LIB})
# Compiler options
ADD_DEFINITIONS(-Wall -O2 -s)