Understanding Property Sheet In Visual Studio Project Management

Naive Editing Properties

The naive method to manage a Visual-Studio project for different configurations (configuration + platform, such as Debug+x64) is to modify values directly in the Property Editor for each configuration. The disadvantages are

  • duplication in multi-configurations, which is difficult to maintain the consistency.
  • difficult to apply to multiple users, or multiple similar projects.

The appropriated solution is to use customized property sheets, which support cascade overriding.

Two Ways to Access Property Editor

  • naive: from project explorer, you can access properties for different configurations
  • advanced: from property manager. Upper sheet in each configuration overrides values in lower sheet. For VS2015, the global sheets locate at <drive>\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140, user sheets locates at <userprofile>\AppData\Local\Microsoft\MSBuild\v4.0. User sheets are obsolete, thus should be avoid to use (recommend to delete them from projects).

 

In the Property Manager, you can create/add any user custom property sheets at project level (that applies to all configuration) or at specified configuration.

custom-props.png

Project Property Sheet

Custom property sheets are saved in stand-alone XML files (for example, MyProps4All.props), instead of project files (.vcxproj). The advantage of stand-alone property sheet files is that they can be shared by different projects and configurations via importing.

The property inheritance (or override order) is

  1. Default settings from the MSBuild CPP Toolset (..\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.Default.props, which is imported by the .vcxproj file.)
  2. Property sheets
  3. .vcxproj file. (Can override the default and property sheet settings.)
  4. Items metadata

 

Reference

 

 

Displaying Chinese UTF-8 Characters in gvim On Windows

Following tip is copied from https://www.dzhang.com/blog/2013/04/02/displaying-chinese-utf-8-characters-in-gvim-on-windows

By default, gvim on my Windows machines just displays question marks, boxes, or garbled characters when I try to open files with Chinese text. The fix was rather simple:

  1. From the gettext project on SourceForge, get libiconv-1.9.1.bin.woe32.zip, which contains bin/iconv.dll. Put that file into gvim’s installation directory (for me, it’s C:\Program Files (x86)\Vim\vim73).
  2. Put this into vimrc:
    set encoding=utf8
    set guifontwide=NSimSun

Note: I’m using gvim 7.3.46 from the official site.

Credit goes to user Tobbe for this answer on superuser.com, which pointed out the key ingredient (iconv.dll).

 

Extra info

There is an extra vim plug-in that might be interesting, I haven’t verified it yet.

VimIM : Vim Input Method — Vim 中文输入法

Remote Debug With gdb/gdbserve

Overview

Remote debugging is useful or necessary, for example, in following scenarios:

  • There’s no full debugger on the target host, but a small stub (e.g. gdbserver) is available.
  • There’s no full source on the target host(for various reasons, such as size, security, etc). In a large project, synchronizing source codes on different hosts is either convenient nor safe. This is probably the most common case in the real world.
  • Debug input/output may pollute the target application input/output, for example, you are debugging a full-screen editor.

In practice, it’s better to have gdb and gdbserver with the same version. I had an experience that gdb (on centos5, v7.0.1) couldn’t connect to gdbserver (on debian 8, v7.7.1).

In the following example, the source codes locate on the host debian, the application is build and debug on debian, and the application is actually run on the remote host centos.

Prepare The Executable

No need to say, you need -g to keep symbols when you build your application. One additional tip: because the target application runs remotely, you don’t actually need to keep symbols in the target binary.

jason@debian$ gcc -g -o app app.c
jason@debian$ objcopy --only-keep-debug app app.debug
jason@debian$ strip -g -o app.remote app
jason@debian$ scp app.remote tony@centos:path/app

Explanation:

  1. build app with symbol
  2. extract symbols into a separate file. Now app.debug contains all debug information. This is common distribution practice.
  3. generate a version of executable without symbols, which (app.remote) is the version you actually distribute. The binary app still contains full symbols for debugger (you can, however, using app.remote plus app.debug, but what’s the point of that?)
  4. distribute the binary to the target host (host: centos, user: tony)

Launch At Target Host

On the target host (centos), start the application

tony@centos$ gdbserver localhost:4444 app
Process app created; pid = 10307
Listening on port 4444

The example uses tcp protocol. You can use serial com, in some special cases (such as in embedded system). The host part in host:port pair is not actually used in the current gdbserver version, so you can give it anything.

Start Debugging Session

Start debugging on the host debian. From the perspective of execution (on centos), gdb is running remotely (on debian); from the perspective of debugger, gdb (on debian) is debugging a program running on the remote host (centos).

jason@debian$ gdb app
... license info
Reading symbols from /home/jason/app...done.
(gdb) target remote centos:4444
Remote debugging using centos:4444
Reading symbos from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
(gdb) break main
(gdb) run

Once gdb connects to gdbserver, you can debug as usual as a normal gdb session, such as step, break, print variables, etc. One thing to remember is that the input and output of the program happen on the remote host.

On the remote host (centos), the gdbserver session looks like

...
Listening on port 4444
Remote debugging from host 192.168.205.96

... normal application input/output

Child exited with status 0
GDBserver exiting
tony@centos$ 

p4 – perforce common commands for batch operations

p4 help
get online help
p4 dirs //Drivers/*
list direct directories under given path (//Drivers)
p4 files //Drivers/…
list files (recursively) under given path (//Drivers)
p4 labels -m 5 //Drivers/…
list latest 5 labels of a path
p4 changes -m 1 //Drivers/…
list  the latest change list
p4 user jason
list user jason’s information
p4 client
show current client
p4 opened
list opened files (that are in the pending change lists)
p4 sync
get files to the workspace

p4 sync file#rev
p4 sync @label
p4 sync //depot/proj/...@rev
p4 sync @2011/06/24
p4 sync file#none           # delete from workspace
p4 unshelve -s changelist [ file_pattern … ]
unshelve a file/change list

perforce file name format

file#n              the n-th revision of file
file#m,n            revision range m,n
file#none           nonexistent revision (delete from workspace)
file#0
file#head           head (latest) revision
file#have           the revision on the current client
file@=n             change number
file@n
file@label          file in label
file@clientname     revision of file last taken into client workspace
file@datespec       datespec    yyyy/mm/dd([ :]hh:mm:ss)?
file@now

Make a DLL

MSDN:

Walkthrough: Creating and Using a Dynamic Link Library (C++)

  1. Make two projects: make_dll.prj and use_dll.prj under the solution
  2. Add Microsoft extension attribute to functions and/or classes
    #ifdef MYDLL_EXPORTS
    #define MYDLL_API  __declspec(dllexport)
    #else
    #define MYDLL_API  __declspec(dllimport)
    #endif
    
    namespace MyLib
    {
        MYDLL_API int foo(int, const char*);
        class MYDLL_API MyClass {
          //...
        };
    }
    
  3. Define MYDLL_EXPORTS in make_dll.prj but not in use_dll.prj
  4. Open use_dll.prj property dialog, choose [Common Properties] [References] and click [Add New Reference …], add reference to make_dll.prj
  5. Build dll (make_dll.prj) and application (use_dll.prj)

 

Further topics:

export functions from a dll by ordinal rather than by name, using .def files

Exporting C++ classes from a DLL